Home > AppleScript, Automator, Mac administration, Mac OS X, Packaging, Payload-Free Package Creator > Payload-Free Package Creator.app Revisited

Payload-Free Package Creator.app Revisited

I do a lot of work with payload-free packages and while I have a process for creating them as I needed them with pkgbuild, this approach requires some setup work. To help make the package creation process more convenient, I developed Payload-Free Package Creator.app, an Automator application that will allow to select an existing script and create a payload-free package that runs the selected script.

However, this tool has used pkgbuild‘s –nopayload function, which creates a package which doesn’t leave an installer receipt behind. This is intended behavior according to Apple, but not leaving a receipt behind can make it hard to determine whether an installer package has been run on a particular machine. This is especially problematic for Munki, which uses receipts along with other methods to track installation status.

While I don’t use Munki, I’ve heard from a number of folks who do and who had run into the no-receipt problem when they tried to use payload-free packages generated by Payload-Free Package Creator.app with Munki.

So the problem was this:

  1. I wanted to create payload-free packages which only run scripts and do not install files.
  2. I wanted to have an installer receipt.
  3. Apple’s built-in method for generating payload-free packages with pkgbuild didn’t provide receipts.
  4. I thought I needed to provide a payload to pkgbuild in order to generate a package which would provide receipts.
  5. Providing a payload meant I was installing files, which is what I didn’t want to do.

The matter had rested there for a while and I didn’t see a good way to fix it.

Fortunately, I was wrong about point 4. Greg Neagle recently documented that you can make a package with pkgbuild that, while not technically payload-free, will act just like one. The key is to create an empty directory and set pkgbuild‘s –root option to look there for files. pkgbuild‘s –root option is used to tell pkgbuild which files to package, but since there will be no files in an empty directory, the package will install no files on the destination Mac.

That’s where I had gone wrong on point 4 – I thought I had to give pkgbuild something to install in order to build a package with a receipt, but it turns out that pkgbuild will successfully build a package while using an empty payload directory. This information allowed me to reconcile points 1 and 2, which resolved the problem.

With this new information, I was able to update Payload-Free Package Creator.app and I’m happy to announce it has two new features:

  • Version numbering
  • Packages generated by Payload-Free Package Creator.app will leave receipts behind after installation.

For more details, see below the jump.

Using Payload-Free Package Creator.app

 

1. If needed, download the Payload-Free_Package_Creator_Application.zip file from the application directory in my GitHub repo.

2. Once downloaded and unzipped, double-click on the Payload-Free Package Creator application.

3. You’ll be prompted to select the script that you want to use as part of creating the installer package.

Screen Shot 2015 05 21 at 7 52 25 AM

 

4. Once you’ve selected the script, you’ll be prompted to name the installer package. By default, the name filled in will be Payload Free Installer Package.

Screen Shot 2015 05 21 at 7 52 44 AM

 

This name can be changed as desired.

Screen Shot 2015 05 21 at 7 52 57 AM

 

5. Once you’ve entered a name for the installer package, you’ll be prompted for a package identifier. By default, the name filled in will be com.github.payload_free.

Screen Shot 2015 05 21 at 7 53 20 AM

 

This name should be changed to be something unique.

Screen Shot 2015 05 21 at 7 53 42 AM

 

6. Once you’ve entered an identifier for the installer package, you’ll be prompted for a version number. By default, the value filled in will be 1.0.

Screen Shot 2015 05 21 at 7 53 51 AM

 

This value should be changed to be something unique.

Screen Shot 2015 05 21 at 7 54 06 AM

 

7. Once the package name, package identifier and package version number have been set, Payload-Free Package Creator.app will prompt for an administrator’s username and password.

Screen Shot 2015 05 21 at 7 54 30 AM

 

8. Once the admin username and password are provided, Payload-Free Package Creator.app will create the installer package and prompt you when it’s finished.

Screen Shot 2015 05 21 at 7 54 43 AM

 

9. Click OK at the prompt and a new Finder window will open and display the newly-created installer package.

Screen Shot 2015 05 21 at 7 55 44 AM

Screen Shot 2015 05 21 at 7 55 50 AM

 

10. Payload-Free Package Creator.app will automatically exit.

 

How Payload-Free Package Creator.app works

Payload-Free Package Creator.app is an Automator application that uses AppleScript, shell scripting and pkgbuild behind the scenes to create installer packages which only run scripts but which will leave behind receipts. When a script is selected, the following process takes place:

  1. The script is copied to /tmp and renamed to postinstall, to match the name that pkgbuild is expecting for a post-installation script.
  2. After the package name, package identifier and package version number are chosen, /tmp is checked to make sure that there is not an existing directory that is named the same as the chosen name. If a matching directory is found, it is removed.
  3. A new directory is created in /tmp that matches the chosen name of the package.
  4. Next, a scripts directory and an empty directory named nopayload are created inside of /tmp/package_name_here. The nopayload directory provides the empty directory for pkgbuild‘s –root option.
  5. The postinstall script is copied to /tmp/package_name_here/scripts
  6. The package is built by pkgbuild using the postinstall script stored in /tmp/package_name_here/scripts
  7. The finished package is stored in /tmp/package_name_here and the user is prompted that the process is finished.
  8. Once the user is notified and clicks OK, a new Finder window opens for /tmp/package_name_here.

The AppleScript used to create the payload-free package as part of the Automator work is below:


on run {input, parameters}
— this repeat loop prevents empty strings from being submitted for the package name value
set q to 0
repeat while q is 0
set result to text returned of (display dialog "Enter a Name For Your Payload-Free Installer Package:" default answer "Payload-Free Installer Package")
if result is not "" then
set pkgname to result
set q to 1
end if
end repeat
— this repeat loop prevents empty strings from being submitted for the package identifier value
set q to 0
repeat while q is 0
set result to text returned of (display dialog "Enter a Package Identifier:" default answer "com.github.payload_free")
if result is not "" then
set pkgid to result
set q to 1
end if
end repeat
— this repeat loop prevents empty strings from being submitted for the version identifier value
set q to 0
repeat while q is 0
set result to text returned of (display dialog "Enter a Version Identifier:" default answer "1.0")
if result is not "" then
set pkgvers to result
set q to 1
end if
end repeat
— Set the postinstall script to be executable
do shell script "chmod a+x /tmp/postinstall" with administrator privileges
— Remove any existing build directories that have the same name as the new payload-free package
do shell script "rm -rf /tmp/" & quoted form of pkgname & "/" with administrator privileges
— Create the build directories for the payload-free package
do shell script "mkdir /tmp/" & quoted form of pkgname & "" with administrator privileges
do shell script "mkdir /tmp/" & quoted form of pkgname & "/scripts" with administrator privileges
do shell script "mkdir /tmp/" & quoted form of pkgname & "/nopayload" with administrator privileges
— Move the postinstall script into the correct build directory
do shell script "mv /tmp/postinstall /tmp/" & quoted form of pkgname & "/scripts" with administrator privileges
— Build the payload-free package
do shell script "pkgbuild –identifier " & quoted form of pkgid & " –version " & quoted form of pkgvers & " –root /tmp/" & quoted form of pkgname & "/nopayload –scripts /tmp/" & quoted form of pkgname & "/scripts /tmp/" & quoted form of pkgname & "/" & quoted form of pkgname & ".pkg" with administrator privileges
— Display dialog that the payload-free package has been created
display alert ((pkgname) as string) & ".pkg has been created."
— Open a new Finder window that shows the new package
do shell script "open /tmp/" & quoted form of pkgname & ""
return input
end run

 

All Payload-Free Package Creator components and scripts are available at my GitHub repo:

https://github.com/rtrouton/Payload-Free-Package-Creator

The Automator workflow files and the AppleScript are also available via the link above if you want to build a customized Payload-Free Package Creator for your own environment.

 

An installer for the latest release of Payload-Free Package Creator.app is available via the link below:

https://github.com/rtrouton/Payload-Free-Package-Creator/releases/latest

  1. cashxx
    May 21, 2015 at 10:12 pm

    Yay! Thanks for the update, will have to check it out! Glad to see it working with Munki!

  2. May 29, 2015 at 1:43 am

    Would be cool to have an option to sign the package with a dev cert. I’ve got an idea of how to identify the correct string for the –sign switch from the keychain but I’m too weak with Applescript to cleanly implement it. This should get you the right string and put nothing if there’s not cert:

    security find-certificate -c “Developer ID Installer:” | grep “labl” | awk -F ‘=’ ‘{ print $2 }’ | sed ‘s/\”//g’ 2>/dev/null

    Or even just an easy squeezy cut and paste string here option. Hopefully someone better at Applescript than me can add that.

  3. June 8, 2015 at 1:25 pm

    Reblogged this on SutoCom Solutions.

  4. July 17, 2015 at 9:30 am

    Thanks for sharing this with the community! The original solution by Greg Neagle from 2010 didn’t work for me. The included script did not execute correctly. Your suggestion does work. Only downside is that it’s not a application bundle. That means building a new installer everytime you need to change to postinstall script. But that only takes 30 seconds, so who cares…

  5. Walter
    April 20, 2016 at 9:47 pm

    Hi Rich, thanks for making this great tool.

    I created a package and assigned a version number, however after running the package I am not able to see the package version number in the /Library/Receipts/InstallHistory.plist. Specifically the String is blank under the “displayVersion” Key. Is there something I am missing? Here is what I’m seeing:

    date
    2016-03-17T20:54:23Z
    displayName
    package_name
    displayVersion

    packageIdentifiers

    com.mycompany.packagename

    processName
    installer

  6. Walter
    April 21, 2016 at 3:40 pm

    Never mind, I was looking in the wrong directory. /private/var/db/receipts/ is where the receipt is located. Thanks!

  1. No trackbacks yet.

Leave a comment