Archive

Archive for February, 2022

Using custom variables in an AutoPkg recipe to set version information

February 22, 2022 1 comment

As part of a recent task to build an AutoPkg recipe which creates an installer package for a screen saver, I ran into an issue. The vendor, for reasons that no doubt make sense to them, split the version information for the screen saver across two separate keys:

  • Major part of the version number: Stored in the CFBundleShortVersionString key of the screen saver’s Info.plist file
  • Minor part of the version number: Stored in the CFBundleVersion key of the screen saver’s Info.plist file

What this meant is that for version 1.4 of the screen saver, the version information was stored as follows:

  • CFBundleShortVersionString key: 1
  • CFBundleVersion key: 4

Getting this information was not the problem. AutoPkg includes a PlistReader processor which allows multiple values to be read from one plist file, so I used it as shown below to read the CFBundleShortVersionString key’s and the CFBundleVersion key’s values and store them in the following variables:

  • CFBundleVersion key: minor_version
  • CFBundleShortVersionString: major_version


<dict>
<key>Arguments</key>
<dict>
<key>info_path</key>
<string>%pathname%/Carousel Cloud.saver/Contents/Info.plist</string>
<key>plist_keys</key>
<dict>
<key>CFBundleVersion</key>
<string>minor_version</string>
<key>CFBundleShortVersionString</key>
<string>major_version</string>
</dict>
</dict>
<key>Processor</key>
<string>PlistReader</string>
</dict>

view raw

gistfile1.txt

hosted with ❤ by GitHub

So now I had the version info (in separate pieces) and now I needed to put them together. The problem I was seeing was that my usual solution, AutoPkg’s Versioner processor is set up to read one value from a plist file. I had two values and neither were in a plist file.

Fortunately, there are multiple ways to solve this problem. The first I thought of was to build a new plist as part of the recipe’s run and put the version information in. The workflow works like this:

1. Use the PlistReader processor to read the desired information.
2. Use the FileCreator processor processor to create a new plist file with the version information formatted as needed.
3. Use the PlistReader processor to read the version information out of the newly-created plist file.


<dict>
<key>Arguments</key>
<dict>
<key>info_path</key>
<string>%pathname%/Carousel Cloud.saver/Contents/Info.plist</string>
<key>plist_keys</key>
<dict>
<key>CFBundleVersion</key>
<string>minor_version</string>
<key>CFBundleShortVersionString</key>
<string>major_version</string>
</dict>
</dict>
<key>Processor</key>
<string>PlistReader</string>
</dict>
<dict>
<key>Processor</key>
<string>FileCreator</string>
<key>Arguments</key>
<dict>
<key>file_path</key>
<string>%RECIPE_CACHE_DIR%/com.companyname.carouselcloudscreensaver.plist</string>
<key>file_mode</key>
<string>0755</string>
<key>file_content</key>
<string>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
&lt;dict&gt;
&lt;key&gt;complete_version&lt;/key&gt;
&lt;string&gt;%major_version%.%minor_version%&lt;/string&gt;
&lt;/dict&gt;
&lt;/plist&gt;
</string>
</dict>
</dict>
<dict>
<key>Arguments</key>
<dict>
<key>info_path</key>
<string>%RECIPE_CACHE_DIR%/com.companyname.carouselcloudscreensaver.plist</string>
<key>plist_keys</key>
<dict>
<key>complete_version</key>
<string>version</string>
</dict>
</dict>
<key>Processor</key>
<string>PlistReader</string>
</dict>

view raw

gistfile1.txt

hosted with ❤ by GitHub

This approach works, but now you have a plist file to clean up later. Another approach is to use custom variable assigning as part of another AutoPkg processor’s run. In this case, you’re using an AutoPkg processor and adding a separate argument which is probably unrelated to the other work the processor is doing, but does the value assignment work you couldn’t accomplish otherwise.

A pretty safe processor to use for this is the EndOfCheckPhase processor. The reason is that by itself, the EndOfCheckPhase processor takes no actions. Instead, it’s used as a marker in AutoPkg recipes to tell AutoPkg to stop checking for new information as part of a recipe’s run. However, even though the EndOfCheckPhase processor doesn’t take actions and doesn’t by default include Arguments values, AutoPkg will still process Arguments values if they’re defined for the EndOfCheckPhase processor. That allows custom variables to be set with values that you couldn’t otherwise set and pass them to AutoPkg. The workflow in this case looks like this:

1. Add the EndOfCheckPhase processor to the very end of the recipe.
2. Perform the desired variable assignment as an Arguments value

The reason to add it to the end is to make sure that all of the other tasks the recipe is performing are completed by the time this processor runs.

In this case, I used this method with the the EndOfCheckPhase processor in the screen saver’s .download recipe to assign the version variable to use the values of the major_version and minor_version variables, separated by a period.


<dict>
<key>Processor</key>
<string>EndOfCheckPhase</string>
<key>Arguments</key>
<dict>
<key>version</key>
<string>%major_version%.%minor_version%</string>
</dict>
</dict>

view raw

gistfile1.txt

hosted with ❤ by GitHub

The result for the latest version of the screen saver software is that the version variable is assigned the following value:


'version': '1.4'

view raw

gistfile1.txt

hosted with ❤ by GitHub

I’ve posted the recipes which use this technique for setting version information to GitHub. They’re available via the link below:

https://github.com/autopkg/rtrouton-recipes/tree/master/CarouselCloudScreenSaver

Categories: AutoPkg, macOS

Jamf Pro Server software no longer supported on macOS as of Jamf Pro 10.37.0

February 21, 2022 2 comments

To follow up on my earlier posts on the Jamf Pro Server Installer for macOS being retired, Jamf has added the following to the Deprecations and Removals section of the Jamf Pro 10.36.0 release notes:

Support Ending for Hosting Jamf Pro Server on macOS—Starting with the release of Jamf Pro 10.37.0, hosting the Jamf Pro server on macOS will no longer be supported. Mac computers with Apple silicon are not supported by the Jamf Pro Installer for macOS. In addition, the Jamf Pro Installer for macOS will not be available to download. The Jamf Pro utilities that were included in the Jamf Pro Installer for macOS—Composer, Jamf Admin, Jamf Recon, and Jamf Remote—will be made available as a separate download.

If you want to migrate your Jamf Pro server from macOS to Jamf Cloud, contact Jamf Support. If you want to keep your server on premise, you can migrate your Jamf Pro server to one of the following servers: Red Hat Enterprise Linux, Ubuntu, or Windows. For more information, see the Migrating to Another Server article.

Screen Shot 2022 02 21 at 9 28 09 AM

For those folks who are running on-premise Jamf Pro servers on Macs, I strongly recommend contacting Jamf Support right now and plan a migration if you haven’t already. As of February 21st, 2022, Jamf’s published support for running Jamf Pro includes the following OS, database and Java versions:


Recommended Configuration:
Operating Systems:
Windows Server 2019
Ubuntu Server 20.04 LTS
Red Hat Enterprise Linux 7.x
Database software versions:
MySQL 8.0.27 – InnoDB
Amazon Aurora (MySQL 5.7 compatible)
MySQL 5.7.36 or later – InnoDB
Java version:
OpenJDK 11
Minimum Supported:
Operating Systems:
Windows Server 2016
Windows Server 2012 R2
Ubuntu Server 18.04 LTS
macOS 10.15 (Support for the Jamf Pro Installer for macOS and hosting Jamf Pro server on macOS will be discontinued with the release of Jamf Pro 10.37.0.)
macOS 10.14 (Support for the Jamf Pro Installer for macOS and hosting Jamf Pro server on macOS will be discontinued with the release of Jamf Pro 10.37.0.)
Database software versions:
MySQL 5.7.36 – InnoDB
MySQL 5.7.8 on Amazon RDS – InnoDB
Java version:
Oracle Java 11

view raw

gistfile1.txt

hosted with ❤ by GitHub

Categories: Jamf Pro, macOS

Using AutoPkg to get the latest Jamf Protect installer and uninstaller from your Jamf Protect tenant

February 17, 2022 Leave a comment

Jamf has enabled a new feature on Jamf Protect tenants, where you can generate a download URL for the latest Jamf Protect client installer and uninstaller. These download URLs do not require authentication, but a security identifier unique to the Jamf Protect tenant needs to be included as part of the download URL:

Screen Shot 2022 02 17 at 4 47 20 PM

Once generated, the download links are formatted similar to this:

Installer:

Screen Shot 2022 02 17 at 4 49 33 PM

 

Uninstaller:

Screen Shot 2022 02 17 at 4 51 30 PM

 

For example, if the Jamf Protect tenant and security identifier were as shown below, the curl commands would look like this:

  • Jamf Protect tenant: companyname.protect.jamfcloud.com
  • Security token: c1f0d1cb-8ddc-4f36-9578-58a7388053d5

Installer:

Uninstaller:

Since the Jamf Protect installer and uninstaller can be downloaded from your Jamf Protect tenant, this means that it’s now possible to use AutoPkg to get the latest Jamf Protect client installer and uninstaller as soon as they are available from your Jamf Protect tenant. For more details, please see below the jump.

Read more…

Categories: AutoPkg, Jamf Protect

autopkg-conductor updated to support both JamfUploaderSlacker and Slacker AutoPkg processors

February 12, 2022 Leave a comment

As part of my preparations for Jamf’s planned authentication changes to the Classic API, I’ve been working more with the JamfUploader AutoPkg processors for Jamf Upload. These processors have emerged as a successor to JSSImporter, the original tool available to upload installer packages and other components to Jamf Pro using AutoPkg.

As part of my work with Jamf Upload, I’ve also updated my autopkg-conductor script to allow the use of either Jamf Upload’s JamfUploaderSlacker AutoPkg processor or JSSImporter’s Slacker AutoPkg processors. For more details, please see below the jump.

Read more…

Querying an API for AutoPkg download URLs

February 3, 2022 Leave a comment

As part of working on a new AutoPkg download recipe today, I very quickly got stuck on a problem. The app in question is Poly’s Lens software and its download page uses JavaScript to provide the download URL for the latest version of the Lens software. While this may have benefits for the vendor, this means I can’t scrape the page for the download URL’s address using AutoPkg.

Discussing the issue in the #autopkg channel of the MacAdmins Slack, folks started poking around the Lens app and discovered that it was using the Squirrel framework to provide software update functionality to the app. Assuming that meant that the app would phone home for updates, ahousseini was kind enough to monitor the app’s HTTP and HTTPS traffic using CharlesProxy. Shortly thereafter, he reported seeing Lens send the following API request using curl:


curl \
-H 'Host: api.silica-prod01.io.lens.poly.com' \
-H 'accept: application/json, text/javascript, */*; q=0.01' \
-H 'content-type: application/json' \
-H 'origin: https://www.poly.com&#39; \
-H 'apollographql-client-name: poly.com-website' \
-H 'accept-language: en-GB,en;q=0.9' \
-H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.3 Safari/605.1.15' \
-H 'referer: https://www.poly.com/&#39; –data-binary '{"query":"\n query {\n availableProductSoftwareByPid(pid:\"lens-desktop-mac\") {\n name\n version\n publishDate\n productBuild {\n archiveUrl\n }\n }\n }"}' \
–compressed 'https://api.silica-prod01.io.lens.poly.com/graphql&#39;

view raw

gistfile1.txt

hosted with ❤ by GitHub

This HTTPS traffic was Lens sending an API request to see if it was running the latest version of the software. The relevant parts from our perspective were the items shown below:

This told us what format we should expect API output to be (in this case, JSON):


-H 'content-type: application/json'

view raw

gistfile1.txt

hosted with ❤ by GitHub

This told us the query which was being sent to the API endpoint:


–data-binary '{"query":"\n query {\n availableProductSoftwareByPid(pid:\"lens-desktop-mac\") {\n name\n version\n publishDate\n productBuild {\n archiveUrl\n }\n }\n }"}'

view raw

gistfile1.txt

hosted with ❤ by GitHub

This told us the API endpoint:

Putting this information together, the following curl command gets a response from the API endpoint:


curl 'https://api.silica-prod01.io.lens.poly.com/graphql&#39; -H 'content-type: application/json' –data-binary '{"query":"\n query {\n availableProductSoftwareByPid(pid:\"lens-desktop-mac\") {\n name\n version\n publishDate\n productBuild {\n archiveUrl\n }\n }\n }"}'

view raw

gistfile1.txt

hosted with ❤ by GitHub

The API response looks similar to this:


{"data":{"availableProductSoftwareByPid":{"name":"Poly Lens Mac – 1.1.11","version":"1.1.11","publishDate":"2022-02-02T17:01:41.503Z","productBuild":{"archiveUrl":"https://swupdate.lens.poly.com/lens-desktop-mac/1.1.11/1.1.11/PolyLens-1.1.11.dmg&quot;}}}}

view raw

gistfile1.txt

hosted with ❤ by GitHub

Part of the API response’s output includes the download URL for the latest version:

Now that we have this information, how to use it with AutoPkg? For more details, please see below the jump:

Read more…

Categories: AutoPkg, macOS
%d bloggers like this: