Automate it! Hedge API example apps

Quick post to talk about some fun I’ve been having with the new Hedge API.

Background: Hedge is an awesome app for securely copying Camera Cards to multiple destinations to ensure data integrity and safety of the original footage. Hedge is one part of a workflow I build for my clients. Hedge is the first step in ensuring an easy and convenient transition from the cameras to the SAN to the tape archive powered by Archiware P5.

TL;DR

Using AppleScript and Automator I have built some apps to quickly set the file naming and data integrity preferences as we want them to be.  And also quickly change them to something else depending on the needed workflow.

API or Clickety click click

Copying camera cards copies is what we use Hedge for. Certain preferences like logs or receipts are great to have to ensure the copy succeeded. Also file naming conventions are good to have. Set and forget, right? But what if you did forget? Or if you’re new and don’t know the convention or you don’t read documentation. What do we do? One way to solve this is build an app that launches Hedge and sets the correct preferences. And if we want to copy USB sticks or something else then we can launch another app that prepares Hedge with a different set of preferences.  For extra points we just ask the user what they want with a nice dialog box and just do that.

hedge

Automator

Automator is awesome. Create workflows, apps, or services amongst many other things. For more info on Automator check out Apple’s official docs or this unofficial website of resources.

Automator.png

For this quick testing I used two AppleScripts with different preferences and settings defined. One for camera card copying and another for USB sticks that need different preferences set. The fancy automator app just calls the needed AppleScript. Make two apps and you have two different workflows without having to explain to users which prefs get set for what, or how the file naming should go to be consistent.

Example 1: Cam Card script (snippet)Hedge-Automator.png

Example 2: USB card copy (snippet)

Hedge-ApplesriptUSB.png

 

Automator can do many things. Call AppleScripts, Run shell scripts, pop-up dialog boxes etc and this is just a simple example of building single purpose apps to set Hedge via its new API. Very cool and so many possibilities.

AppleScript

What if we could just build one app which asked the user what they wanted to do? We can do that!

AppleScript-DialogQuit.png

Choose “Cam” and the appropriate preferences are set and file naming conventions applied.

Hedge-CamCard-Prefs.png

Hedge-CamCard-FileNaming.png

Choose “USB” and a different set of preferences are set. Magic.

Hedge-USBCard-Prefs.png

Hedge-USBCard-FileNaming.png

How do we do this? This piece of AppleScript chains an action to a response or button choice. Run a script or choose an action. The possibilities are endless. And thanks to the Hedge API we can set preferences on or off, and set destinations or many other things. We can do them programmatically and we can ensure they are set correctly. Fun times!

Hedge-API-Script-Quit.png

AppleScript vs POSIX:

I updated my AppleScript code with the POSIX path of the scripts it wants to load. It’s a major improvement! I had packaged up my scripts and my Hedge Setup app with munkipkg then deployed through Munki but when I demoed it — nothing worked…. because the start up disk drive was named something else. The fix: set a variable to be the POSIX path (Unix path in AppleScript friendly format).

Scripting and App Building

I hope that helped. We can do a lot of the same things with Python and in my testing I was working with a script written in python3 but since that’s not shipping on Macs in the current version of macOS by default (not yet!) then AppleScript was the quickest way to get this done. This is not restricted to AppleScript. Using Automator and your favourite scripting language you can build apps for your clients, co-workers, friends and family.

A note about the Hedge API:

There are two major calls I use in my scripts “setDestination” and “setPreferences”

The “setDestination” call looks like this:

open ‘hedge://actions?json=[{“setDestination”:{“path”:”/Volumes/LaCie/Testing/Test1″}},{“token”:”1234567890123345555″}]’

Note: the token is generated for you when you have a Pro license.

The “the setPreferences” call uses plist keys.

Note: I’ll have more say about using the actual Hedge API after it is officially announced.

To install macOS Mojave, or not to?

InstallMojave

Just the other day macOS Mojave was released and now the armies of Macs armed only with the AppStore are silently downloading the installer and ready to upgrade. You can’t hurry too fast to be on the bleeding edge, hurry faster!

Just in case you don’t want everyone to install macOS 10.14.0 (dot zero!) in the first week of its release here’s a way to slow down the upgrade hordes using Erik Berglund’s AppBlocker script. Erik Berglund is also the author of ProfileCreator (for creating profiles) and the author of many other great scripts.

Note: for true binary whitelisting check out Google’s Santa project and Upvote (and Moroz and Zentral, two other Santa sync servers).

Step 1. Get it

Clone or download the AppBlocker project from GitHub

AppleBlockerProject.png

Step 2. Do it

Edit the AppBlocker.py script with the Bundle Identifier of your app to block, in this case for the Mojave installer from the AppStore it is:

com.apple.InstallAssistant.Mojave

You can also edit the alert message, and the icon that is shown, as well as decide if the blocked app should be deleted or not. The script is easy to edit in BBEdit, or nano (in Terminal). Use whatever your favorite text editor is to make the necessary changes.

# List of all blocked bundle identifiers. Can use regexes.
blockedBundleIdentifiers = ['com.apple.InstallAssistant.Mojave']

# Whether the blocked application should be deleted if launched
deleteBlockedApplication = False

# Whether the user should be alerted that the launched applicaion was blocked
alertUser = True

# Message displayed to the user when application is blocked
alertMessage = "The application \"{appname}\" has been blocked by IT"
alertInformativeText = "Contact your administrator for more information"

# Use a custom Icon for the alert. If none is defined here, the Python rocketship will be shown.
alertIconPath = "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/Actions.icns"

UPDATED NOTE:

To determine the Bundle identifier of other applications you can use osascript

osascript -e 'id of app "iTunes"'
com.apple.iTunes

If you want to block more than one app use a comma separated list in the AppBlocker.py script:

['com.apple.InstallAssistant.Mojave','com.apple.iTunes']

 

Step 3. Run it

Put the script where you want to run it. The default location as defined in the launchd plist included with the app is “/usr/local/bin”. Put the launchd.plist in “/Library/LaunchDaemons/” and start up your launchd to block your apps!

launchctl load /Library/LaunchDaemons/com.github.erikberglund.AppBlocker.plist

Step 4. Automate it

For bonus points we automate! Bundle it all up in a package with munkipkg, then distribute it with Munki to all your clients.

Using munkipkg is easy. Create the folder using munkipkg

./munkipkg --create AppBlocker

munkipkg: Created new package project at AppBlocker

Then you fill the payload folders with those items you downloaded from the AppBlocker project. LauchD plist in the LaunchDaemons folder and AppBlocker.py in the “usr local bin” (create each nested folder).

AppBlocker-Munkipkg3.png

And finally create a post install script (no “.sh”) with the launchctl action to start your plist.

AppBlocker-Munkipkg4.png

Last but not least add this package to your Munki repo as an unattended managed install  that everyone gets. Of course, only do this after testing your package locally somewhere to verify that it works properly. Remember the saying: “You may not test very often, but when you do it’s always in production.” Be very careful with your testing but always automate all the things.

Updated after the initial blog post to explain how to add more than one app to block, and how to use osascript to determine the bundle identifier.

 

 

 

Be a NoMAD!

 

NoMAD stands for “no more AD” and has nothing to do with a nomadic lifestyle, nomads, ronin or other wandering IT professionals. Sorry.

NoMAD allows you to stop binding Macs to a corporate domain and instead get your kerberos tickets as needed. Connect to those file shares, change your password, and other fun tasks, without being stuck on the domain and constantly resetting your keychain from the insanity of password retention policies.

NoMAD-intro

Using Autopkg and Autopkgr to feed trusted apps into your Munki repo you can easily deploy NoMAD to your fleet of Macs.

And for bonus points you can add your preference settings as “updates for” NoMAD in Munki. One such add on is a setting for an auto mounting sharepoint.

Name your file: “menu.nomad.shares.plist” and open up your favourite text editor.

<?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”&gt;
<plist version=”1.0″>
<dict>
<key>Shares</key>
<array>
<dict>
<key>AutoMount</key>
<true/>
<key>ConnectedOnly</key>
<true/>
<key>Groups</key>
<array/>
<key>LocalMount</key>
<string></string>
<key>Name</key>
<string>Corp_Share</string>
<key>Options</key>
<array/>
<key>URL</key>
<string>smb://winserver5000/Corp_Share</string>
</dict>
</array>
<key>Version</key>
<string>1</string>
</dict>
</plist>

Create a package with munkipkg and add this to Munki. Set the package as an update for Munki and as your NoMAD agent gets installed your updates for NoMAD go with it.

More tips and tricks in the future.

 

Hello macOS Sierra, bye bye El Cap

We welcome the beautiful and wonderful macOS Sierra (10.12) and say good bye to the old and weary El Capitan (OS X 10.11.6)…. Wait, not so fast. Slow it down. Just a tad bit.

While Watchman is alerting me to users downloading, then installing the newest Apple macOS (née OS X, Mac OS X), we must be ready. Ready to troubleshoot issues with apps that developers haven’t tested thoroughly for a new OS that appears to be the same, but changes everything under the hood.

How do we test? In a VM of course.

What do we need:

  1. VMWare Fusion
  2. Greg et. al. createOSXinstallPkg
  3. Rich Trouton’s disable setup assistant payload free packages
  4. Mager Valp’s Create User Pkg
  5. Greg et. al. Munki (latest release)
  6. add your own packages, such as a munki kicksart (set repo url, client identifier, etc)
  7. UPDATE: we can’t forget Rich Trouton’s First Boot Generator App

What are we doing?

createOSXinstallPkg was created to turn Apple’s App Store Install macOS Sierra.app or previous Install OS X versions into nice Apple installer packages to upgrade in place using Munki (or other deployment tools). The new trick added recently is to create a new Fake Install.app with our packages to use install in VMWare Fusion instead of on a real Mac.

UPDATED STEPS! Note: I’d forgotten about First Boot Generator

  1. Download your installer app of choice (Install macOS sierra)
  2. Download createOSX installer
  3. Prepare your custom packages, or gathers ones your want to add to the installer
  4. Organize your installers into folders like this: 00, 01, 02, etc
  5. Launch First Boot Generator App and transmogrify that folders of packages
  6. Run createOSX installer with the fake app option if you want to test a VM, or without if you want to build a package
  7. Run createOSX as many times as you want with different OS X installers, and the same first boot package. Test diff OS installers with your customer PKGs.

Note: use the “–make-fake-app” option to prep for VMWare Fusion, omit it for a pkg

Note2: Here’s some examples using createOSXinstallPkg and various OSX installers

createOSXinstallPkg sudo ./createOSXinstallPkg --source /Volumes/SSD/Install\ macOS\ Sierra.app --make-fake-app --pkg ~/bin/PKG_BUILD/FirstBoot_staging/First\ Boot\ Package\ Install.pkg --output /Volumes/Updates/Builds

createOSXinstallPkg sudo ./createOSXinstallPkg --source /Volumes/Updates/Builds/Install\ OS\ X\ El\ Capitan.app --pkg ~/bin/PKG_BUILD/FirstBoot_staging/First\ Boot\ Package\ Install.pkg --output /Volumes/Updates/Builds

 

firstbootgeneratorapp

firstbootpackages

Note: If you get a message that your custom pkg you want to add is not a Flat package then use productbuild to repackage it.

Example:

➜  productbuild –package SetMunkiRepo.pkg SetMunkiRepo_flat.pkg

 

Reference: See Greg’s post on Managing OS X for more info make VMWare images using this method. And also Rich Trouton’s Der Flounder blog post on First Book Generator App

 

 

Camera Archives

For editing clients with a proper SAN this is the setup I like to use a watch folder on the SAN that sends to tape the camera archives automatically on a timed interval.

This requires

  1. proper SAN
  2. a watch folder setup with Archiware P5 archive
  3. camera archives, created in FCP X from the camera cards

Note: you can also use Adobe Prelude, Shotput or Resolve to create verified copies of camera cards. Use what you trust and works for you. The idea is not to copy by hand and avoid the perils of corrupt files.

Bonus: multiple drives to enable multi-streaming and parallelizing of your data. Why not makes cloned tapes copies and stream lots of data to all four (yes, four !) drives. See the illustration below.

 

 

Screen Shot 2016-08-03 at 10.35.40 AM

MacDevOps Manifesto

I was explaining Munki (and autopkg) to some colleagues when I hit on the idea of the MacDevOps manifesto.

Munki and friends (apps used to augment and extend Munki) are helpful automation tools. Setting up automation systems take time and must be maintained and grown but they pay big dividends.  Freeing us to do Dev work or other tasks they automate and iterate and repeat and build our systems in the way we want.

No more 100 machines built in a hundred different ways (unless we want to). But now we can check at a glance in MunkiReport to verify that indeed the latest Adobe Flash patch is installed. That may make our lives better. Especially if we need to satisfy corporate IT or our bosses that we are up to date and patched as required.

The MacDevOps Manifesto Part 1: Munki and friends

Munki is at its core free software created by Greg Neagle at Disney Animation and used worldwide in many different ways but essentially to distribute apps and run scripts on client workstations. There are many ways to customize it and if fits many different workflows. The MacDevOps:YVR conference I ran last June turned out to be a Munki love-in and showed me the many awesome and varied ways organizations are using it.

With AutoPkg, another free Mac open source project, Munki can get the latest updates to any software that it has recipes for and by extension install them on clients immediately. This fits the workflow of having Flash, Java and web browsers (Chrome or FireFox) updated as soon as possible for security patches. Exploits on the Mac are coming from these entry points and if you need to use these apps or plugins then having the latest versions helps. For this feature alone I use Munki. In a few months you will see that Munki with AutoPkg has downloaded dozens of versions of each app and keeping up with this takes time away from other tasks. Automation of simple tasks frees up our time so we can focus on other things. That is MacDevOps.

I also use Munki for installation of any app that is needed everywhere. If I have to download or install one app for one client workstation I put it in Munki and it is ready for installation anywhere with a simple click by the user in a self service portal or automatically by choosing managed installs. Of course if there is an app you don’t want installed (flash or Skype or messenger, etc) add it to Munki and mark it as managed uninstall. Done.

Scripts and files and config Profiles (replacement for mcx, managed preference settings for OS X) can be imported and used to configure workstations to make deployment easy and flexible. Put everything in Munki and then you don’t have to use golden master builds anymore. Buy a new Mac and install the Munki client. Done.

Add to this Munki Report which gives an excellent dashboard for what is installed and a total inventory of your client Macs. Very useful info which will let you know if you 15 different versions of flash or Photoshop or any app you choose to look for.

Last but least I always install Watchman Monitoring which reports to a secure cloud (web portal) to automatically monitor for bad drives, Ram, backups not running etc. It’s a great 50ft overview of all your installs and it can alert you immediately when a machine is having issues that you need to deal with (drives 90% full or Xsan volume not mounted, etc).

I find this combination of Munki and Watchman great for helping me manage my clients and I want to share these ideas about MacDevOps inspired ways of automating systems with everyone. Jump in and get involved with all these projects. You’ll be writing recipes for AutoPkg and sharing cool Munki tips and tricks with all your friends. And maybe like me you will start writing plugins for Watchman to monitor your favourite apps (I’m working on Archiware P5 backup and archive monitoring scripts).

Good luck to everyone and hope to see you at the next MacDevOps:YVR conference in June 2016. If you can’t make it go to your nearest Mac Dev / IT conference or start your own meet up somewhere local.

Munki tricks: Import Adobe CC apps

In our ongoing quest to use Munki to manage all software, one eventually gets to the realization that Adobe software must be distributed as well. How we do this?

With Adobe CC Team you can use the excellent CCP (creative cloud packaging) tool to make packages with the settings you want (users can or can’t update, importantly).

Once you have all these packages what do you do? Grab Tim Sutton’s “munkiimport_cc_installers.py” script and scan your folder with all your newly created package and you’re on your way.

https://github.com/timsutton/aamporter/blob/master/scripts/munkiimport_cc_installers.py

Example:

$ sudo ./munkiimport_cc_installers.py /tmp/CC/ –subdirectory “apps/Adobe/CC/2014” –developer “Adobe” –category “Media”
Password:
Making disk image containing AE-CC2014_Install.pkg…
created: /tmp/munki-3aetVZ/AE-CC2014_Install.dmg
Disk image created at: /tmp/munki-3aetVZ/AE-CC2014_Install.dmg
Making disk image containing AE-CC2014_Uninstall.pkg…
created: /tmp/munki-3aetVZ/AE-CC2014_Uninstall.dmg
Disk image created at: /tmp/munki-3aetVZ/AE-CC2014_Uninstall.dmg
Copying AE-CC2014_Install.dmg to /Users/Shared/munki_repo/pkgs/apps/Adobe/CC/2014/AE-CC2014_Install-13.0.0.dmg…
Copying AE-CC2014_Uninstall.dmg to /Users/Shared/munki_repo/pkgs/apps/Adobe/CC/2014/AE-CC2014_Uninstall-13.0.0.dmg…
Saving pkginfo to /Users/Shared/munki_repo/pkgsinfo/apps/Adobe/CC/2014/AE-CC2014-13.0.0…
Making disk image containing Pho-CC2014_Install.pkg…
created: /tmp/munki-a005sR/Pho-CC2014_Install.dmg
Disk image created at: /tmp/munki-a005sR/Pho-CC2014_Install.dmg
Making disk image containing Pho-CC2014_Uninstall.pkg…
created: /tmp/munki-a005sR/Pho-CC2014_Uninstall.dmg
Disk image created at: /tmp/munki-a005sR/Pho-CC2014_Uninstall.dmg
Copying Pho-CC2014_Install.dmg to /Users/Shared/munki_repo/pkgs/apps/Adobe/CC/2014/Pho-CC2014_Install-15.0.dmg…
Copying Pho-CC2014_Uninstall.dmg to /Users/Shared/munki_repo/pkgs/apps/Adobe/CC/2014/Pho-CC2014_Uninstall-15.0.dmg…
Saving pkginfo to /Users/Shared/munki_repo/pkgsinfo/apps/Adobe/CC/2014/Pho-CC2014-15.0…