Posted on 05-15-2014 06:32 AM
I'm trying to make the switch from a monolithic workflow with DeployStudio to a packaged workflow with Casper, both thin and not. ;) With DS, I used admin autologin and a login script to execute tasks that need to happen on the first boot after DS has finalized the image. I let DS do the binding and my script is there to basically license Adobe Creative Cloud.
I have already been using launchd for tasks such as rebooting daily and running a weekly data clean-up script. This is my first time trying to get something to launch once only on the first time the machine is booted. At the moment it is not working. The logic is a little convoluted and I am open to suggestions on how to simplify this.
All of my scripts are in /Library/AdminToolBox, a directory I created for such things. My launchd plist looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>ca.organization_name.firstboot</string>
<key>RunAtLoad</key>
<true/>
<key>LaunchOnlyOnce</key>
<true/>
<key>ProgramArguments</key>
<array>
<string>/Library/AdminToolBox/on-firstboot.sh</string>
</array>
</dict>
</plist>
The on-firstboot.sh script is there to find out if this is the first time we booted. If so, we delete the empty file /Library/AdminToolBox/firstboot and execute our script, /Library/AdminToolBox/firsttime_actions.sh:
#!/bin/sh
# Entire script is conditional on existence of firstboot file
# If it is missing, we exit immediately
if [ -f /Library/AdminToolBox/firstboot ] ; then
rm -f /Library/AdminToolBox/firstboot
/Library/AdminToolBox/firsttime_actions.sh ;
fi
exit 0
The firsttime_actions.sh script:
#!/bin/sh
/usr/sbin/ipconfig/waitforall
# Do something to indicate we executed
touch /Library/AdminToolBox/executed_firsttime_actions.txt
# Bail out of here, this is just a test
exit 0
# Serialize Adobe CC
/Library/AdminToolBox/adobe_prtk --tool=VolumeSerialize --provfile=/Library/AdminToolBox/prov.xml
# Set system name
/Library/AdminToolBox/doname.sh
# Install QuickAdd package to add system to Casper Suite
/usr/sbin/installer -pkg /Library/AdminToolBox/QuickAdd.pkg -target /
# Unload our startup item and delete it
launchctl unload -w /Library/LaunchDaemons/ca.durhamcollege.firstboot.plist
rm /Library/LaunchDaemons/ca.durhamcollege.firstboot.plist
Unfortunately, the file /Library/AdminToolBox/executed_firsttime_actions.txt is not being created so I presume all of this code is failing somehow. I have never had trouble getting the login hook trick to work but it is cumbersome as it means the image is created with the hidden admin account set to automatically login just so we can get our script to run. I'd love to move on to launchd but I'm obviously doing something wrong.
The permissions on the launchd item is correct. I have tried various permissions on the scripts in the AdminToolBox directory but I normally set them like this:
chmod 700 *.sh
Cheers...
Solved! Go to Solution.
Posted on 05-15-2014 06:54 AM
Since you are unloading and removing the LaunchDaemon at the end of your script, there's no need to limit the LaunchDaemon to run only once. I use this for my launchd item for my first boot script:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.integer.postimage</string>
<key>ProgramArguments</key>
<array>
<string>/private/var/inte/scripts/postimage_10.9.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
You might try something like that to see if it works.
Also, is the install that is putting all of that in place being done at reboot? I have my pkg file that drops my post imaging (first boot) script and this launchd item, set to install on boot drive after imaging.
Posted on 05-15-2014 06:54 AM
Since you are unloading and removing the LaunchDaemon at the end of your script, there's no need to limit the LaunchDaemon to run only once. I use this for my launchd item for my first boot script:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.integer.postimage</string>
<key>ProgramArguments</key>
<array>
<string>/private/var/inte/scripts/postimage_10.9.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
You might try something like that to see if it works.
Also, is the install that is putting all of that in place being done at reboot? I have my pkg file that drops my post imaging (first boot) script and this launchd item, set to install on boot drive after imaging.
Posted on 05-15-2014 08:28 AM
stevewood: Thanks for the quick reply. My launchd plist was very similar to yours. I changed it to match what DeployStudio uses to launch their ds_finalize.sh script just in case I was missing something. The script doesn't seem to execute. From what I've read here, items in /Library/LaunchDaemons run as root, is that correct? I tried the script with 777 perms and it still didn't seem to execute.
The scripts were all on the image prior to the install.
Yes, after testing your example launchd with minor changes everything started working. Thanks very much.
Posted on 05-15-2014 01:07 PM
Ownership/perms: root:wheel ownership on both, 644 on the plist, 755 on the script.
Are you checking launchctl as root to see if it's loading? No need to have the RunOnlyOnce key, as already mentioned.
Posted on 05-15-2014 05:39 PM
JPDyson: Thanks for the follow-up on permissions; I had the perms for the plist set correctly and the script is now working.