From 94e682d25f046f13ebf5748ae2770c3125a1bfe1 Mon Sep 17 00:00:00 2001 From: mpanighetti Date: Mon, 16 Nov 2020 12:53:15 -0800 Subject: [PATCH 1/6] added macOS Big Sur support - added macOS Big Sur support - removed `%UPDATE_MECHANISM%` strings (mechanism will be consistent on all supported macOS versions in the near future) - updated wording in message strings - renamed plist attributes - removed legacy resource file and package receipt references - README formatting improvements - removed CHANGELOG (GitHub releases serve this function better) - iterated version --- CHANGELOG.md | 221 -------------------- README.md | 21 +- build-info.plist | 2 +- payload/Library/Scripts/Install or Defer.sh | 60 ++---- scripts/preinstall | 9 - 5 files changed, 32 insertions(+), 281 deletions(-) delete mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index bc63434..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,221 +0,0 @@ -# Install or Defer Change Log - -All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). - - -## [Unreleased] - TBD - -Nothing yet. - - -## [3.0.2] - 2020-07-06 - -### Changed - -- removed `CatalogURL` check from macOS 11+ (custom catalog URL definition is deprecated in Catalina and not supported in Big Sur) -- removed all Python calls to prepare for eventual Python runtime removal in future macOS releases - - replaced managed preferences read commands with `defaults read` pointed at the `/Library/Managed Preferences/` file path -- restored `StartInterval` attribute read - - added comment for context of purpose -- replaced `[ERROR]` with `❌ ERROR:` in script output -- added full binary paths (except for built-ins) -- double-quote-surrounded file paths and variables -- removed error code parsing to avoid ShellCheck flags -- removed `shellcheck disable` definitions -- updated ShellCheck job to use latest version of [azohra/shell-linter](https://github.com/azohra/shell-linter) -- separated optional content from required in README for improved legibility - - -## [3.0.1] - 2020-04-02 - -### Changed - -- removed unused `StartInterval` attribute read -- preinstall script only attempts to forget legacy package receipt if it is present on the system -- postinstall script sets LaunchDaemon ownership and permissions (in case files were modified prior to distribution and ownership/permissions were not properly set) #36 -- removed logger code from preinstall and postinstall scripts (install.log can be used for installer diagnostic purposes in these cases) -- changed postinstall script to POSIX Shell (Bash not necessary due to script simplicity) - - -## [3.0] - 2020-01-30 - -### Changed - -- transitioned bundle ID (and all associated file names and references) to `com.github.mpanighetti` -- renamed script to match project name -- preinstall script removes both legacy and current resource files via array - -### Removed - -- removed macOS Sierra support - - -## [2.3.4] - 2020-01-21 - -### Changed - -- `clean_up` function no longer unloads primary LaunchDaemon ahead of triggering system restart or shutdown #33 - - moved primary LaunchDaemon unload to `exit_without_updating` -- `clean_up` function moves all script resources to `/private/tmp/install-or-defer` - - -## [2.3.3] - 2019-10-15 - -### Added - -- added macOS Catalina support - - accounted for new `softwareupdate` syntax #32 - - added explicit 10.15 support in version compatibility check #25 -- removed legacy `launchctl` syntax - - -## [2.3.2] - 2019-09-23 - -### Added - -- Added explicit unload of helper LaunchDaemon (fixes an issue where the process persists if the enforced updates do not require a restart, e.g. Safari). - - -## [2.3.1] - 2019-07-23 - -### Added - -- Added `/usr/bin` to `$PATH` definitions (fixes an issue where third-party Python2 installs fail attempts to read system settings due to missing `Foundation` and `CoreFoundation` modules). - - -## [2.3.0] - 2019-07-16 - -### Added - -- if a custom software update URL is set, the script now checks that URL for reachability before proceeding - - -## [2.2.0.1] - 2019-07-15 - -### Changed - -- generalized `$MSG_ACT_OR_DEFER` to refer to "IT" rather than "ExampleCorp" to allow usage of the script or the packaged build without environment-specific modifications - - -## [2.2] - 2019-06-04 - -### Added - -- added option for custom `$MAX_DEFERRAL_TIME` and `$SKIP_DEFERRAL` settings defined by plist attributes, or if undefined, reverts to script default (allows for managing deferral periods via configuration profile rather than making the change in the script and repackaging) - -### Changed - -- standardized casing (`UpperCamelCase` for CFPreferences, `ALL_CAPS_WITH_UNDERSCORES` for variables) -- split README text in definition lists into multiple paragraphs - - -## [2.1.4] - 2019-05-14 - -### Changed - -- added cleanup tasks to preinstall script and `exit_without_updating` (ensures `AppleSoftwareUpdatesForcedAfter` attribute doesn't persist between script reinstalls) -- made `$BUNDLE_ID` LaunchDaemon unload conditional on file existing (reduces error output) - - -## [2.1.3] - 2019-04-11 - -### Added - -- added `--no-scan` flag to `--download` and `--install` commands (avoids repeatedly checking for updates after initial `softwareupdate --list`, speeding up script runtime) - - -## [2.1.2] - 2019-04-10 - -### Added - -- added shutdown workflow for BridgeOS updates (detects string in `softwareupdate --install --all` output indicating a shutdown is required rather than a restart, changes restart function to shut down instead) #10 - - -## [2.1.1] - 2019-04-10 - -### Changed - -- moved update check after deferral period check (reduces amount of `softwareupdate` processes running in the background between deferral periods) -- switched to Software Update icon as default alert branding -- reworded some `echo` output -- consolidated dynamic substitution notes in README -- consistent indent spacing in script - - -## [2.1] - 2019-01-19 - -### Added - -- added example of a recommended update that doesn't require a restart to README - -### Changed - -- made system restart conditional on an update requiring it (and made the corresponding messaging variable based on restart requirement) - - if a restart is required, scripts runs `--all` updates and restarts on completion - - if a restart is not required, script only runs `--recommended` updates -- consolidated MESSAGING description -- renamed functions and variables to reflect new behaviors -- increased recommended minimum macOS to 10.12+ -- formatting changes for consistent spacing and labeling -- switched example smart groups in README to use regex for shorter queries (left old behavior in separate example for older versions of Jamf Pro) -- updated screenshots in README to reflect current script behavior - -### Removed - -- Removed support for OS X 10.11 or earlier - - -## [2.0] - 2019-01-10 - -### Added - -- added separate `$MSG_UPDATING` alert while updates are running in the background (deferred update during restart not working in 10.13+ #4) - - gives user option to manually run updates (dynamically describes method of manual updates depending on macOS version) -- added preflight `softwareupdate --list` (more accurate than reading from `/Library/Updates/index.plist`, with tradeoff of longer script runtime #3) before caching updates (script exits if `--list` returns no recommended results) -- added explicit macOS High Sierra and Mojave support in version checks - -### Changed - -- set `softwareupdate --download` to only grab `--recommended` updates (as per `README` and the intent of the script to only trigger for security updates requiring restart) -- renamed `trigger_updates_at_restart` to `check_for_updates`, moved recon/unload to dedicated `exit_without_updating` function -- moved updater mechanism to dedicated `run_updates` function -- renamed `clean_up_before_restart` function to `clean_up` (since it isn't always run as part of a restart action) -- changed App Store icon path (.png resource no longer exists in macOS 10.14, and jamfHelper natively supports .icns files) -- updated Casper references to Jamf Pro in `README` -- updated example security patches in `README` to more recent builds (matching naming convention from [Apple security updates](https://support.apple.com/en-us/HT201222)) - -### Removed - -- removed all `/Library/Updates` dependencies as that path is now under SIP in macOS 10.14+ - - -## [1.0.1] - 2017-07-24 - -### Changed - -- specifies full path to helper script #2 - - -## 1.0.0 - 2017-03-02 - -- Initial release - - -[Unreleased]: https://github.com/mpanighetti/install-or-defer/compare/v3.0.2...HEAD -[3.0.2]: https://github.com/mpanighetti/install-or-defer/compare/v3.0.1...v3.0.2 -[3.0.1]: https://github.com/mpanighetti/install-or-defer/compare/v3.0...v3.0.1 -[3.0]: https://github.com/mpanighetti/install-or-defer/compare/v2.3.4...v3.0 -[2.3.4]: https://github.com/mpanighetti/install-or-defer/compare/v2.3.3...v2.3.4 -[2.3.3]: https://github.com/mpanighetti/install-or-defer/compare/v2.3.2...v2.3.3 -[2.3.2]: https://github.com/mpanighetti/install-or-defer/compare/v2.3.1...v2.3.2 -[2.3.1]: https://github.com/mpanighetti/install-or-defer/compare/v2.3.0...v2.3.1 -[2.3.0]: https://github.com/mpanighetti/install-or-defer/compare/v2.2.0.1...v2.3.0 -[2.2.0.1]: https://github.com/mpanighetti/install-or-defer/compare/v2.2...v2.2.0.1 -[2.2]: https://github.com/mpanighetti/install-or-defer/compare/v2.1.4...v2.2 -[2.1.4]: https://github.com/mpanighetti/install-or-defer/compare/v2.1.3...v2.1.4 -[2.1.3]: https://github.com/mpanighetti/install-or-defer/compare/v2.1.2...v2.1.3 -[2.1.2]: https://github.com/mpanighetti/install-or-defer/compare/v2.1.1...v2.1.2 -[2.1.1]: https://github.com/mpanighetti/install-or-defer/compare/v2.1...v2.1.1 -[2.1]: https://github.com/mpanighetti/install-or-defer/compare/v2.0...v2.1 -[2.0]: https://github.com/mpanighetti/install-or-defer/compare/v1.0.1...v2.0 -[1.0.1]: https://github.com/mpanighetti/install-or-defer/compare/v1.0...v1.0.1 diff --git a/README.md b/README.md index cb6fb19..793d646 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This framework will enforce the installation of pending Apple security updates o ![Install or Defer prompt](img/install-or-defer-fullscreen.png) -This workflow is most useful for updates that require a restart and include important security-related patches (e.g. macOS Catalina 10.15.2), but also applies to critical security updates that don't require a restart (e.g. Safari 13.0.4). Basically, anything with the `Recommended: YES` and/or `Action: restart` label in the `softwareupdate` catalog is in scope. +This workflow is most useful for updates that require a restart and include important security-related patches (e.g. macOS Catalina 10.15.7 Supplemental), but also applies to critical security updates that don't require a restart (e.g. Safari 14.0.1). Basically, anything Software Update marks as "recommended" or requiring a restart is in scope. This framework is distributed in the form of a [munkipkg](https://github.com/munki/munki-pkg) project, which allows easy creation of a new installer package when changes are made to the script or to the LaunchDaemon that runs it (despite the name, packages generated with munkipkg don't require Munki; they work great with Jamf Pro). See the [Installer creation](#installer-creation) section below for specific steps on creating the installer for this framework. @@ -13,7 +13,7 @@ This framework is distributed in the form of a [munkipkg](https://github.com/mun Here's what needs to be in place in order to use this framework: -- The current version of this framework has been tested only on __macOS 10.13 through 10.15__, but older versions should continue to function normally for previous macOS builds (note, however, that those versions of macOS are no longer receiving regular security updates from Apple and thus may not benefit from this framework). +- The current version of this framework has been tested on __macOS High Sierra, Mojave, Catalina, and Big Sur__, but older versions should continue to function normally for previous macOS builds (note, however, that those versions of macOS are no longer receiving regular security updates from Apple and thus may not benefit from this framework). - Target Macs must be __enrolled in Jamf Pro__ and have the `jamfHelper` binary installed. ## Optional @@ -132,7 +132,6 @@ There are several settings in the script that can be customized by changing defa The above messages use the following dynamic substitutions: - `%DEFER_HOURS%` will be automatically replaced by the number of hours remaining in the deferral period. -- `%UPDATE_MECHANISM%` will be automatically replaced by either "App Store > Updates" or "System Preferences > Software Update" depending on the version of macOS. - The section in the `<>` will be removed if a restart is not required. - The section in the `{{double curly brackets}}` will be removed when this message is displayed for the final time before the deferral deadline. @@ -157,8 +156,8 @@ Download and install [munkipkg](https://github.com/munki/munki-pkg), if you have If you make changes to the script, we recommend changing the following three things: -- The Last Modified metadata in the script. -- The Version metadata in the script. +- The __Last Modified__ metadata in the script. +- The __Version__ metadata in the script. - The `version` key in the build-info.plist file (to match the script version). With munkipkg installed, this command will generate a new installer package in the build folder: @@ -266,13 +265,13 @@ Create a policy with the following criteria: You should see something similar to the following output (the numbers, which represent dates, will vary): ``` - AppleSoftwareUpdatesDeferredUntil = 1585884274; - AppleSoftwareUpdatesForcedAfter = 1586042469; + UpdatesDeferredUntil = 1585884274; + UpdatesForcedAfter = 1586042469; ``` 9. Enter the following commands to "skip ahead" to the next deferral and re-trigger the prompt: ``` - sudo defaults write /Library/Preferences/com.github.mpanighetti.install-or-defer AppleSoftwareUpdatesDeferredUntil -int $(date +%s) + sudo defaults write /Library/Preferences/com.github.mpanighetti.install-or-defer UpdatesDeferredUntil -int $(date +%s) sudo launchctl unload /Library/LaunchDaemons/com.github.mpanighetti.install-or-defer.plist sudo launchctl load /Library/LaunchDaemons/com.github.mpanighetti.install-or-defer.plist ``` @@ -289,7 +288,7 @@ Create a policy with the following criteria: Once the Testing steps above have been followed, there are only a few steps remaining to deploy the framework: -1. On the Jamf Pro web app, edit the __Install or Defer__ policy and click on the __Scope__ tab. +1. In the Jamf Pro web app, edit the __Install or Defer__ policy and click on the __Scope__ tab. 2. Remove the test Macs from the scope. 3. Add all the __Critical Update Needed__ smart groups into the scope. 4. Click __Save__. @@ -319,10 +318,10 @@ sudo chmod 644 /path/to/install-or-defer/payload/Library/LaunchDaemons/com.githu ## Miscellaneous Notes -- Feel free to change the `com.github.mpanighetti` style identifier to match your company instead. If you do this, make sure to update the filenames of the LaunchDaemons, their corresponding file paths in the preinstall and postinstall scripts, and the `$BUNDLE_ID` variable in the script. +- Feel free to change the `com.github.mpanighetti` bundle identifier to match your company instead. If you do this, make sure to update the filenames of the LaunchDaemons, their corresponding file paths in the preinstall and postinstall scripts, and the `$BUNDLE_ID` variable in the script. - You can specify a different default logo if you'd rather not use the Software Update icon (e.g. corporate branding). `jamfHelper` supports .icns and .png files. - If you encounter any issues or have questions, please open an issue on this GitHub repo. Enjoy! -1 This example frequency assumes you're using the default deferral period of 72 hours. If you've set a custom deferral period, it is recommended that your policy runs less frequently than the maximum deferral time, so that your Macs have the chance to defer, timeout, and apply the updates before the policy attempts to run again (since the preinstall script will reset `AppleSoftwareUpdatesDeferredUntil` and `AppleSoftwareUpdatesForcedAfter`). +1 This example frequency assumes you're using the default deferral period of 72 hours. If you've set a custom deferral period, it is recommended that your policy runs less frequently than the maximum deferral time, so that your Macs have the chance to defer, timeout, and apply the updates before the policy attempts to run again (since the preinstall script will reset `UpdatesDeferredUntil` and `UpdatesForcedAfter`). diff --git a/build-info.plist b/build-info.plist index d0b1eab..976f707 100644 --- a/build-info.plist +++ b/build-info.plist @@ -17,6 +17,6 @@ suppress_bundle_relocation version - 3.0.2 + 3.0.3 diff --git a/payload/Library/Scripts/Install or Defer.sh b/payload/Library/Scripts/Install or Defer.sh index 3ba5326..c1d377f 100755 --- a/payload/Library/Scripts/Install or Defer.sh +++ b/payload/Library/Scripts/Install or Defer.sh @@ -12,8 +12,8 @@ # the system restarts automatically. # Authors: Mario Panighetti and Elliot Jordan # Created: 2017-03-09 -# Last Modified: 2020-07-06 -# Version: 3.0.2 +# Last Modified: 2020-11-16 +# Version: 3.0.3 # ### @@ -44,31 +44,25 @@ SCRIPT_PATH="/Library/Scripts/Install or Defer.sh" # remaining in the deferral period. # - The section in the {{double curly brackets}} will be removed when this # message is displayed for the final time before the deferral deadline. -# - The sections in the <> will be removed if a restart -# is not required for the pending updates. -# - %UPDATE_MECHANISM% will be automatically replaced depending on macOS -# version: -# - macOS 10.13 or lower: "App Store - Updates" -# - macOS 10.14+: "System Preferences - Software Update" +# - The sections in the <> will be removed if a +# restart is not required for the pending updates. # The message users will receive when updates are available, shown above the # "Run Updates" and "Defer" buttons. MSG_ACT_OR_DEFER_HEADING="Critical updates are available" -MSG_ACT_OR_DEFER="Apple has released critical security updates, and your IT department would like you to install them as soon as possible. Please save your work, quit all applications, and click Run Updates. +MSG_ACT_OR_DEFER="Your Mac needs to run critical security updates<< which require a restart>>. Please save your work, quit all applications, and click Run Updates. -{{If now is not a good time, you may defer this message until later. }}Updates will install automatically after %DEFER_HOURS% hours<<, forcing your Mac to restart in the process>>. Note: This may result in losing unsaved work. +{{If now is not a good time, you may defer this message until later. }}Updates will install automatically after %DEFER_HOURS% hours<<, forcing your Mac to restart in the process>>. -If you'd like to manually install the updates yourself, open %UPDATE_MECHANISM% and apply all system and security updates<<, then restart when prompted>>. - -If you have any questions, please call or email the IT help desk." +If you have any questions, please contact IT." # The message users will receive after the deferral deadline has been reached. MSG_ACT_HEADING="Please run updates now" -MSG_ACT="Please save your work, then open %UPDATE_MECHANISM% and apply all system and security updates<<, then restart when prompted>>. If no action is taken, updates will be installed automatically<<, and your Mac will restart>>." +MSG_ACT="Please save your work, then run all available macOS security updates<< (restart your Mac when prompted)>>. If no action is taken, updates will be installed automatically." # The message users will receive while updates are running in the background. MSG_UPDATING_HEADING="Running updates" -MSG_UPDATING="Running system updates in the background.<< Your Mac will restart automatically when this is finished.>> You can force this to complete sooner by opening %UPDATE_MECHANISM% and applying all system and security updates." +MSG_UPDATING="Running macOS security updates in the background.<< Your Mac will restart automatically when this is finished.>>" #################################### TIMING ################################### @@ -303,7 +297,7 @@ exit_without_updating () { # Copy all output to the system log for diagnostic purposes. exec 1> >(/usr/bin/logger -s -t "$(/usr/bin/basename "$0")") 2>&1 -echo "Starting $(/usr/bin/basename "$0") script. Performing validation and error checking..." +echo "Starting $(/usr/bin/basename "$0"). Performing validation and error checking..." # Define custom $PATH. PATH="/usr/sbin:/usr/bin:/usr/local/bin:$PATH" @@ -333,32 +327,20 @@ fi OS_MAJOR=$(/usr/bin/sw_vers -productVersion | /usr/bin/awk -F . '{print $1}') OS_MINOR=$(/usr/bin/sw_vers -productVersion | /usr/bin/awk -F . '{print $2}') -# If the macOS version is not 10.13 through 10.15, this script may not work. +# This script has currently been tested in macOS 10.13+ and macOS 11, +# and will exit with error for any other macOS versions. # When new versions of macOS are released, this logic should be updated after # the script has been tested successfully. -if [[ "$OS_MAJOR" -eq 10 && "$OS_MINOR" -lt 13 ]] || [[ "$OS_MAJOR" -lt 10 ]]; then - echo "❌ ERROR: This script requires at least macOS 10.13. This Mac has $OS_MAJOR.$OS_MINOR." - BAILOUT=true -elif [[ "$OS_MAJOR" -gt 10 ]] || [[ "$OS_MINOR" -gt 15 ]]; then - echo "❌ ERROR: This script has been tested through macOS 10.15 only. This Mac has $OS_MAJOR.$OS_MINOR." +if [[ "$OS_MAJOR" -lt 10 ]] || [[ "$OS_MAJOR" -eq 10 && "$OS_MINOR" -lt 13 ]] || [[ "$OS_MAJOR" -gt 11 ]]; then + echo "❌ ERROR: This script supports macOS 10.13+ and macOS 11, but this Mac is running macOS ${OS_MAJOR}.${OS_MINOR}, unable to proceed." BAILOUT=true -else - if [[ "$OS_MINOR" -lt 14 ]]; then - MSG_ACT_OR_DEFER="${MSG_ACT_OR_DEFER//%UPDATE_MECHANISM%/App Store - Updates}" - MSG_ACT="${MSG_ACT//%UPDATE_MECHANISM%/App Store - Updates}" - MSG_UPDATING="${MSG_UPDATING//%UPDATE_MECHANISM%/App Store - Updates}" - else - MSG_ACT_OR_DEFER="${MSG_ACT_OR_DEFER//%UPDATE_MECHANISM%/System Preferences - Software Update}" - MSG_ACT="${MSG_ACT//%UPDATE_MECHANISM%/System Preferences - Software Update}" - MSG_UPDATING="${MSG_UPDATING//%UPDATE_MECHANISM%/System Preferences - Software Update}" - fi fi # We need to be connected to the internet in order to download updates. if /sbin/ping -q -c 1 208.67.222.222; then # Check if a custom CatalogURL is set and if it is available # (deprecated in macOS 11+). - if [[ "$OS_MAJOR" -eq 10 && "$OS_MINOR" -lt 16 ]]; then + if [[ "$OS_MAJOR" -lt 11 ]]; then SU_CATALOG=$(/usr/bin/defaults read "/Library/Managed Preferences/com.apple.SoftwareUpdate" CatalogURL 2>"/dev/null") if [[ "$SU_CATALOG" != "None" ]]; then if /usr/bin/curl --user-agent "Darwin/$(/usr/bin/uname -r)" -s --head "$SU_CATALOG" | /usr/bin/grep "200 OK" >"/dev/null"; then @@ -421,10 +403,10 @@ fi echo "Maximum deferral time: $(convert_seconds "$MAX_DEFERRAL_TIME")" # Perform first run tasks, including calculating deadline. -FORCE_DATE=$(/usr/bin/defaults read "$PLIST" AppleSoftwareUpdatesForcedAfter 2>"/dev/null") +FORCE_DATE=$(/usr/bin/defaults read "$PLIST" UpdatesForcedAfter 2>"/dev/null") if [[ -z $FORCE_DATE || $FORCE_DATE -gt $(( $(/bin/date +%s) + MAX_DEFERRAL_TIME )) ]]; then FORCE_DATE=$(( $(/bin/date +%s) + MAX_DEFERRAL_TIME )) - /usr/bin/defaults write "$PLIST" AppleSoftwareUpdatesForcedAfter -int $FORCE_DATE + /usr/bin/defaults write "$PLIST" UpdatesForcedAfter -int $FORCE_DATE fi # Calculate how much time remains until deferral deadline. @@ -433,7 +415,7 @@ echo "Deferral deadline: $(/bin/date -jf "%s" "+%Y-%m-%d %H:%M:%S" "$FORCE_DATE" echo "Time remaining: $(convert_seconds $DEFER_TIME_LEFT)" # Get the "deferred until" timestamp, if one exists. -DEFERRED_UNTIL=$(/usr/bin/defaults read "$PLIST" AppleSoftwareUpdatesDeferredUntil 2>"/dev/null") +DEFERRED_UNTIL=$(/usr/bin/defaults read "$PLIST" UpdatesDeferredUntil 2>"/dev/null") if [[ -n "$DEFERRED_UNTIL" ]] && (( DEFERRED_UNTIL > $(/bin/date +%s) && FORCE_DATE > DEFERRED_UNTIL )); then # If the policy ran recently and was deferred, we need to respect that # "defer until" timestamp, as long as it is earlier than the deferral @@ -501,7 +483,7 @@ if (( DEFER_TIME_LEFT > 0 )); then exit 1 elif [[ -n $PROMPT && $DEFER_TIME_LEFT -gt 0 && $PROMPT -eq 0 ]]; then echo "User clicked Run Updates $PROMPT_ELAPSED_STR." - /usr/bin/defaults delete "$PLIST" AppleSoftwareUpdatesDeferredUntil 2>"/dev/null" + /usr/bin/defaults delete "$PLIST" UpdatesDeferredUntil 2>"/dev/null" run_updates elif [[ -n $PROMPT && $DEFER_TIME_LEFT -gt 0 && $PROMPT -eq 1 ]]; then # Kill the jamfHelper prompt. @@ -511,12 +493,12 @@ if (( DEFER_TIME_LEFT > 0 )); then elif [[ -n $PROMPT && $DEFER_TIME_LEFT -gt 0 && $PROMPT -eq 2 ]]; then echo "User clicked Defer $PROMPT_ELAPSED_STR." NEXT_PROMPT=$(( $(/bin/date +%s) + EACH_DEFER )) - /usr/bin/defaults write "$PLIST" AppleSoftwareUpdatesDeferredUntil -int "$NEXT_PROMPT" + /usr/bin/defaults write "$PLIST" UpdatesDeferredUntil -int "$NEXT_PROMPT" echo "Next prompt will appear after $(/bin/date -jf "%s" "+%Y-%m-%d %H:%M:%S" "$NEXT_PROMPT")." elif [[ -n $PROMPT && $DEFER_TIME_LEFT -gt 0 && $PROMPT -eq 239 ]]; then echo "User deferred by exiting jamfHelper $PROMPT_ELAPSED_STR." NEXT_PROMPT=$(( $(/bin/date +%s) + EACH_DEFER )) - /usr/bin/defaults write "$PLIST" AppleSoftwareUpdatesDeferredUntil -int "$NEXT_PROMPT" + /usr/bin/defaults write "$PLIST" UpdatesDeferredUntil -int "$NEXT_PROMPT" echo "Next prompt will appear after $(/bin/date -jf "%s" "+%Y-%m-%d %H:%M:%S" "$NEXT_PROMPT")." elif [[ -n $PROMPT && $DEFER_TIME_LEFT -gt 0 && $PROMPT -gt 2 ]]; then # Kill the jamfHelper prompt. diff --git a/scripts/preinstall b/scripts/preinstall index d8c600c..9d4c39c 100755 --- a/scripts/preinstall +++ b/scripts/preinstall @@ -1,13 +1,9 @@ #!/bin/bash RESOURCE_FILES=( - "$3/Library/LaunchDaemons/com.elliotjordan.install_or_defer.plist" "$3/Library/LaunchDaemons/com.github.mpanighetti.install-or-defer.plist" - "$3/Library/Preferences/com.elliotjordan.install_or_defer.plist" "$3/Library/Preferences/com.github.mpanighetti.install-or-defer.plist" - "$3/Library/Scripts/install_or_defer.sh" "$3/Library/Scripts/Install or Defer.sh" - "$3/Library/Scripts/install_or_defer_helper.sh" "$3/Library/Scripts/Install or Defer_helper.sh" "$3/private/tmp/install-or-defer" ) @@ -16,11 +12,6 @@ RESOURCE_FILES=( echo "Killing any active jamfHelper notifications..." /usr/bin/killall jamfHelper 2>"/dev/null" -# Clear out legacy package receipt (if present). -if [[ $(/usr/sbin/pkgutil --pkgs) == *"com.elliotjordan.install_or_defer"* ]]; then - /usr/sbin/pkgutil --forget "com.elliotjordan.install_or_defer" -fi - # Remove all script resources (if already present on the system). echo "Removing existing script resources..." for TARGET_FILE in "${RESOURCE_FILES[@]}"; do From 367e5083549a37f08f2deecfc44e23798db40de4 Mon Sep 17 00:00:00 2001 From: mpanighetti Date: Tue, 17 Nov 2020 11:45:51 -0800 Subject: [PATCH 2/6] removed Apple Silicon support - removed Apple Silicon support pending testing (need to eventually update script to support changes in the `softwareupdate` workflow) --- payload/Library/Scripts/Install or Defer.sh | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/payload/Library/Scripts/Install or Defer.sh b/payload/Library/Scripts/Install or Defer.sh index c1d377f..ac09cd5 100755 --- a/payload/Library/Scripts/Install or Defer.sh +++ b/payload/Library/Scripts/Install or Defer.sh @@ -12,7 +12,7 @@ # the system restarts automatically. # Authors: Mario Panighetti and Elliot Jordan # Created: 2017-03-09 -# Last Modified: 2020-11-16 +# Last Modified: 2020-11-17 # Version: 3.0.3 # ### @@ -336,6 +336,18 @@ if [[ "$OS_MAJOR" -lt 10 ]] || [[ "$OS_MAJOR" -eq 10 && "$OS_MINOR" -lt 13 ]] || BAILOUT=true fi +# Determine platform architecture. +PLATFORM_ARCH=$(/usr/bin/arch) + +# This script has currently been tested on Intel Macs, and will exit with error +# when run on Apple Silicon Macs. +# This logic should be updated after the script has been tested and updated for +# Apple Silicon Mac compatibility. +if [[ "$PLATFORM_ARCH" = "arm64" ]]; then + echo "❌ ERROR: This script has not been tested on Apple Silicon Macs, unable to proceed." + BAILOUT=true +fi + # We need to be connected to the internet in order to download updates. if /sbin/ping -q -c 1 208.67.222.222; then # Check if a custom CatalogURL is set and if it is available From ea39d404a5ff7ae0c207f1e85001cca45e97a47a Mon Sep 17 00:00:00 2001 From: Mario Panighetti Date: Tue, 1 Dec 2020 11:33:51 -0800 Subject: [PATCH 3/6] added note on Apple Silicon support to README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 793d646..b0cd966 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ This framework is distributed in the form of a [munkipkg](https://github.com/mun Here's what needs to be in place in order to use this framework: - The current version of this framework has been tested on __macOS High Sierra, Mojave, Catalina, and Big Sur__, but older versions should continue to function normally for previous macOS builds (note, however, that those versions of macOS are no longer receiving regular security updates from Apple and thus may not benefit from this framework). +- This framework has only been tested on __Intel Macs__, and currently exits if run on Apple Silicon Macs. `softwareupdate` binary behavior has changed on Apple Silicon and further testing on native hardware is required before we can update the script for compatibility. Stay tuned! - Target Macs must be __enrolled in Jamf Pro__ and have the `jamfHelper` binary installed. ## Optional From 8f684a27412b0d2bc2f4854f18772ba23c6ac02f Mon Sep 17 00:00:00 2001 From: Mario Panighetti Date: Mon, 7 Dec 2020 11:54:08 -0800 Subject: [PATCH 4/6] added README reference to Apple Silicon compatibility issue --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b0cd966..4578b6d 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ This framework is distributed in the form of a [munkipkg](https://github.com/mun Here's what needs to be in place in order to use this framework: - The current version of this framework has been tested on __macOS High Sierra, Mojave, Catalina, and Big Sur__, but older versions should continue to function normally for previous macOS builds (note, however, that those versions of macOS are no longer receiving regular security updates from Apple and thus may not benefit from this framework). -- This framework has only been tested on __Intel Macs__, and currently exits if run on Apple Silicon Macs. `softwareupdate` binary behavior has changed on Apple Silicon and further testing on native hardware is required before we can update the script for compatibility. Stay tuned! +- This framework has only been tested on __Intel Macs__, and currently exits with no update enforcement action if run on Apple Silicon Macs. `softwareupdate` binary behavior has changed on Apple Silicon and further testing on native hardware is required before we can update the script for compatibility. Stay tuned! #45 - Target Macs must be __enrolled in Jamf Pro__ and have the `jamfHelper` binary installed. ## Optional From 841070c7e65e9addaeba13e263753d0ee158e89c Mon Sep 17 00:00:00 2001 From: Mario Panighetti Date: Mon, 7 Dec 2020 12:13:58 -0800 Subject: [PATCH 5/6] added restart flag for Big Sur - added `--restart` flag for macOS Big Sur #47 - iterated version to 4.0 as [plist key names constitute a non-backwards-compatible change](https://github.com/mpanighetti/install-or-defer/pull/44#discussion_r536535994) --- build-info.plist | 2 +- payload/Library/Scripts/Install or Defer.sh | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/build-info.plist b/build-info.plist index 976f707..28b39f6 100644 --- a/build-info.plist +++ b/build-info.plist @@ -17,6 +17,6 @@ suppress_bundle_relocation version - 3.0.3 + 4.0 diff --git a/payload/Library/Scripts/Install or Defer.sh b/payload/Library/Scripts/Install or Defer.sh index ac09cd5..76b5263 100755 --- a/payload/Library/Scripts/Install or Defer.sh +++ b/payload/Library/Scripts/Install or Defer.sh @@ -12,8 +12,8 @@ # the system restarts automatically. # Authors: Mario Panighetti and Elliot Jordan # Created: 2017-03-09 -# Last Modified: 2020-11-17 -# Version: 3.0.3 +# Last Modified: 2020-12-07 +# Version: 4.0 # ### @@ -114,6 +114,7 @@ check_for_updates () { # a restart. If no updates need to be installed, bail out. if [[ "$UPDATE_CHECK" =~ (Action: restart|\[restart\]) ]]; then INSTALL_WHICH="all" + RESTART_FLAG="--restart" # Remove "<<" and ">>" but leave the text between # (retains restart warnings). MSG_ACT_OR_DEFER="$(echo "$MSG_ACT_OR_DEFER" | /usr/bin/sed 's/[\<\<|\>\>]//g')" @@ -121,6 +122,7 @@ check_for_updates () { MSG_UPDATING="$(echo "$MSG_UPDATING" | /usr/bin/sed 's/[\<\<|\>\>]//g')" elif [[ "$UPDATE_CHECK" =~ (Recommended: YES|\[recommended\]) ]]; then INSTALL_WHICH="recommended" + RESTART_FLAG="" # Remove "<<" and ">>" including all the text between # (removes restart warnings). MSG_ACT_OR_DEFER="$(echo "$MSG_ACT_OR_DEFER" | /usr/bin/sed 's/\<\<.*\>\>//g')" @@ -193,7 +195,12 @@ run_updates () { # Run Apple system updates. echo "Running $INSTALL_WHICH Apple system updates..." - UPDATE_OUTPUT_CAPTURE="$(/usr/sbin/softwareupdate --install --$INSTALL_WHICH --no-scan 2>&1)" + # macOS Big Sur requires triggering the restart as part of the softwareupdate action, meaning the script will not be able to run its clean_up functions until the next time it is run. + if [[ "$OS_MAJOR" -gt 10 ]] && [[ "$INSTALL_WHICH" = "all" ]]; then + echo "System will restart as soon as the update is finished. Cleanup tasks will run on a subsequent update check." + fi + # shellcheck disable=SC2086 + UPDATE_OUTPUT_CAPTURE="$(/usr/sbin/softwareupdate --install --${INSTALL_WHICH} ${RESTART_FLAG} --no-scan 2>&1)" echo "Finished running Apple updates." # Trigger restart if script found an update which requires it. From f28c03fd38bfb27310a7945fd8159b9882cf352f Mon Sep 17 00:00:00 2001 From: Mario Panighetti Date: Mon, 7 Dec 2020 13:26:41 -0800 Subject: [PATCH 6/6] added issue hyperlink --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4578b6d..bb24460 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ This framework is distributed in the form of a [munkipkg](https://github.com/mun Here's what needs to be in place in order to use this framework: - The current version of this framework has been tested on __macOS High Sierra, Mojave, Catalina, and Big Sur__, but older versions should continue to function normally for previous macOS builds (note, however, that those versions of macOS are no longer receiving regular security updates from Apple and thus may not benefit from this framework). -- This framework has only been tested on __Intel Macs__, and currently exits with no update enforcement action if run on Apple Silicon Macs. `softwareupdate` binary behavior has changed on Apple Silicon and further testing on native hardware is required before we can update the script for compatibility. Stay tuned! #45 +- This framework has only been tested on __Intel Macs__, and currently exits with no update enforcement action if run on Apple Silicon Macs. `softwareupdate` binary behavior has changed on Apple Silicon and further testing on native hardware is required before we can update the script for compatibility. Stay tuned! [#45](https://github.com/mpanighetti/install-or-defer/issues/45) - Target Macs must be __enrolled in Jamf Pro__ and have the `jamfHelper` binary installed. ## Optional