We Are Imagr (And So Can You)

For a long time, Mac Admins have been relying on the wonderfully useful tool DeployStudio. This free tool has been the mainstay of many deployment strategies, and has been my old faithful for years.

Despite its utility and functionality, it has some issues. Some of its functionality is almost black-box opaque, and we have to make some guesses and assumptions, and do some wrestling to make it work the way we want. The biggest issue, of course, is that it’s OS X-only, meaning that Mac deployment relies on having a Mac in a data-center environment. This makes many network administrators unhappy, as Apple does not offer an enterprise-level Mac anymore, not since the 2009 XServe was discontinued. Putting Mac Minis in the data center has raised eyebrows among the server purists and network neckbeards, but no one could deny how useful DeployStudio is. But since it’s not open-source, there’s not much the Mac admin community can really do about it.

Finally, that’s about to change – thanks to Graham Gilbert and his incredible work on his tool called Imagr. Imagr is an open-source deployment tool that runs in a NetInstall environment and makes running scripts, restoring images, and installing packages easy.

Imagr now leverages the functionality of Pepijn Bruienne’s AutoNBI to make the creation of all-inclusive NetBoot Images (hereafter referred to as “NBIs”) easy and straightforward.

Imagr is in its early stages of development, so there’s obviously lots of rough edges and work to be done. Improvements are being made constantly, and by many contributors, so you can get an idea of the excitement of the community around an open-source tool to do deployments with.

Despite Graham’s excellent work at the wiki, getting a chance to play with it may be a bit foreboding to admins who aren’t sure where to start.

First, I’d suggest reading Greg Neagle’s excellent starting point blog posts: Part 1 and Part 2.

I’d like to get into a bit more detail so that future admins who want to test can investigate this thoroughly.

The Setup

You need four things to test out Imagr:

  1. A NetBoot server.
    The easiest way to accomplish this is with an OS X Server running the NetBoot service. If you have an existing DeployStudio server running on OS X Server, that would be a perfect choice. See Greg Neagle’s post above for how you can use Imagr with existing DeployStudio NBIs. I’ll be referring to this as the “Netboot server.”
  2. A target device or VM to test with.
    I highly recommend using VMWare Fusion’s NetBoot compatibility to make testing faster, but if you’ve got a physical machine you’re willing to blow away, that works just fine too. I’ll be referring to this as the “client.”
  3. A web server.
    OS X Server running a Web service will work just fine. I’m using my existing Munki repo. I’ll refer to this as the “web server.” If you want to use OS X Server 4’s default web server, just place all relevant files in /Library/Server/Web/Data/Sites/Default/.
  4. A machine to generate your NBIs on, preferably running 10.10.3 build 14D136 (to be compatible with all current Apple hardware).
    This could also be the OS X Server if you’re using one, as long as it’s fully updated to the latest version of OS X. I’ll be referring to this as the “admin computer.”

In this post, I’m going to use my existing 10.9.5 OS X Server 3 to serve out NetBoot (since it’s already used for DeployStudio). I’m using my own workstation as the admin computer, running 10.10.3 build 14D136 to generate the NBIs. I’m testing with a VMWare Fusion 7 Pro VM as client that will be NetBooting.

Preparing Your NBI:

Note: pre-step zero: download the latest Yosemite installer from the Mac App Store. I’ll be using the default path: /Applications/Install OS X Yosemite.app in this example.

  1. Create a file called imagr_config.plist that is hosted on your Web server.
    I’m hosting it on my munki repo in a folder called ‘imagr’, so it can accessed at http://munki/repo/imagr/imagr_config.plist. We’ll fill the contents of this file shortly. For now, just make sure it’s accessible.
  2. On the admin computer, download or clone Imagr from the GitHub page:
    git clone https://github.com/grahamgilbert/imagr.
  3. Create a file called config.mk in the same directory as the “Makefile” that is included with the Imagr clone (~/Applications/imagr/config.mk would be the path in my example).
  4. This config.mk file is going to be used to override the variables. Change the URL, which should be the accessible URL of your “imagr_config.plist” file. Additionally, if you have existing NBIs (from DeployStudio, for example), make sure you choose an index that does not collide with an existing one. The default is 5000:
    URL="http://munki/repo/imagr/imagr_config.plist"
    APP="/Applications/Install OS X Yosemite.app"
    OUTPUT=~/Desktop/
    NBI="Imagr-Testing"
    ARGS="-e -p" # Enable Netboot set, include python
    INDEX=5000
    

  5. From inside the imagr directory, run this command:
    make nbi

  6. At the end of the lengthy command run, you should have a file located in your OUTPUT folder (in this example, on the Desktop) called “Imagr-Testing.nbi”.
  7. This NBI needs to be copied to your NetBoot server. If you’re using OS X Server as your NetBoot server, you need to place this file in /Library/NetBoot/NetBootSP0/.
  8. Launch Server.app and go the NetInstall section. You should see it show up:
    Screen Shot 2015-05-12 at 8.55.00 AM
  9. Select your “Imagr-Testing” boot image and click on the gear icon to get its properties and details:
    Screen Shot 2015-05-12 at 8.55.12 AM
  10. First, make sure that the index it chooses (by default, 5000) does not collide with other NBI indexes. If it does, change the index number here (and then change your config.mk to build NBIs using a different index).
    Screen Shot 2015-05-12 at 8.54.48 AM
  11. By default, the NBI only makes itself available to compatible Mac models. This is great for actual deployment, but if you want to do testing with a VM, you might need to turn this off. Change the availability so that it’s open for “all Mac models”:
    Screen Shot 2015-05-12 at 8.55.12 AM
  12. If you’re doing testing with a VMWare Fusion VM, you’ll also need to make sure that the “Imagr-Testing” NBI is the Default netboot image, as Fusion only works with the default. Select the image, click the gear icon, choose “Use as Default Boot Image.”
    Screen Shot 2015-05-12 at 8.55.19 AM
  13. Verify on your clients. You should be able to see the “Imagr-Testing” netboot image in the Startup Disk pane of the System Preferences.

Creating a Workflow:

Now that the NBI is ready, we need an actual Imagr deployment configuration so that it can be tested. This workflow information is stored in the imagr-config.plist file we created on the Web server earlier. The workflow structure is documented on the wiki.

You can use any text editor to create this plist. For visual completeness, I’ll also include screenshots of Xcode’s visual plist editor.

Here’s the starting empty plist:


<?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"&gt;
<plist version="1.0">
<dict>
<key>password</key>
<string></string>
<key>workflows</key>
<array>
</array>
</dict>

First, we need a password. On any computer with Python (such as the Admin computer):
python -c 'import hashlib; print hashlib.sha512("YOURPASSWORDHERE").hexdigest()'
Copy the long hash string and set that as the value of the Password key at the root of the plist:


<key>password</key>
<string>278c0c9360772fc0ab2f25c7bcafdd2579e3aa05ba4041abbf30d0ebe4c9b8b1b56f4b1ba822ccf32072e3ac443b14b49d99fa1201b02011fd486078d83b3cde</string>

Screenshot 2015-05-12 09.09.44

Now it’s time to fill out a workflow. This basic workflow is going to install a live package (i.e. not at first boot). This package is a CreateOSXInstallPkg package for 10.10.3 build 14D136. It needs to be accessible via HTTP somewhere, so it’s a prime candidate for going into the “imagr” directory on the Web server I already created.

The package installation can be described like this:


<dict>
<key>name</key>
<string>Yosemite Upgrade – Base</string>
<key>description</key>
<string>Deploys a 10.10.3 base image. Does NOT wipe the drive first.</string>
<key>restart_action</key>
<string>restart</string>
<key>bless_target</key>
<false/>
<key>components</key>
<array>
<dict>
<key>type</key>
<string>package</string>
<key>url</key>
<string>http://munki/repo/imagr/InstallYosemite-10.10.3.dmg</string&gt;
<key>first_boot</key>
<false/>
</dict>
</array>
</dict>

Screenshot 2015-05-12 09.24.06

In this workflow, we’re specifying a restart_action value of restart, which forces Imagr to reboot when the workflow completes (successfully).

The components key lists the actual process for things we want to do. Here, we’re just using a component of type package, which installs a package. We specify the url to the package, and we’re installing this package live, not at first boot, thanks to the value of false for first_boot.

Note that the url key points to a disk image, not a package itself. CreateOSXInstallPkg produces a bundle package, not a flat package, and thus it must be wrapped in a disk image. If you aren’t sure how to do that, follow these steps:

  1. mkdir InstallYosemite-10.10.3
  2. mv InstallYosemite-10.10.3.pkg InstallYosemite-10.10.3/
  3. /usr/bin/hdiutil create -srcfolder InstallYosemite-10.10.3 InstallYosemite-10.10.3.dmg
  4. Copy the resulting disk image to the location where it can be served via Web.

All this workflow accomplishes is installing the CreateOSXInstallPkg package, and then restarts.

Read the documentation to see how you can also leverage Scripts and Image cloning in addition to package installs. The workflow is fairly extensible.

Testing Out Imagr:

We have a NBI image we created, serving out NetBoot from the NetBoot server. We have a workflow in our imagr_config.plist file to install a package. Now it’s time for an actual test.

  1. Boot up a VM or physical device (the client device) to the NetBoot image called “Imagr-Testing” (or whatever you named it).
  2. Log in using the password you specified (in my example, it was “YOURPASSWORDHERE”).
  3. Run your workflow!

Testing it out again, and then again

If you want to make any changes to your NBI (or are testing out new forks/updates to Imagr), you need to rebuild the NBI each time.

  1. make update to rebuild the NBI without needing to build from scratch. This will save time (hat tip to Erik Gomez and Clayton Burlison).
  2. Copy it to your NetBoot server into /Library/NetBoot/NetBootSP0.
  3. Change index number if necessary (which you should do by specifying a unique index number in config.mk.
  4. Change the models to “All Mac models” if booting into a VM.
  5. Set the boot image as default.
  6. Reboot the client machine.
  7. Rinse, wash, repeat!

Setting Up Munki With OS X Yosemite Server

There are many ways to set up Munki, since it’s just a webserver. The Demonstration Setup is a great way to get started, but doesn’t list the steps for setting up OS X Server. A lot of new Munki admins (or generally new Munki admins) may have an OS X Server they have access to, but not other web servers, so a guide to getting started with the latest version of OS X Server (as of writing time, that’s Server 4, on Mac OS 10.10.2 Yosemite) may be helpful.

This is all assuming you’ve got Server.app set up and running.

If the Websites service in Server.app is running, turn it off first.

The first steps are to create the Munki repo in the location that Server 4 uses to store website data:
mkdir /Library/Server/Web/Data/Sites/Default/repo
mkdir /Library/Server/Web/Data/Sites/Default/repo/catalogs
mkdir /Library/Server/Web/Data/Sites/Default/repo/pkgs
mkdir /Library/Server/Web/Data/Sites/Default/repo/pkgsinfo
mkdir /Library/Server/Web/Data/Sites/Default/repo/manifests

Change permissions to make sure it’s accessible:
chmod -R a+rX /Library/Server/Web/Data/Sites/Default/repo

In the Server.app Websites pane, edit the “Server Website” (port 80) settings:
Next to “Redirects”, click “Edit…”, and remove the only redirect (which automatically redirects port 80 to port 443 traffic). It should look like this:
Screen Shot 2015-02-18 at 8.42.17 AM

Next, click “Edit Advanced Settings” and check the box for “Allow folder listing” (just for now – it’s easier to visually test this way):
Screen Shot 2015-02-18 at 8.42.13 AM

Turn the Websites service on.

Open up Safari, navigate to:
http://localhost/repo/

You should see a page like this:
Screen Shot 2015-02-18 at 8.37.41 AM

If you can get to this point, you’ve done the website setup work. Now you can go to the next section:
https://github.com/munki/munki/wiki/Demonstration-Setup#populating-the-repo

Once you’ve populated the repo, you can set up a new manifest called “test_munki_client”. Follow the instructions exactly:
https://github.com/munki/munki/wiki/Demonstration-Setup#creating-a-client-manifest

Go through the Client Configuration section:
https://github.com/munki/munki/wiki/Demonstration-Setup#munki-client-configuration
Here, you need to do two things on your OS X client.

If you are testing this on the OS X Server itself (i.e. you are only using one machine total), do this:
sudo defaults write /Library/Preferences/ManagedInstalls SoftwareRepoURL "http://localhost/repo"
sudo defaults write /Library/Preferences/ManagedInstalls ClientIdentifier "test_munki_client"

If you are testing Munki on a different client machine from the server, do this:
sudo defaults write /Library/Preferences/ManagedInstalls SoftwareRepoURL "http://ip_or_domain_name_of_server/repo"
sudo defaults write /Library/Preferences/ManagedInstalls ClientIdentifier "test_munki_client"

And then finally you can check to see if Munki behaves as you’d expect:
sudo /usr/local/munki/managedsoftwareupdate -vv