Packaging CrashPlan PROe for Munki

A note before you begin...

This is not advanced Munki usage, but it is also more intermediate than beginner. If you aren't comfortable importing packages into Munki or editing pkgsinfo .plist files, you may want to start off with Absolute beginner’s guide to setting up Munki (not monkey).

Why the official deployment method won't work for Munki

Code42 has a guide for Preparing The Crashplan App For Deployment. It basically downloads (from your CrashPlan PROe server) a .zip file of some tools to customize your installation. To prepare for Munki, though, you shouldn't run the custom.sh script. What that script does is create a .Custom directory inside the disk image (.dmg) for CrashPlan, which it expects to be mounted at /Volumes/CrashPlanPROe. So if you run that script, and then you try to import the disk image into Munki using munkiimport, none of your customizations will take, because Munki will mount the disk image elsewhere (not /Volumes/CrashPlanPROe).

Tweaking the userInfo.sh Script

As you can see from Code42's official documentation, the two files you want to modify are custom.properties and userInfo.sh. I seem to be the only one who's run into this issue, but I kept getting the user as root with the default settings (because I'm installing the CrashPlan .pkg as sudo presumably, but that's how the .pkg file works). If you run into this issue, there's a trick to get the currently-logged-in user, even though you're essentially running the .pkg as root. There appears to be another way to get the most-recently-logged-in user (which is probably also the currently-logged-in user), too. I actually use a combination of the two, because I ran into a situation in which one method gave me _mbsetupuser, even though I was clearly logged in as another user.

So the middle section of my userInfo.sh looks like this:

# Find actually logged-in user (not root)
login_state=$(defaults read /Library/Preferences/com.apple.loginwindow.plist lastUser)

if [ "$login_state" == "loggedIn" ]; then

# If the user is logged in, the most reliable way to get the actual user is from this command
actual_user=$(ls -l /dev/console | awk '/ / { print $3 }')

else

actual_user=$(defaults read /Library/Preferences/com.apple.loginwindow.plist lastUserName)

fi
CP_USER_HOME="/Users/$actual_user"
user="$actual_user"

but I prefer the first method, because it will work for the most-recently-logged-in-user even if you're logged out. This comes in handy if you're installing CrashPlan along with a bunch of other Munki packages that require a logout or reboot. If you use the first method, you're going with the last actually logged in user. If you use the second method and at the login screen, you'll get root.

Tweaking the pkginfo .plist for CrashPlan

Once you've imported CrashPlan into Munki, you may have to do the following (I did). First, you may have to put in an installs array. Before I put that in, Munki kept considering CrashPlan not to be installed and then got into an infinite reinstall loop.

To get the proper installs array (thanks, commenter Dan), run this command on a system that has CrashPlan and Munki installed:

/usr/local/munki/makepkginfo -f /Applications/CrashPlan.app
and you should see in the output something like this:
<key>installs</key>
<array>
<dict>
<key>CFBundleIdentifier</key>
<string>com.backup42.desktop</string>
<key>CFBundleName</key>
<string>CrashPlan</string>
<key>CFBundleShortVersionString</key>
<string>3.6.5</string>
<key>CFBundleVersion</key>
<string>3.6.5</string>
<key>path</key>
<string>/Applications/CrashPlan.app</string>
<key>type</key>
<string>application</string>
<key>version_comparison_key</key>
<string>CFBundleShortVersionString</string>
</dict>
</array>
Put that into your pkginfo .plist for CrashPlan, and the install loop will no longer happen.

For uninstalling, make the uninstall method in the .pkginfo (or .plist) this:

<key>uninstall_method</key>
<string>/Library/Application Support/CrashPlan/Uninstall.app/Contents/Resources/uninstall.sh</string>

Munki-fying CrashPlan custom settings (Method #1)

Greg Neagle (the author of Munki) has proposed making CrashPlan require a settings package for CrashPlan that puts the custom.properties and userInfo.sh files in /Library/Application Support/CrashPlan/custom. I would try that first, to see if it works for you. For some reason, it hasn't worked for me (and I've tried custom, Custom, and .Custom).

Munki-fying CrashPlan custom settings (Method #2)

What worked for me is a similar method that's a bit more convoluted. So I created a package that delivers a payload of the custom.properties and userInfo.sh files to /Library/Application Support/CrashPlan/.Custom, and then I have a preinstall script for CrashPlan temporarily copy those to /Volumes/CrashPlanPROe, as if the disk image were really mounted there. Then, when the installation is done, I have a postinstall script delete the files from the fake disk image.

Here's the preinstall script:

#!/bin/bash

# Copy over custom settings if they exist
if [ -d /Library/siprep/.Custom ]; then

# Make a temp directory
mkdir -p /Volumes/CrashPlanPROe/Custom

# Copy over the custom settings
cp -R /Library/siprep/.Custom/* /Volumes/CrashPlanPROe/Custom/

# Rename the Custom directory
mv /Volumes/CrashPlanPROe/Custom /Volumes/CrashPlanPROe/.Custom

fi
You may be thinking, "Uh, why don't you just copy .Custom instead of making a directory and then renaming it?" That's what I used to do, but something in Sierra broke that approach and gave Operation not permitted as an error—I'm assuming it has to do with copying a hidden directory.

Here's the postinstall script:

#!/bin/bash

# If there is the temporary /Volumes directory, then delete it

if [ -d /Volumes/CrashPlanPROe/.Custom ] && [ ! -d /Volumes/CrashPlanPROe/Install\ CrashPlanPROe.pkg ]; then

rm -r /Volumes/CrashPlanPROe

fi
Your mileage may vary. I'd definitely start with Greg Neagle's suggestion first and use my shoddy workaround only if you need to.

2 thoughts on “Packaging CrashPlan PROe for Munki”

  1. You should try populating the installs array with the output of the makepkginfo command (with the -f switch). Example:

    sudo /usr/local/munki/makepkginfo -f /Applications/CrashPlan.app

    Munki will grab (accurate) info like CFBundleVersion and the like. I originally discovered this when dealing with Adobe CC apps (kill me I’m hea) but I tend to use it whenever I find weird things in the contents pane of MunkiAdmin post munkiimport.

Leave a Reply

Your email address will not be published. Required fields are marked *