Skip to content

Commit

Permalink
Add the ability to use a custom icon and helper messages.
Browse files Browse the repository at this point in the history
  • Loading branch information
Graham authored and Graham committed Aug 13, 2019
1 parent fefaae8 commit 4614956
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 18 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
build/*
custom_icon/*
*.DS_Store
46 changes: 35 additions & 11 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ identifier="com.github.grahampugh.nice_updater"
# Default version of the build, you can leave this alone and specify as an argument like so: ./build.sh 1.7
version="1.0"

# The title of the message that is displayed when software updates are in progress and a user is logged in
updateRequiredTitle="macOS Software Updates Required"

# The message that is displayed when software updates are in progress and a user is logged in
updateRequiredMessage="Software updates are required to be installed on this Mac which require a restart. Please save your work and press Install Now to begin the installation.
The Mac will restart during installation is complete. Some macOS updates may require multiple restarts and/or the computer may shut down as part of the process."

# The title of the message that is displayed when software updates are in progress and a user is logged in
updateInProgressTitle="Software Update In Progress"

Expand Down Expand Up @@ -38,7 +46,7 @@ startInterval="86400"
mainDaemonPlist="/Library/LaunchDaemons/${identifier}.plist"
mainDaemonFileName="${mainDaemonPlist##*/}"
mainOnDemandDaemonPlist="/Library/LaunchDaemons/${identifier}_on_demand.plist"
onDemainDaemonFileName="${mainOnDemandDaemonPlist##*/}"
onDemandDaemonFileName="${mainOnDemandDaemonPlist##*/}"
onDemandDaemonIdentifier="${identifier}_on_demand"
watchPathsPlist="/Library/Preferences/${identifier}.trigger.plist"
preferenceFileFullPath="/Library/Preferences/${identifier}.prefs.plist"
Expand Down Expand Up @@ -81,17 +89,19 @@ defaults write "$PWD/$mainDaemonFileName" Label -string "$identifier"
defaults write "$PWD/$mainDaemonFileName" StartInterval -int "$startInterval"

# Create/modify the on_demand Daemon plist
[[ -e "$PWD/$onDemainDaemonFileName" ]] && /usr/libexec/PlistBuddy -c Clear "$PWD/$onDemainDaemonFileName" &> /dev/null
defaults write "$PWD/$onDemainDaemonFileName" Label -string "$onDemandDaemonIdentifier"
/usr/libexec/PlistBuddy -c "Add :ProgramArguments array" "$PWD/$onDemainDaemonFileName"
/usr/bin/plutil -insert ProgramArguments.0 -string "/bin/bash" "$PWD/$onDemainDaemonFileName"
/usr/bin/plutil -insert ProgramArguments.1 -string "/Library/Scripts/nice_updater.sh" "$PWD/$onDemainDaemonFileName"
/usr/bin/plutil -insert ProgramArguments.2 -string "on_demand" "$PWD/$onDemainDaemonFileName"
/usr/libexec/PlistBuddy -c "Add :WatchPaths array" "$PWD/$onDemainDaemonFileName"
/usr/bin/plutil -insert WatchPaths.0 -string "$watchPathsPlist" "$PWD/$onDemainDaemonFileName"
[[ -e "$PWD/$onDemandDaemonFileName" ]] && /usr/libexec/PlistBuddy -c Clear "$PWD/$onDemandDaemonFileName" &> /dev/null
defaults write "$PWD/$onDemandDaemonFileName" Label -string "$onDemandDaemonIdentifier"
/usr/libexec/PlistBuddy -c "Add :ProgramArguments array" "$PWD/$onDemandDaemonFileName"
/usr/bin/plutil -insert ProgramArguments.0 -string "/bin/bash" "$PWD/$onDemandDaemonFileName"
/usr/bin/plutil -insert ProgramArguments.1 -string "/Library/Scripts/nice_updater.sh" "$PWD/$onDemandDaemonFileName"
/usr/bin/plutil -insert ProgramArguments.2 -string "on_demand" "$PWD/$onDemandDaemonFileName"
/usr/libexec/PlistBuddy -c "Add :WatchPaths array" "$PWD/$onDemandDaemonFileName"
/usr/bin/plutil -insert WatchPaths.0 -string "$watchPathsPlist" "$PWD/$onDemandDaemonFileName"

# Create/modify the main preference file
[[ -e "$PWD/$preferenceFileName" ]] && /usr/libexec/PlistBuddy -c Clear "$PWD/$preferenceFileName" &> /dev/null
defaults write "$PWD/$preferenceFileName" UpdateRequiredTitle -string "$updateRequiredTitle"
defaults write "$PWD/$preferenceFileName" UpdateRequiredMessage -string "$updateRequiredMessage"
defaults write "$PWD/$preferenceFileName" UpdateInProgressTitle -string "$updateInProgressTitle"
defaults write "$PWD/$preferenceFileName" UpdateInProgressMessage -string "$updateInProgressMessage"
defaults write "$PWD/$preferenceFileName" LoginAfterUpdatesInProgressMessage -string "$loginAfterUpdatesInProgressMessage"
Expand All @@ -109,9 +119,19 @@ chmod +x /private/tmp/nice_updater/scripts/postinstall
# Put the main script in place
cp "$PWD/nice_updater.sh" /private/tmp/nice_updater/files/Library/Scripts/nice_updater.sh

# put a custom icon in place if present
if find $PWD/custom_icon -name *.png ; then
icon_path=/Library/Scripts/nice_updater_custom_icon.png
echo "Adding the icon to /private/tmp/nice_updater/files$icon_path"
cp -f "$PWD/custom_icon/"*.png /private/tmp/nice_updater/files$icon_path
defaults write "$PWD/$preferenceFileName" IconCustomPath -string "$icon_path"
else
echo "Nothing found at $PWD/custom_icon/*.png"
fi

# Copy the LaunchDaemon plists to the temp build directory
cp "$PWD/$mainDaemonFileName" "/private/tmp/nice_updater/files/Library/LaunchDaemons/"
cp "$PWD/$onDemainDaemonFileName" "/private/tmp/nice_updater/files/Library/LaunchDaemons/"
cp "$PWD/$onDemandDaemonFileName" "/private/tmp/nice_updater/files/Library/LaunchDaemons/"
cp "$PWD/$preferenceFileName" "/private/tmp/nice_updater/files/Library/Preferences/"

# Remove any unwanted .DS_Store files from the temp build directory
Expand Down Expand Up @@ -143,4 +163,8 @@ if [[ "$?" == "0" ]]; then
else
echo "Build failed."
fi
exit 0

# using plutil is fine but it converts the plists to binary which is not good for readability. Let's convert them back.
/usr/bin/plutil -convert xml1 "$PWD/$preferenceFileName"
/usr/bin/plutil -convert xml1 "$PWD/$mainDaemonFileName"
/usr/bin/plutil -convert xml1 "$PWD/$onDemandDaemonFileName"
10 changes: 9 additions & 1 deletion com.github.grahampugh.nice_updater.prefs.plist
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,27 @@
<integer>3</integer>
<key>AfterFullUpdateDelayDayCount</key>
<integer>14</integer>
<key>IconCustomPath</key>
<string>/Library/Scripts/nice_updater_custom_icon.png</string>
<key>Log</key>
<string>/Library/Logs/Nice_Updater.log</string>
<key>LoginAfterUpdatesInProgressMessage</key>
<string>Unfortunately you logged in while Apple Software Updates were being installed. This Mac will restart in 60 seconds.
If you have any questions please call the Help Desk.</string>
<key>MaxNotificationCount</key>
<integer>11</integer>
<integer>10</integer>
<key>UpdateInProgressMessage</key>
<string>Apple Software Updates are being installed now. Please do not turn off this Mac, it will automatically reboot once the installation is complete.
If you see this message for more than 30 minutes please call the Help Desk.</string>
<key>UpdateInProgressTitle</key>
<string>Software Update In Progress</string>
<key>UpdateRequiredMessage</key>
<string>Software updates are required to be installed on this Mac which require a restart. Please save your work and press Install Now to begin the installation.
The Mac will restart during installation is complete. Some macOS updates may require multiple restarts and/or the computer may shut down as part of the process.</string>
<key>UpdateRequiredTitle</key>
<string>macOS Software Updates Required</string>
</dict>
</plist>
21 changes: 15 additions & 6 deletions nice_updater.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ watchPathsPlist="/Library/Preferences/com.github.grahampugh.nice_updater.trigger
preferenceFileFullPath="/Library/Preferences/com.github.grahampugh.nice_updater.prefs.plist"

###### Variables below this point are not intended to be modified #####
helperTitle=$(defaults read "$preferenceFileFullPath" UpdateRequiredTitle)
helperDesc=$(defaults read "$preferenceFileFullPath" UpdateRequiredMessage)
updateInProgressTitle=$(defaults read "$preferenceFileFullPath" UpdateInProgressTitle)
updateInProgressMessage=$(defaults read "$preferenceFileFullPath" UpdateInProgressMessage)
loginAfterUpdatesInProgressMessage=$(defaults read "$preferenceFileFullPath" LoginAfterUpdatesInProgressMessage)
Expand All @@ -19,9 +21,18 @@ scriptName=$(basename "$0")
osVersion=$(sw_vers -productVersion)
osMinorVersion=$(echo "$osVersion" | awk -F. '{print $2}')
osReleaseVersion=$(echo "$osVersion" | awk -F. '{print $3}')
[[ "$osMinorVersion" -le 12 ]] && icon="/System/Library/CoreServices/Software Update.app/Contents/Resources/SoftwareUpdate.icns"
[[ "$osMinorVersion" -ge 13 ]] && icon="/System/Library/CoreServices/Install Command Line Developer Tools.app/Contents/Resources/SoftwareUpdate.icns"
iconCustomPath=$(defaults read "$preferenceFileFullPath" IconCustomPath)
JAMFHELPER="/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper"

# set default icon if not included in build
if [[ -z $iconCustomPath ]]; then
icon="$iconCustomPath"
elif [[ "$osMinorVersion" -le 12 ]]; then
icon="/System/Library/CoreServices/Software Update.app/Contents/Resources/SoftwareUpdate.icns"fi
elif [[ "$osMinorVersion" -ge 13 ]]; then
icon="/System/Library/CoreServices/Install Command Line Developer Tools.app/Contents/Resources/SoftwareUpdate.icns"
fi

function writelog () {
DATE=$(date +%Y-%m-%d\ %H:%M:%S)
/bin/echo "${1}"
Expand Down Expand Up @@ -103,8 +114,6 @@ function alert_user () {
launchctl load -w "$mainOnDemandDaemonPlist"
writelog "Notifying $loggedInUser of available updates..."
helperTitle="Software Updates Required"
helperDesc="Updates are required to be installed on this Mac which require a restart. The Mac will restart after installation."
if [[ "$notificationsLeft" == "0" ]]; then
helperExitCode=$( "$JAMFHELPER" -windowType utility -lockHUD -title "$helperTitle" -heading "$subtitle" -description "$helperDesc" -button1 "Install Now" -defaultButton 1 -timeout 82800 -icon "$icon" -iconSize 100 )
else
Expand Down Expand Up @@ -166,15 +175,15 @@ function update_check () {
writelog "A restart is required for remaining updates."
# If no user is logged in, just update and restart. Check the user now as some time has past since the script began.
loggedInUser=$(/usr/bin/python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "\n");')
loggedInUser=$(/usr/sbin/scutil <<< "show State:/Users/ConsoleUser" | /usr/bin/awk -F': ' '/[[:space:]]+Name[[:space:]]:/ { if ( $2 != "loginwindow" ) { print $2 }}')
loggedInUID=$(id -u "$loggedInUser")
if [[ "$loggedInUser" == "root" ]] || [[ -z "$loggedInUser" ]]; then
writelog "No user logged in."
writelog "Installing updates that DO require a restart..."
trigger_updates "--recommended --restart"
record_last_full_update
# Some time has passed since we started to install the updates, check for a logged in user once more
loggedInUser=$(/usr/bin/python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "\n");')
loggedInUser=$(/usr/sbin/scutil <<< "show State:/Users/ConsoleUser" | /usr/bin/awk -F': ' '/[[:space:]]+Name[[:space:]]:/ { if ( $2 != "loginwindow" ) { print $2 }}')
if [[ ! "$loggedInUser" == "root" ]] && [[ -n "$loggedInUser" ]]; then
writelog "$loggedInUser has logged in since we started to install updates, alerting them of pending restart."
"$JAMFHELPER" -windowType utility -lockHUD -title "$updateInProgressTitle" -alignHeading center -alignDescription natural -description "$loginAfterUpdatesInProgressMessage" -icon "$icon" -iconSize 100 -timeout "60"
Expand Down
4 changes: 4 additions & 0 deletions postinstall.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ chown root:wheel "$preferenceFileFullPath"
chmod 644 "$preferenceFileFullPath"
chown root:wheel /Library/Scripts/nice_updater.sh
chmod 755 /Library/Scripts/nice_updater.sh
if [[ -f /Library/Scripts/custom_icon.png ]]; then
chown root:wheel /Library/Scripts/custom_icon.png
chmod 644 /Library/Scripts/custom_icon.png
fi

# Start our LaunchDaemons
/bin/launchctl load -w "$mainDaemonPlist"
Expand Down

0 comments on commit 4614956

Please sign in to comment.