In this post, I’ll begin to demonstrate how beneficial it can be to automate some of the more tedious tasks involved with setting up a new install of MacOS X Lion (10.7) or Mountain Lion (10.8). In this early post we’ll focus on getting our machine to a state where it has the tools and core utilities required to continue the deployment with an automation tool like Opscode Chef, which will be introduced in a future post in this series.
A Little Background
I am responsible for the deployment and management of dozens of MacOS X machines. As this fleet of workstations has grown, it has become exponentially more challenging to centrally manage the deployment and configuration of these assets. As a systems administrator responsible for this number of developer workstations, one of the most important things you can learn to do is automate the deployment and maintenance process as cleanly and as consistently as possible.
Where to Begin?
The first steps involved in preparing an OS X workstation for typical developer use is the installation of Xcode and Command Line Tools. Both of these are available from Apple, but installation is largely a point-and-click affair, which seems to fly in the face of the virtues of automation. As such, I did what seemed logical. I created an automation script which will deploy these tools with minimal fuss. All that’s needed to start this process is to run a script from the Terminal of an out-of-the-box OS X installation. Let’s start with the Command Line tools script, which you can save anywhere in your home directory to a file called install_cltools.sh
:
#!/bin/bash
# install_cltools.sh
# This script will install Apple Command Line Tools in
# an automated fashion after downloading the install
# dmg from an accessible web server.
# This is a webserver from which the installers can be
# downloaded. Unfortunately, Apple has a lame habit
# of only making these utilities available for download
# by logging into their website, so you'll need to
# download them there and then move them onto a web
# server that this script can access. PROTIP: You can
# even use localhost by starting a quick python
# webserver from the ~/Downloads directory on your Mac.
# For example:
# cd ~/Downloads; python -m SimpleHTTPServer 8080
webserver="http://localhost:8080/"
info="[info]"
warning="[warning]"
error="[error]"
check_root() {
if [[ $EUID -ne 0 ]]; then
echo "$error This script must be run as root" 1>&2
exit 1
fi
}
detect_osx_version() {
result=`sw_vers -productVersion`
if [[ $result =~ "10.7" ]]; then
osxversion="10.7"
osxvername="Lion"
cltools=xcode46cltools_10_76938132a.dmg
mountpath="/Volumes/Command Line Tools (Lion)"
mpkg="Command Line Tools (Lion).mpkg"
elif [[ $result =~ "10.8" ]]; then
osxversion="10.8"
osxvername="Mountain Lion"
cltools=xcode46cltools_10_86938131a.dmg
mountpath="/Volumes/Command Line Tools (Mountain Lion)"
mpkg="Command Line Tools (Mountain Lion).mpkg"
else
echo "$error This machine is running an unsupported version of OS X" 1>&2
exit 1
fi
echo -e "$info Detected OS X $osxversion $osxvername"
}
check_tools() {
RECEIPT_FILE=/var/db/receipts/com.apple.pkg.DeveloperToolsCLI.bom
[ -f "$RECEIPT_FILE" ] && echo "$info Command Line Tools are already installed. Exiting..." && exit 0
}
download_tools () {
# Use curl to download the appropriate installer to tmp
if [ ! -f /tmp/$cltools ]; then
echo -e "$info Downloading Command Line Tools for Mac OS X $osxversion"
cd /tmp && curl -O $webserver/$cltools
else
echo -e "$info $cltools already downloaded to /tmp/$cltools."
fi
}
install_tools() {
# Mount the Command Line Tools dmg
echo -e "$info Mounting Command Line Tools..."
hdiutil mount -nobrowse /tmp/$cltools
# Run the Command Line Tools Installer
echo -e "$info Installing Command Line Tools..."
installer -pkg "$mountpath/$mpkg" -target "/Volumes/Macintosh HD"
# Unmount the Command Line Tools dmg
echo -e "$info Unmounting Command Line Tools..."
hdiutil unmount "$mountpath"
}
cleanup () {
rm /tmp/$cltools
echo "$info Cleanup complete."
exit 0
}
# Make sure only root can run our script
check_root
# Detect and set the version of OS X for the rest of the script
detect_osx_version
# Check for if tools are already installed by looking for a receipt file
check_tools
# Check for and if necessary download the required dmg
download_tools
# Start the appropriate installer for the correct version of OSX
install_tools
# Cleanup files used during script
cleanup
Run It!
After creating this file, all that’s required is to run:
$ chmod +x cltools_install.sh $ sudo ./cltools_install.sh
How To Verify It Worked
I’m a stickler for seeing things through to completion. This means we should always verify our changes. How can we quickly check to ensure this script worked? Once it finishes, we can confirm that the following files are now in our /usr/bin/
directory:
ar as asa bison c++ c89 c99 cc ci clang clang++ cmpdylib co codesign_allocate compileHelp cpp ctags ctf_insert cvs cvsbug desdp dsymutil dwarfdump dyldinfo flex flex++ g++ gatherheaderdoc gcc gcov gcov-4.2 gdb git git-cvsserver git-receive-pack git-shell git-upload-archive git-upload-pack gm4 gnumake gperf gprof hdxml2manxml headerdoc2html i686-apple-darwin11-llvm-g++-4.2 i686-apple-darwin11-llvm-gcc-4.2 ident indent install_name_tool ld lex libtool lldb llvm-cpp-4.2 llvm-g++ llvm-g++-4.2 llvm-gcc llvm-gcc-4.2 lorder m4 make merge mig mkdep nasm ndisasm nm nmedit otool pagestuff projectInfo ranlib rcs rcs2log rcsclean rcsdiff rcsmerge rebase redo_prebinding resolveLinks rlog rpcgen sdef sdp segedit size strip svn svnadmin svndumpfilter svnlook svnserve svnsync svnversion unifdef unifdefall unwinddump vgrind what xml2man yacc
Up Next: XCode
In the next part of this series on MacOS X deployment, I’ll demonstrate how we can automate the installation of XCode in a way similar to the way the Command Line Tools were installed in this guide. Stay tuned, it’s going to get exciting!
Leave a Reply