Using autopkg for “general purpose” packaging

A few days ago I made a simple tool for building packages available: munkipkg.

https://github.com/munki/munki-pkg

I got many comments and suggestions for additional features and all sorts of cool additions. Some have even been added to the tool already. But I would like to keep munkipkg a pretty simple, basic tool.

The Luggage (https://github.com/unixorn/luggage) has been around for a while; if munkipkg is too simple for your needs, please have look at that.

I also suggested to several people that if they had more complex needs than munkipkg could handle, it might make more sense to use autopkg, which supports very complex, customizable workflows.

I could tell by the awkward silence that my suggestion was confusing to some — that they had trouble grokking how to use autopkg to build packages “from scratch”, using files and scripts on the local disk.

So I created a GitHub repo demonstrating how to use autopkg in this manner. It’s here: https://github.com/gregneagle/autopkg-packaging-demo

munkipkg comes with three demo package projects. Two of the packages install files, the third is a “payload-free” package that simply runs a script when installed. The autopkg-packaging-demo duplicates these packages, but uses autopkg to build them instead of munkipkg.

(One could also imagine building these packages using either tool: the payload and scripts directories would be the same — in other words, you could have both a build-info.plist for munkipkg and a recipe for autopkg in the same package project directory.)

Assuming you have autopkg installed, you can `git clone` the repo, or download and expand the zip file, and run the autopkg recipes within.

I hope this clears up some confusion, and sparks some new ideas!

Using autopkg for “general purpose” packaging

Introducing munkipkg

https://github.com/munki/munki-pkg

munkipkg is a simple tool for building packages in a consistent, repeatable manner from source files and scripts in a project directory.

Files, scripts, and metadata are stored in a way that is easy to track and manage using a version control system like git.

Another tool that solves a similar problem is Joe Block’s The Luggage (https://github.com/unixorn/luggage). If you are happily using The Luggage, you can probably safely ignore this tool.

Though this tool may eventually be added to the set of tools installed with the Munki command-line tools, it’s not currently tied to Munki and can be run completely standalone.

Learn more here.

Introducing munkipkg

PSU MacAdmins 2015 Packaging Workshop

If you are participating in the Packaging Workshop on July 7th at the Penn State MacAdmins Conference, you may want to download some materials in advance when you aren’t competing with all the other people for limited conference Wi-Fi bandwidth. Note — don’t install these items — just download their installers and keep them handy for the workshop.

Silverlight pkg:
http://www.microsoft.com/getsilverlight/handlers/getsilverlight.ashx

Adobe Reader 11 pkg:
http://ardownload.adobe.com/pub/adobe/reader/mac/11.x/11.0.10/en_US/AdbeRdr11010_en_US.dmg

Google Earth pkg:
http://dl.google.com/earth/client/advanced/current/GoogleEarthMacNoUpdate-Intel.dmg

Firefox dmg:
http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/latest/mac/en-US/Firefox%2039.0.dmg

Google Chrome dmg:
https://dl.google.com/chrome/mac/stable/GGRO/googlechrome.dmg

Packages:
http://s.sudre.free.fr/Software/files/Packages.dmg

Some optional things:

Suspicious Package:
http://www.mothersruin.com/software/SuspiciousPackage/download.html

Pacifist:
https://www.charlessoft.com

PSU MacAdmins 2015 Packaging Workshop

Pseudo-“Payload-free” pkgs with pkgbuild

“Payload-free” packages — that is, Apple installer packages that do not have a file payload, but only run scripts, are a nice tool for OS X admins to have. They provide a convenient way to deliver and execute scripts as root. If you have a way to install packages on your managed machines, you can also run scripts as root by wrapping them in a “payload-free” package.

Rich Trouton has written up the basic procedure using the built-in `pkgbuild` tool: https://derflounder.wordpress.com/2012/08/15/creating-payload-free-packages-with-pkgbuild/

But payload-free packages built this way have a “feature” that can sometimes prove problematic. Flat packages built with pkgbuild using the --nopayload option do not leave receipts in the pkgutil database. This means it can be difficult to determine if a given payload-free package has already been installed on a given machine.

This is especially annoying with Munki: by default, when installing a package, Munki uses the package’s receipt(s) to determine whether or not the package has been installed. Without that receipt, and with no other information, Munki can’t tell if the package has been installed.

Fortunately, it’s trivial to make a pseudo-payload-free package that leaves a receipt. All we need to do is specify an empty payload!

Here’s how we make a “true” payload-free package (that does not leave a receipt):

pkgbuild --nopayload --scripts /path/to/scripts_dir --identifier org.example.payloadfree --version 1.0 MyGreatPayloadFree.pkg

and here’s a “pseudo” payload-free package that does leave a receipt:

mkdir empty
pkgbuild --root empty --scripts /path/to/scripts_dir --identifier org.example.payloadfree --version 1.0 MyGreatPayloadFree.pkg

That’s it! Instead of using the --nopayload option, we create an empty directory and point the --root option at it. The package is built with the empty payload, and when installed, the package leaves a receipt.

Pseudo-“Payload-free” pkgs with pkgbuild

Setting up server-side resources for Imagr testing

Imagr requires a web server (or servers) to get its workflows, images to restore, and packages to install.

In an earlier post, I described setting up an existing DeployStudio NBI for Imagr testing.

If you are testing Imagr, or even better, hoping to help with its development, you’ll need to configure a test server.

You’ll need a web server, and a way to get some files on it. I just used my existing Munki repo web server. I created a new folder called “testing” and copied a few packages into it. (For first-boot install, Imagr currently supports only flat packages. For immediate install, bundle packages are OK if they are at the root of a disk image/.dmg file.).

Next, create a configuration¬†plist. There’s an example here:¬†https://github.com/grahamgilbert/imagr#the-configuration-plist. Here’s another:

<?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>password</key>
  <string>40e78b0d11c553be61645796fdb9438271a23ed8b4aadb253a9222c6e4c861e2dbc75139000b0709fc0c5ad66b0f2573e38a72a8f629e270e59530fc3159d8e4</string>
  <key>workflows</key>
  <array>
    <dict>
      <key>name</key>
      <string>Munki Bootstrap</string>
      <key>description</key>
      <string>Installs the required pkgs to begin a Munki bootstrap on restart.</string>
      <key>components</key>
      <array>
        <dict>
            <key>type</key>
            <string>package</string>
            <key>url</key>
            <string>http://munki/repo/testing/DA_adminaccount_1.5.pkg</string>
            <key>pre_first_boot</key>
            <true/>
        </dict>
        <dict>
            <key>type</key>
            <string>package</string>
            <key>url</key>
            <string>http://munki/repo/testing/DisableSetupAssistant.pkg</string>
            <key>pre_first_boot</key>
            <true/>
        </dict>
        <dict>
            <key>type</key>
            <string>package</string>
            <key>url</key>
            <string>http://munki/repo/testing/munkitools-2.2.4.2431.pkg</string>
            <key>pre_first_boot</key>
            <true/>
        </dict>
        <dict>
            <key>type</key>
            <string>package</string>
            <key>url</key>
            <string>http://munki/repo/testing/munki_kickstart.pkg</string>
            <key>pre_first_boot</key>
            <true/>
        </dict>
      </array>
    </dict>
  </array>
</dict>
</plist>

The password is a hash for “LETMEIN”; you can certainly generate your own as explained here: https://github.com/grahamgilbert/imagr#password

The various URLs point to the pkgs I copied into the testing folder in my Munki repo share. Adjust as needed.

I saved this plist in the same folder as the testing pkgs as “testing.plist”. (Boring, I know.)
Make sure you can open it in a web browser before you continue — in my case it’s available
at http://munki/repo/testing/testing.plist

We are now done with the server config.

Boot a test client into the DeployStudio NBI that was configured as in my earlier post.

Open the Terminal.app.
We need to tell Imagr how to find the configuration plist, so:

defaults write com.grahamgilbert.Imagr serverurl http://munki/repo/testing/testing.plist

Make sure you replace the URL with the actual URL to the config plist you created.

Now launch Imagr:

/private/var/tmp/DSNetworkRepository/testing/Imagr.app/Contents/MacOS/Imagr

And bask in your success (or grumble at your failure…)

Setting up server-side resources for Imagr testing