Local DeployStudio setup for classes: 10.11 Issues solved

Posted on: 02:03 PM by Maurits

All our Mac’s are configured with a local partition (RestoreX) that contains a full OS X System, with a local DeployStudio setup to restore the other partition for use in training.
We do this to be able to restore Macs at the start of each class without the need to build an ethernetwork first, which is useful when we are travelling.

With 10.11 we had to make a few changes to the workflow we used since 10.5 times, due to SIP.
In this blog I will show you what are the issues with DeployStudio 1.7.2 on OS X 10.11/SIP, how I solved them with a script using diskutil mergePartitions and diskutil splitPartitions, and some more details including my complete workflow and lessons learned.

Local DeployStudio partition setup

We have used DeployStudio for years to restore our Mac’s before start of each training class. The ease of use, speed, automatic configuration (names, users, etc) make it a perfect tool for our purpose.
DeployStudio is designed to deploy Mac’s while netbooted, but we used it in a unconventional setup where all three components (DeployStudio server, Repository and Runtime) are on the same OS X Partition, named Restore11.
We restore OS X to an other local partition.
I have plans to post a separate blog post on this setup later.

These issues need a different solution on 10.11 than on previous versions:

  • Reboot at the end of the workflow.
  • Partitioning
  • Restore the Recovery HD partition

Each issue is explained in the following paragraphs.


DeployStudio ends a workflow by quitting the Runtime, which results in a reboot (when netbooted). In our setup we have to run a script to set the appropriate startup volume, and reboot the Mac before killing the Runtime.
The bless command is protected by SIP. It is documented that bless can only boot from ‘Trusted’ NetInstall servers (see HT205054), but I found that the commands I used in 10.10 (shown below) did not work in 10.11:
/usr/sbin/bless --device "/Volumes/$DS_LAST_RESTORED_DEVICE" --setBoot
/sbin/shutdown -r now

This script results in an error (“Could not set IOService for s3”) when run on 10.11, while it worked on 10.10.

After some researching I found that the SystemSetup command works better for this workflow for 10.11, so the code used in the script to reboot the Mac to the just restored partition contains this code:
/usr/sbin/systemsetup -setstartupdisk "/Volumes/$DS_LAST_RESTORED_VOLUME"
/sbin/shutdown -r now

The full mjs_reboot.sh script I use as a last step in our workflow (see step 4 screenshot below) is posted on Github: here

Partitioning and the Recovery HD (Apple_Boot) partition

Most DeployStudio workflows will start with partitioning a whole disk, which cannot be used since the RestoreX partition cannot be deleted 🙂
Up to 10.10 I could use the default DeployStudio step ‘Restore’ and select the appropriate partition or Volume, and include the ‘Restore system recovery partitions’ checkbox in the Restore step.

For FileVaulted disks I had created a separate script (and workflow), which was easy to recognize since the Finder would prompt the user to ‘Enter your password to unlock …..’
In the case where a previous class had left more partition, I used Disk Utility to delete the un-needed partitions manually. With the workflow and scripts I show you here, both issues do no longer need manual intervention; the script will re-configure any setup, and restore my desired state.

Desired state of partitions

I want to partitions to look like this (before deployment):

 diskutil list
 /dev/disk0 (internal, physical)
 #: TYPE                  NAME           SIZE IDENTIFIER
 0: GUID_partition_scheme           *250.1 GB disk0
 1:                   EFI EFI        209.7 MB disk0s1
 2:             Apple_HFS Restore11a  74.9 GB disk0s2
 3:             Apple_HFS leeg       174.2 GB disk0s3

Restore11a is the partition that contains OS X, DeployStudio, Repository and Runtime.
The partition ‘leeg’ (Dutch for ’empty’) will be the target of the deployment.
I do not want to have a recovery partition (yet), because I sometimes use different OS X versions, and the Recovery HD version should match the version of OS X used, so the Recovery HD must be part of the Restore process.
Since we train students for system admin tasks, the previous class my leave the partition setup in any state: One ‘plain’ HFS+ volume, un-encrypted CoreStoreage, FileVault may be set, more than one partition may be created, etc.

Solution to get desired state

I created the following script to set my desired state, regardless of the previous state. This method reduces the need for manual intervention (see above for FileVault, or more Partitions)
I start my script to see if there is a CoreStorage partition.
DISKUTIL_CS=`diskutil list|grep Apple_CoreStorage | awk '{ print $NF; }'`
This will output the device name (like disk0s3) for the CoreStorage partition, or empty if none.
The UUID of the CoreStorage Volume Group is found and defined as a variable:
LGV_UUID=`diskutil cs list |grep "Logical Volume Group" |awk '{ print $NF; }'`

If there is a CoreStorage partition, it will be deleted:
if [ "$DISKUTIL_CS" != "" ] ; then
echo " - CoreStorage found, deleting CS volume"
diskutil cs delete $LGV_UUID 2>&1
diskutil eraseVolume JHFS+ leeg $DISKUTIL_CS 2>&1
echo " - done erase LVG"

If there is no CoreStorage, skip the previous step, and proceed here:
To merge possible other partitions into one large partition:

LAST_SLICE=`diskutil list|grep : |grep disk0s | awk ' END { print $NF; }'`
echo " - first merge $DISKUTIL_CS to $LAST_SLICE"
echo y | diskutil mergePartitions force JHFS+ leeg disk0s3 $LAST_SLICE

Solution to asr and resizing for Recovery HD

An other issue I found is that DeployStudio Runtime could NOT restore an Image created with AutoDMG, and restore the Recovery HD as it could in 10.10. Before 10.11 the Runtime will check for existing Recovery HD partition, if not, resize the target partition, and restore both the ‘Macintosh HD’ and the ‘Recovery HD’.
In 10.11 The asr command will fail to resize the partition with an error:
/usr/sbin/asr restore --source /Users/Shared/DS_Repo/Masters/HFS/osx-10.11.3-15D21.hfs.dmg --target /dev/disk0s3 --puppetstrings --noprompt --allowfragmentedcatalog --noverify --erase --buffers 1 --buffersize 32m 2>&1
XSTA start 359 client
XSTA setup
Validating target...done
XSTA metadata
Validating source...done
Couldn't open target disk for repartitioning.
Command failure: XSTA fail
Restoration failed

The Couldn’t open target disk for repartitioning error did NOT occur if the right Recovery HD partition (a 650 MB Apple_Boot type) was already there, OR if I disabled System Integrity Protection (SIP).
Disabling SIP is not recommended, since I want to train my students in troubleshooting, resetting the NVRAM is a normal thing to do in class, and after resetting your NVRAM SIP is enabled by default.
So I edited my script to make sure the desired state includes a proper Recovery HD partition using this command:

echo " - creating room for recovery at end of disk0s3"
diskutil splitpartition disk0s3 JHFS+ leegsplit R %Apple_Boot% %noformat% %recovery% 2>&1

After the previous step there should be only one partition, disk0s3 (leeg), and this command will re-generate the Recovery partition at the end of disk0s3, and asr (as used by the Restore step in DS workflows) can proceed normally.
The output of diskutil after this command will look like this:

/dev/disk0 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *250.1 GB   disk0
   1:                        EFI EFI                     209.7 MB   disk0s1
   2:                  Apple_HFS Restore11a               74.9 GB   disk0s2
   3:                  Apple_HFS newsplit                172.5 GB   disk0s3
   4:                 Apple_Boot                         650.0 MB   disk0s4

Now we can use the ‘default’ DeployStudio Restore step in our workflow, and use both the options to restore the recovery partition, and convert to CoreStorage. CoreStorage is default for the OS X Install, and I like our Mac’s to be as close to default as possible).
See below the screenshot for step 2 for my settings.

Full script on Github

The full re-partitioning script I use is posted on Github: here

Full workflow to restore locally

Here are the screenshots of my workflow to restore an image created with AutoDMG, configure name and users, and reboot from the local restored image.
Step 1:
Step 2:
Step 3:
Step 4:

Lessons Learned

Logs not updated if Runtime is killed

My script will reboot the Mac (and kill the Runtime), which will prevent the Runtime from writing the last part of the logs to the DS_Repo/Logs. The last line in the log will be ‘Running workflow: ‘ A-restore 10.11.3 and config” (EC93…..)”

Issue: diskutil mergePartitions not merging all space?

While preparing this script I found out that in some situations the workflow resulted in an Apple_Boot partition of 1.3 GB (or if I run the command serveral times a multiple of 650 MB).
I guess that although not visible with diskutil list command, there is still some space reserved for the Apple_Boot partition, and the diskutil splitpartition command added 650 MB to this partition. Maybe a reboot could solve this, but I want my workflow to work without reboot.
I found that if I run the sequence diskutil mergePartitions and diskutil splitpartition twice, the result was the desired Apple_Boot partition of 650 MB, so I ran these commands twice in the script.

AutoDMG and recovery

AutoDMG creates one .dmg file, but if you open this .dmg you will see that it contains both a HFS+ volume and a Recovery HD volume. To see this you can mount this .dmg file, and run diskutil list, you will see something similar to this:

/dev/disk4 (disk image):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        +35.4 GB    disk4
   1:                        EFI EFI                     209.7 MB   disk4s1
   2:                  Apple_HFS Macintosh HD            34.6 GB    disk4s2
   3:                 Apple_Boot Recovery HD             650.0 MB   disk4s3

DeployStudio is aware of this, so you can enable the option ‘Restore system recovery partitions’ in the Restore step without the need for a specific .recovery.hfs image in the Repository.
Normally DeployStudio will look for an image in the Masters/HFS/ repository, If the image to deploy is named ‘OSX10.11.hfs.dmg’, the runtime will look for an recovery image named ‘OSX10.11.recovery.dmg’.

Learn more @ LAI

Curious to learn how to do this kind of things in your organisation?

Find when you can go to the next Deployment of OS X with DeployStudio and Munki or OS X Shell Scripting training!

Maurits Sanders

Comments are closed.