Munki Guide

From AFP548 Wiki
Jump to: navigation, search

Note: The specifics on this guide may be a little dated, but the basics are still valid. Repo setup and the components of the pkginfo file remain the same, except that there are more options in newer revisions of munki. Be sure to check http://code.google.com/p/munki/w/list for the latest information.

This guide is meant to be a quick start for anyone interested in using munki. According to the munki project page on Google code, " munki is a set of tools that, used together with a web server-based repository of packages and package metadata, can be used by OS X administrators to manage software installs (and in many cases removals) on OS X client machines. munki attempts to address some of the limitations of using the Apple package format for managed software installations and removals. Additionally, munki supports Adobe CS3/CS4/CS5 Enterprise Deployment "packages", and drag-and-drop disk images as installer sources." The munki project page can be found here http://code.google.com/p/munki/.

This guide is meant to supplement the information that is already found on the munki wiki pages http://code.google.com/p/munki/w/list. The creator of munki already has a getting started guide that is well worth reading: http://code.google.com/p/munki/wiki/GettingStartedWithMunki. Like the InstaUp2Date_Guide, this article is meant to direct the reader step-by-step in order to be successful with munki. Munki is a very powerful tool and can be used with an enormous amount of flexibility. The scope of this guide is for a very simple setup that will set the foundation so that the depth of the tool can be explored as needed.

The following will be covered:

  1. Setting up a basic munki repository on an xserve.
  2. Populating the repository with software, metadata about that software and the files that control what a particular Client will get (manifests).
  3. Installing munkitools on a client and configuring the client settings.
  4. Doing a test run and troubleshooting any issues that arise.



Requirements for this guide:

  • A web server (OS X Server, Apache on any Linux distro, Windows IIS if you must). For this guide, we'll go over the basic configuration for a OS X Server-based munki repository.
  • Munkitools must be installed on your client machine (http://code.google.com/p/munki/downloads/list). This will require a reboot, so install it, reboot and come back to the guide. Note that it is not necessary for the tools to be installed on your server. All the processing is done client-side.

The Repository[edit]

The munki repository was designed with flexibility in mind. It can be hosted on any web server. This means you can host it on OS X Server if you'd like, any flavor of Linux or even a windows web server if you absolutely must.

For the purposes of this guide, we will assume that it is being hosting on an xserve, although it could be any web server.

  1. Create a new directory in your root web directory(/Library/WebServer/Documents/). It can be named whatever you like, but for this guide we will name it munki_repo.
  2. Within the munki_repo directory, you will want to make the following directory structure. It MUST be exactly these directories and spellings:
    • catalogs (Automatically generated files)
    • manifests (Files that determine what the client must install)
    • pkgs (All the install items go here in dmg format)
    • pkgsinfo (meta data about each package goes here)
  3. Here are some quick directions for setting up a web service on an Xserve:
    1. Open Server admin, go to the Services section
    2. Check "Web" and hit save.
    3. Now go to "Web" in the left hand column under your server name and select "Sites" at the top of the right hand pane.
    4. We'll use the default site for this guide, but you can make a new one if you please. Point "Web Folder" to your newly created munki_repo folder (/Library/WebServer/Documents/munki_repo) and click save.
    5. Make sure the Web service is started and we are done with the Web setup.


With these directories made and a basic web server set up, you are ready to put your first application into your munki repository. We'll start with something easy...Firefox.

Populating the Repository[edit]

  1. Download Firefox here: www.firefox.com.
  2. After Firefox is downloaded, browse to your munki_repo directory, go into the pkgs directory and create a new directory named apps. Within the apps folder, make another folder named Mozilla. Best practice is to place software into a folder named after the company that makes it. Also separating out the packages by type (Apps, Drivers, Printers, Settings, etc) will further help organize your repository. Place the .dmg file into /munki_repo/pkgs/apps/mozilla/. The pkgs folder CAN be one big directory full of .dmg files, but putting them into folders makes it a lot cleaner and easier to use. A note to be made here is that all files must be flat, the best way to make sure a file is flat (that is, not a series of folders, as most .pkgs and .apps are), is to place it into a .dmg file (Putting Packages into DMGs). Thankfully, Firefox comes in a .dmg so we do not need to worry about this.
  3. Now that your Firefox .dmg file is in place, open Terminal.app (/Applications/Utilities/Terminal.app).
  4. Its time to generate our first pkginfo file. We will generate the pkginfo files on a client machine. As a side note, I typically install munkitools on my main machine and use it to do all the maintenance work on my munki repository. On my xserve, I setup an AFP share for the munki repo so I can easily mount it and manipulate the files in it from my main client machine. If you are hosting this on something other then an xserve, an SMB or NFS file share would work just as well for this purpose. Before we run the command to create info about the packages, lets create some directory structure like we did with the pkgs directory. In the pkgsinfo directory, create a new directory named apps and another within apps named Mozilla. It is generally best to have this mirror your pkgs folder structure. Then, in terminal, type the following:
/usr/local/munki/makepkginfo /path/to/munki_repo/pkgs/apps/mozilla/Firefox 3.6.10.dmg > /path/to/munki_repo/pkgsinfo/apps/mozilla/Firefox-3.6.10


This will generate a pkginfo file for your Firefox.dmg installer. (As an alternative, you can use a new tool Greg released named munkiimport).It should be noted that the pkginfo file does not need an extension (just like everything in OS X), but one can be appended if it is useful for you (I personally use .pkginfo). Firefox is a simple drag and drop .app install and munki is smart enough to realize that and the pkginfo file reflects that fact:

<?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>autoremove</key>
	<false/>
	<key>catalogs</key>
	<array>
		<string>testing</string>
	</array>
	<key>installer_item_hash</key>
	<string>10ede8228c869ba4b03611b6ec750acbccf879f20ce52cb86e1baf6972f60fb0</string>
	<key>installer_item_location</key>
	<string>mozilla/Firefox 3.6.10.dmg</string>
	<key>installer_item_size</key>
	<integer>18996</integer>
	<key>installer_type</key>
	<string>copy_from_dmg</string>
	<key>installs</key>
	<array>
		<dict>
			<key>CFBundleIdentifier</key>
			<string>org.mozilla.firefox</string>
			<key>CFBundleName</key>
			<string>Firefox</string>
			<key>CFBundleShortVersionString</key>
			<string>3.6.10</string>
			<key>path</key>
			<string>/Applications/Firefox.app</string>
			<key>type</key>
			<string>application</string>
		</dict>
	</array>
	<key>items_to_copy</key>
	<array>
		<dict>
			<key>destination_path</key>
			<string>/Applications</string>
			<key>source_item</key>
			<string>Firefox.app</string>
		</dict>
	</array>
	<key>minimum_os_version</key>
	<string>10.4.0</string>
	<key>name</key>
	<string>Firefox</string>
	<key>uninstall_method</key>
	<string>remove_copied_items</string>
	<key>uninstallable</key>
	<true/>
	<key>version</key>
	<string>3.6.10.0.0</string>
</dict>
</plist>


This pkginfo file is chock full of good information, but there are several key items that must be noted:

  • Catalogs - Catalogs are a file on the munki repo that are generated when you run the makecatalogs command. The purpose of these catalogs is to separate out software that you are testing from software that you want production machines to get. You can use several different catalogs if you like, but for this guide we will only use testing and production. For now the testing catalog is the only one we want this to be a member of until we've had a chance to verify it works properly.
  • installer_type - This indicates that munki correctly identified this as an item that will be copied from a dmg to a specified location. This works hand in hand with the items_to_copy key. There are several different installer types, including ones that are specifically written to function with Adobe updates.
  • installs - This key lists important information about what is being installed. This shows the CFBundleIdentifier, as well as the CFBundleShortVersionString, which is used to compare versions. If an installs key is present,receipts are not used to determine if it needs to be installed. The Firefox installer does not have any receipts since it is drag and drop, so this fact is irrelevant for our Firefox install.
  • items_to_copy - This specifies where the item in the .dmg is being copied to and what specifically in the .dmg is being copied. You can clearly see that Firefox.app is being copied to /Applications.
  • name - This is the name that we will refer to this software as in our manifest files (The files that tell the client what they need to install).
  • version - This shows the version of the item that is being installed.


All this information is used by munki as it runs. For instance, if you have Firefox-3.6.9 and Firefox-3.6.10 pkginfo files, both with the name of Firefox, it will only install the latest version (3.6.10). In fact, if you have Firefox as a managed install, it will also look at a clients Firefox version and if it is less then 3.6.10, it will go ahead and install the latest version of Firefox.
Now that we have a software package in the munki repo and we have pkginfo generated for that item, it is time to update our catalogs to reflect the new item. The tool used to do this is /usr/local/munki/makecatalogs. It looks through each pkginfo file in the repository and which catalogs they belong to as per the catalogs key mentioned above and generates one catalog for each catalog referenced. In this case, it will only generate one file named "testing". To do so, issue this command:

/usr/local/munki/makecatalogs /path/to/munki_repo
 
Adding apps/mozilla/Firefox-3.6.10 to testing...

</br> You can see that it added apps/mozilla/Firefox-3.6.10 to testing, which is the catalog we specified in the pkginfo file. If you browse to munki_repo/catalogs you'll notice there are now two new files, one named all and one named testing. Within these files, you'll find information regarding the Firefox installer. This is pretty much a copy of the pkginfo file. The point of the catalog files is that you can separate out installers by their status as a package. If you are not quite done testing it yet, I would put it in a catalog such as testing. If you have a pilot group that is beta testing a newer version of Firefox, you could have a catalog named 'beta' if you'd like. The catalog system is quite flexible as far as what you can do with it. Moving on to manifests, you will see how the catalogs become useful.
To make your first manifest, use the following as a template. Just create a new text document named desktops in munki_repo/manifests and paste the following into it:(taken from the Google code page for munki and modified for this guide)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>catalogs</key>
	<array>
		<string>testing</string>
	</array>
 
	<key>managed_installs</key>
	<array>
		<string>Firefox</string>
	</array>
 
	<key>managed_uninstalls</key>
	<array>
	</array>
</dict>
</plist>


Specified first and foremost in the manifest is the catalog. This tells munki which catalog to search for the items listed in the manifest. In this case, we only have testing, but you could have testing and production. If an item is present in both, it will install the software from whichever catalog is listed first.
Next we have managed_installs. This tells munki to install the software listed, in this case Firefox. Munki will install that software and make sure it stays installs. If you update the software package for Firefox to 3.6.11 in the repo (add .dmg and create pkginfo), it will recognize that there is a newer version in the repository and install it if it is in the correct catalogs. If the user drags and drop Firefox to the trash, munki will reinstall it on next run. managed_installs indicates that it will make sure any applications listed are installed and of the latest version in the repository, even if it means reinstalling them.
Much like managed_installs, you also have managed_uninstalls. This is mainly useful for uninstalling software that used to be managed, but you no longer want on the client machine. It will use whatever uninstall_method is specified in that software's pkginfo file. If the end users re-installs the software, it will uninstall it.
That's it for the repository configuration, so lets move on to the client.

Configuring the Client[edit]

The default configuration file for the client is located here:

/Library/Preferences/ManagedInstalls.plist

There are many things that you can set via this preference file, but at the moment we are only interested in the basics. (More about the various options here: Munki Configuration).Here is the default ManagedInstalls.plist that gets installed with munkitools:

<<?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>ClientIdentifier</key>
    <string></string>
    <key>DaysBetweenNotifications</key>
    <integer>1</integer>
    <key>InstallAppleSoftwareUpdates</key>
    <false/>
    <key>LogFile</key>
    <string>/Library/Managed Installs/Logs/ManagedSoftwareUpdate.log</string>
    <key>LoggingLevel</key>
    <integer>1</integer>
    <key>ManagedInstallDir</key>
    <string>/Library/Managed Installs</string>
    <key>PackageVerificationMode</key>
    <string>hash</string>
    <key>SoftwareRepoURL</key>
    <string>http://munki/repo</string>
    <key>SoftwareUpdateServerURL</key>
    <string></string>
    <key>SuppressAutoInstall</key>
    <false/>
    <key>SuppressStopButtonOnInstall</key>
    <false/>
    <key>SuppressUserNotification</key>
    <false/>
    <key>UseClientCertificate</key>
    <false/>
</dict>
</plist>

To customize this file for your own use, put the name of your web server instead of 'webserver' and for 'manifest_name' change it to desktops. We want to have munki prompt our users for Apple Software Updates, so change the InstallAppleSoftwareUpdates key from <false/> to <true/>. The resulting ManagedInstalls.plist file should look 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>ClientIdentifier</key>
	<string>desktops</string>
	<key>DaysBetweenNotifications</key>
	<integer>1</integer>
	<key>InstallAppleSoftwareUpdates</key>
	<true/>
	<key>LogFile</key>
	<string>/Library/Managed Installs/Logs/ManagedSoftwareUpdate.log</string>
	<key>LoggingLevel</key>
	<integer>1</integer>
	<key>ManagedInstallDir</key>
	<string>/Library/Managed Installs</string>
	<key>PackageVerificationMode</key>
	<string>hash</string>
	<key>SoftwareRepoURL</key>
	<string>http://mymunkiserver/munki_repo/</string>
	<key>SoftwareUpdateServerURL</key>
	<string></string>
	<key>SuppressAutoInstall</key>
	<false/>
	<key>SuppressStopButtonOnInstall</key>
	<false/>
	<key>SuppressUserNotification</key>
	<false/>
	<key>UseClientCertificate</key>
	<false/>
</dict>
</plist>

This customized ManagedInstalls.plist must be deployed to the client for it to work properly. It can be copied into place using ARD, SCP from the command line or via a package (I put a munki configuration package at the end of my DeployStudio imaging workflow, so it can be changed without rebuilding the image). Regardless of how the file gets put into place, it is necessary that you put it into place after installing the munkitools package.
Now that we have the ManagedInstalls.plist customized for our needs, there are only two steps to configuring a client:

  1. Install munkitools
  2. Put the custom ManagedInstalls.plist into place (ARD, Package, Script, etc).


Now to test our configuration. With our current manifest (desktops), Firefox is listed as a managed install. One of three things will occur:

  1. Munki will install Firefox because it isn't present.
  2. Munki will install Firefox because the version currently installed is older then the version in munki.
  3. Munki will not install Firefox because it is already installed and matches the version in the munki repo.

Munki will always look at the client to see if the managed_installs software is present and up to date. In the case of Firefox, it compares the version installed to the version in the repo to determine if it must do anything or not. This is determined by the installs key in the pkginfo file or if no installs keys are present, it will use the receipts data to determine the appropriate action. Note: If an installs key is present, receipts are not used for this function.

Doing a Test Run[edit]

Lets do our first run of munki. We'll do it manually using terminal to make sure it is working properly.

  1. Open Terminal (/Applications/Utilities/Terminal.app)
  2. Type the following:
sudo /usr/local/munki/managedsoftwareupdate --verbose

This will run munki in verbose mode and give us more detail about what is going on. This is similar to running managedsoftwareupdate --checkonly, but with more output.

This is what the output should look like:

Managed Software Update Tool
Copyright 2010 The Munki Project
http://code.google.com/p/munki
 
Getting manifest client_manifest...
	0..20..40..60..80..100
Using manifest: desktops
**Checking for installs**
Getting catalog testing...
Retreiving catalog "testing"...
	0..20..40..60..80..100
Need to install Firefox
Downloading Firefox 3.6.10.dmg from Apps/Mozilla/Firefox 3.6.10.dmg
Downloading Firefox 3.6.10.dmg...
	0..20..40..60..80..100
**Checking for removals**
**Checking for managed updates**
The following items will be installed or upgraded:
    + Firefox-3.6.10.0.0
 
Run managedsoftwareupdate --installonly to install the downloaded updates.


This shows us that it has pulled down the manifest file (desktops) and checked it to see what needs to be done. Then, it sees that Firefox is a managed_installs item and checks the computer to see if it exists or not. In this case, my test machine does not have Firefox installed, so it downloads the installer DMG from the server and puts it into the cache (/Library/ManagedInstalls/Cache/). It then checks for removals and managed updates, finding none, it completes by summarizing what actions will be taken, in this case, Installing Firefox.

Lets install the update from command line as well and see what it looks like:

Managed Software Update Tool
Copyright 2010 The Munki Project
http://code.google.com/p/munki
 
Installing Firefox (1 of 1)...
Mounting disk image Firefox 3.6.10.dmg...
Copying Firefox.app to /Applications...
The software was successfully installed.

We can see that the Firefox dmg gets mounted, munki copies Firefox.app to /Applications and it reports a successful install. We have just deployed our first piece of software using munki!

If you want to see what it looks like from the end user perspective, you can open the Managed Software Update.app (/Applications/Utilities/Managed Software Update.app). This has a very nice GUI and displays the updates in a fashion that looks just like the Apple Software Updates interface that the end user us accustomed to.

Another way to push out updates is to run /usr/local/munki/managedsoftwareupdate --auto. This will take the appropriate action depending upon the computer's state. If the machine is at the login window, Munki will hide the login window and display a status bar while it checks and installs updates if necessary. This prevents the user from logging in while updates are running. If the user is logged in, it will check for updates and if any are needed, it will pop up the Managed Software Update.app interface and prompt them to update.

There are many things that can be done with munki and this guide is a just an extremely simple setup. Using munki you can do many things, from Managing Printers to managing CS5 Installs and Updates. For a fill list of things munki can do and guides on how to do them, see the Munki Wiki pages on its Google code page.