Activating Geometer’s Sketchpad in macOS 10.13.6 (and beyond?)

In Licensing GSP Deployments by Terminal Command , I covered the officially sanctioned way to license GSP5 for Macs.

I believe that was still working even as of 10.13.5. It certainly was working in 10.12.

Unfortunately, with 10.13.6—unless you had an already activated GSP when you upgraded to 10.13.6 from 10.13.5 or earlier—you might get error messages like

usage: Sketchpad_Executable -license (register | deregister) -name LicenseName -code AuthorizationCode
in the terminal or like in the GUI, even if you're using an admin account.

So I opened a ticket with McGraw Hill, and they said:

The license for all users is stored in the "/Library/Application Support/The Geometer's Sketchpad/" so it must be a permissions issue with that folder, either creating it for a new install, or accessing it when deregistering an old install.

If you copy the "The Geometer's Sketchpad" folder for a non-admin user install (which would be found in "~/Application Support/The Geometer's Sketchpad", to the global /Library/Application Support/ folder, that should also work, provided that the folder permissions allow read/write.

Lo and behold, that was the the old non-sanctioned, unofficial way I used to license GSP5 on Macs.

Tested it out on 10.13.6. Works!

So, yeah, use the old way until McGraw Hill figures out what's going on.

Using ffmpeg to trim video

No real tutorial here, just a link to a great resource on this via Stack Overflow:
Cutting the videos based on start and end time using ffmpeg

Cutting with ffmpeg takes a lot less longer than rendering out via iMovie, and it results in a similarly sized output file instead of a giant one

P.S. My boss just showed me how you can do this in Quicktime with Edit > Trim. Much easier!

Waiting for FileVault encryption to finish to install macOS updates

If you notice you can't install new macOS updates on a Mac, it could be that it's still in the process of FileVault encrypting.

For example, here's a machine that's on macOS 10.13.4.

softwareupdate can't find any updates.

And even if you try to manually install the 10.13.6 combo update, you get macOS High Sierra 10.13.6 Update can't be installed on this disk. This volume does not meet the requirements for this update.

And, yup—lo and behold! The FileVault encryption is still in progress. Once that's done, the 10.13.6 update should install just fine.

Images not loading in Gmail canned responses

Do you use images in canned responses in Gmail? Did you notice your images suddenly showing up as blank boxes (both in the composition and in the actual sent message)?


Well, there's a fix for that. Use the new Gmail instead of the old Gmail:


Your images should now load (you do not need to re-create your old canned responses).

Integrating DetectX Swift with Munki

If you like DetectX Swift and want to integrate it with Munki, this is how I did it. Hat tip to Zack McCauley for doing the heavy lifting, which I'm now building on. I'd recommend you read his blog post first.

So instead of having an Outset script or separate Launch Agent, I decided to put the DetectX Swift scan as part of the Munki run (specifically a script in the preflight.d directory that MunkiReport creates):

#!/bin/bash

# Run a DetectX Swift scan
/Applications/Utilities/DetectX\ Swift.app/Contents/MacOS/DetectX\ Swift search -aj /usr/local/munki/preflight.d/cache/detectx.json

Outside of MunkiReport (but connecting to the MunkiReport MySQL database), I have a script that generates a Python list of files that DetectX Swift has flagged as "issues":

$query="SELECT issues FROM detectx WHERE numberofissues > 0";
$result=mysqli_query($YOURDATABASECONNECTION, $query);
if(mysqli_num_rows($result)>0){
   // Create an array to store the results
   $larger_issues=array();
   while($row=mysqli_fetch_assoc($result)){
      
      // Create an array based on a semi-colon delimiter
      $smaller_issues=explode(";", $row['issues']);
      foreach($smaller_issues AS $smaller_issue){
          if((trim($smaller_issue)!='') AND (!in_array($smaller_issue, $larger_issues))){
            array_push($larger_issues, $smaller_issue);
         }
      }

   // End fetching results
   }

   if(!empty($larger_issues)){
      echo '<p>okay_to_delete = [ ';
      $counter=0;
      while($counter+1<count($larger_issues)){
         echo '\'' . $larger_issues[$counter] . '\',<br />';   
         $counter+=1;
      }
      echo '\'' . $larger_issues[$counter] . '\' ]</p>';
      //print_r($larger_issues);
   
   // End checking there are elements in larger issues (there should be)
   }

// End checking there are any issues
}

And finally I have a nopkg to do the actual cleaning of the issues DetectX flagged.

So why even have an array of okay-to-delete things?

Well, DetectX Swift has command-line options to scan, but it (at least as of this writing) does not have the option to command-line remove things, presumably so someone has a chance to review the things removed before actually removing them. Also, since it's just forcefully removing things (yes, I know about using shutil to remove, but I've run into weird situations in which that doesn't work consistently, so I'm using a subprocess to invoke rm instead), it's probably a good idea for at least one human to review things before they get removed.

The nopkg also copies the .json to /var/log (with a datetime stamp in the name) before removing anything.

Use docklib to manage macOS docks

docklib instead of dockutil

I have a few posts about using dockutil to manage the macOS dock. dockutil is still a valid and working project, but I'm starting to migrate my scripts to docklib instead, which doesn't seem to require workarounds like this one.

Installing docklib

The installation instructions for docklib say you can put the docklib.py file in the same directory as the scripts that invoke it or you can put it "in your Python path." I'd recommend just grabbing the docklib .pkg from the releases page or using the AutoPkg docklib recipes to download it. The .pkg puts docklib.py in /Library/Python/2.7/site-packages/docklib.py.

Using docklib with Outset

docklib can be used in an Outset login-once or login-every script. There is no need to explicitly put in a delay to wait for the initial dock to appear before running your script. There is also no need, if you're specifying a dock (rather than modifying an existing one) to remove the default applications Apple puts on the dock. If you're specifying a dock, just say what you want to add. Use this suggested template:

import os
from docklib import Dock
tech_dock = [
   '/Applications/Google Chrome.app',
   '/Applications/App Store.app',
   '/Applications/Managed Software Center.app',
   '/Applications/System Preferences.app',
   '/Applications/Utilities/Activity Monitor.app',
   '/Applications/Utilities/Console.app',
   '/Applications/Utilities/Disk Utility.app',
   '/Applications/Utilities/Migration Assistant.app',
   '/Applications/Utilities/Terminal.app',
]
dock = Dock()
dock.items['persistent-apps'] = []
for item in tech_dock:
   if os.path.exists(item):
      item = dock.makeDockAppEntry(item)
      dock.items['persistent-apps'].append(item)
dock.save()

Checking if an item exists before removing/adding via docklib?

Here's an example of checking for something's existence on the right side of the dock before adding it. To check on the left side, it's a very similar process, except you just replace

section='persistent-others'
with
section='persistent-apps'

For example, this will add Microsoft Word only if it's not in the dock already:

from docklib import Dock
dock = Dock()
if dock.findExistingLabel('Microsoft Word', section='persistent-apps') == -1:
   item = dock.makeDockAppEntry('/Applications/Microsoft Word.app')
   dock.items['persistent-apps'].append(item)
   dock.save()

If you add an item using docklib that already exists in the dock, a second instance of it will be added to the dock, so you definitely should check for the existence of the item first.

However, if you want to remove an item, just use the standard removal procedure:

from docklib import Dock
dock = Dock()
dock.removeDockEntry('Microsoft Word')
dock.save()
If the item isn't in the dock when you try to remove it, docklib won't give any error or warning.

What I learned upgrading from MunkiReport 2 to MunkiReport 3

The setup for the old (version 2) MunkiReport was fairly simple. You essentially just downloaded the folder to your web server.

The setup for the new (version 3) MunkiReport has a bit more nuance to it. I had a lot of trouble setting it up, but thanks to some help from other Mac admins (special thanks to Rick Heil for getting me over the finish line), I was able to finally get it up and running.

Here are a few issues I ran into. Maybe if you're running into the same or similar issues, this list may help:

  • Ubuntu 16.04 doesn't have PHP 7.0.27 or higher, which the new version of MunkiReport requires, so I had to add it in with the appropriate PPA.
  • On a related note, once you add that PPA to your sources.list in Ubuntu, you get a whole ton of PHP versions available via apt: 7.0, 7.1, 7.2. It's best to make sure you have only version of PHP installed and remove all the rest. I'd recommend 7.2 at this point.
  • It's a good idea to start with the sqlite database just to eliminate MySQL connection issues as a possibility. That said, since the main MunkiReport 3 files don't live in the public-facing part of the web server, be especially mindful of this part of the wiki instructions: when using SQLite as backend (which is the default), check if the directory /app/db/ is writeable by the webserver.
  • If you're using AD or SAML authentication, move it up in the composer.json file from suggest to require and get rid of the description after the version number. For example, "adldap2/adldap2": "^8.0 Required for AD authentication" should change to "adldap2/adldap2": "^8.0" after being moved.
  • If you're running the composer command and get a [RuntimeException] The "--no-suggest" option does not exist. message, just ditch the --no-suggest part of the command.

Backing up database data from a Crypt server

This is really just a step-by-step version of what's available in the July 2015 update doc, which links to Django dumpdata and loaddata.

If you want back up your Crypt server database, this is how you can dump the data out:

docker ps
to find the name of your docker container, in case you forgot it? Let's just assume, for the next command, that the container's name is Crypt.
docker exec -it Crypt bash
This gets you to a bash prompt inside the Crypt docker container.
cd /home/docker/crypt/
Change to the docker crypt directory.
python manage.py dumpdata > db.json
Dump the data out into a .json file.
exit
Exit out of the docker container bash shell.
docker cp Crypt:/home/docker/crypt/db.json .
Copy the .json file to where you are outside the docker container.

If you want to get back into the docker container to delete the original .json (since there is no docker mv, only docker cp), you can do

docker exec -it Crypt bash
rm /home/docker/crypt/db.json
exit

P.S. Thanks to Graham Gilbert for the tip about not needing to chmod the manage.py file.

P.P.S. This data dump method will work regardless of whether you're using the built-in sqlite3 database or an external postgresql database.

Upgrading to High Sierra: “You may not install this volume because the computer is missing a firmware partition”

If you try to upgrade to High Sierra (macOS 10.13) and get You may not install this volume because the computer is missing a firmware partition when trying to select your drive to upgrade, it may be because you're upgrading on an OWC drive.

If you're using Munki, the error may appear in your /Library/Managed Installs/Logs/Install.log as Starting macOS install: FAILED: startosinstall failed with return code 243.

Previously, you'd have to physically swap back the OEM drive, and then put the OWC drive back again, but now OWC has its own firmware updater tool that fixes the problem:
Aura SSDs: Firmware Update (beta).

Parental Controls keeps blocking allowed apps

If macOS Parental Controls keep blocking allowed apps (both allowed through the checklist in System Preferences and through manually approving via password), deleting the account and recreating it may not be enough to fix the glitch. Instead, try recreating an account with a new name.

I've found Santa to block things more reliably (or not to block things you've allowed). You can block by certificate or (for Apple applications you'd need to do this), block by binary.