mirror of
https://github.com/mtan93/Installomator.git
synced 2026-04-02 22:04:27 +01:00
Merge pull request #406 from Installomator/2022-02-02_Theile-base
Version 9.0 fixed, from branch 2022 02 02 theile base
This commit is contained in:
@@ -43,17 +43,52 @@ if [[ $label == "version" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
printlog "################## Start Installomator v. $VERSION"
|
||||
printlog "################## $label"
|
||||
# MARK: Logging
|
||||
log_location="/private/var/log/Installomator.log"
|
||||
|
||||
# Check if we're in debug mode, if so then set logging to DEBUG, otherwise default to INFO
|
||||
# if no log level is specified.
|
||||
if [[ $DEBUG -ne 0 ]]; then
|
||||
LOGGING=DEBUG
|
||||
elif [[ -z $LOGGING ]]; then
|
||||
LOGGING=INFO
|
||||
datadogLoggingLevel=INFO
|
||||
fi
|
||||
|
||||
# Associate logging levels with a numerical value so that we are able to identify what
|
||||
# should be removed. For example if the LOGGING=ERROR only printlog statements with the
|
||||
# level REQ and ERROR will be displayed. LOGGING=DEBUG will show all printlog statements.
|
||||
# If a printlog statement has no level set it's automatically assigned INFO.
|
||||
|
||||
declare -A levels=(DEBUG 0 INFO 1 WARN 2 ERROR 3 REQ 4)
|
||||
|
||||
# If we are able to detect an MDM URL (Jamf Pro) or another identifier for a customer/instance we grab it here, this is useful if we're centrally logging multiple MDM instances.
|
||||
if [[ -f /Library/Preferences/com.jamfsoftware.jamf.plist ]]; then
|
||||
mdmURL=$(defaults read /Library/Preferences/com.jamfsoftware.jamf.plist jss_url)
|
||||
elif [[ -n "$MDMProfileName" ]]; then
|
||||
mdmURL=$(sudo profiles show | grep -A3 "$MDMProfileName" | sed -n -e 's/^.*organization: //p')
|
||||
else
|
||||
mdmURL="Unknown"
|
||||
fi
|
||||
|
||||
# Generate a session key for this run, this is useful to idenify streams when we're centrally logging.
|
||||
SESSION=$RANDOM
|
||||
|
||||
# Mark: START
|
||||
printlog "################## Start Installomator v. $VERSION, date $VERSIONDATE" REQ
|
||||
printlog "################## Version: $VERSION" INFO
|
||||
printlog "################## Date: $VERSIONDATE" INFO
|
||||
printlog "################## $label" INFO
|
||||
|
||||
# Check for DEBUG mode
|
||||
if [[ $DEBUG -gt 0 ]]; then
|
||||
printlog "DEBUG mode $DEBUG enabled."
|
||||
printlog "DEBUG mode $DEBUG enabled." DEBUG
|
||||
fi
|
||||
|
||||
# How we get version number from app
|
||||
# (alternative is "CFBundleVersion", that can be used in labels)
|
||||
versionKey="CFBundleShortVersionString"
|
||||
if [[ -z $versionKey ]]; then
|
||||
versionKey="CFBundleShortVersionString"
|
||||
fi
|
||||
|
||||
# get current user
|
||||
currentUser=$(scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ { print $3 }')
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
mochakeyboard)
|
||||
name="Mocha Keyboard"
|
||||
type="appInDmgInZip"
|
||||
downloadURL="https://mochasoft.dk/mochakeyboard.dmg.zip"
|
||||
appNewVersion=""
|
||||
expectedTeamID="RR9F5EPNVW"
|
||||
;;
|
||||
@@ -1,7 +0,0 @@
|
||||
mochatelnet)
|
||||
name="Telnet"
|
||||
type="appInDmgInZip"
|
||||
downloadURL="https://mochasoft.dk/telnet.dmg.zip"
|
||||
appNewVersion=""
|
||||
expectedTeamID="RR9F5EPNVW"
|
||||
;;
|
||||
@@ -1,7 +0,0 @@
|
||||
mochatn3270)
|
||||
name="TN3270"
|
||||
type="appInDmgInZip"
|
||||
downloadURL="https://mochasoft.dk/tn3270.dmg.zip"
|
||||
appNewVersion=""
|
||||
expectedTeamID="RR9F5EPNVW"
|
||||
;;
|
||||
@@ -1,7 +0,0 @@
|
||||
mochatn3812)
|
||||
name="TN3812"
|
||||
type="appInDmgInZip"
|
||||
downloadURL="https://mochasoft.dk/tn3812.dmg.zip"
|
||||
appNewVersion=""
|
||||
expectedTeamID="Frydendal"
|
||||
;;
|
||||
@@ -1,7 +0,0 @@
|
||||
mochatn5250)
|
||||
name="TN5250"
|
||||
type="appInDmgInZip"
|
||||
downloadURL="https://mochasoft.dk/tn5250.dmg.zip"
|
||||
appNewVersion=""
|
||||
expectedTeamID="RR9F5EPNVW"
|
||||
;;
|
||||
@@ -1,26 +1,29 @@
|
||||
# MARK: Functions
|
||||
|
||||
cleanupAndExit() { # $1 = exit code, $2 message
|
||||
if [[ -n $2 && $1 -ne 0 ]]; then
|
||||
printlog "ERROR: $2"
|
||||
fi
|
||||
if [ "$DEBUG" -ne 1 ]; then
|
||||
# remove the temporary working directory when done
|
||||
printlog "Deleting $tmpDir"
|
||||
rm -Rf "$tmpDir"
|
||||
fi
|
||||
|
||||
cleanupAndExit() { # $1 = exit code, $2 message, $3 level
|
||||
if [ -n "$dmgmount" ]; then
|
||||
# unmount disk image
|
||||
printlog "Unmounting $dmgmount"
|
||||
hdiutil detach "$dmgmount"
|
||||
printlog "Unmounting $dmgmount" DEBUG
|
||||
unmountingOut=$(hdiutil detach "$dmgmount" 2>&1)
|
||||
printlog "Debugging enabled, Unmounting output was:\n$unmountingOut" DEBUG
|
||||
fi
|
||||
if [ "$DEBUG" -ne 1 ]; then
|
||||
# remove the temporary working directory when done (only if DEBUG is not used)
|
||||
printlog "Deleting $tmpDir" DEBUG
|
||||
deleteTmpOut=$(rm -Rfv "$tmpDir")
|
||||
printlog "Debugging enabled, Deleting tmpDir output was:\n$deleteTmpOut" DEBUG
|
||||
fi
|
||||
|
||||
# If we closed any processes, reopen the app again
|
||||
reopenClosedProcess
|
||||
printlog "################## End Installomator, exit code $1 \n\n"
|
||||
if [[ -n $2 && $1 -ne 0 ]]; then
|
||||
printlog "ERROR: $2" $3
|
||||
fi
|
||||
printlog "################## End Installomator, exit code $1 \n\n" REQ
|
||||
|
||||
# if label is wrong and we wanted name of the label, then return ##################
|
||||
if [[ $RETURN_LABEL_NAME -eq 1 ]]; then
|
||||
1=0
|
||||
1=0 # If only label name should be returned we exit without any errors
|
||||
echo "#"
|
||||
fi
|
||||
exit "$1"
|
||||
@@ -64,19 +67,77 @@ displaynotification() { # $1: message $2: title
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# MARK: Logging
|
||||
log_location="/private/var/log/Installomator.log"
|
||||
|
||||
printlog(){
|
||||
|
||||
[ -z "$2" ] && 2=INFO
|
||||
log_message=$1
|
||||
log_priority=$2
|
||||
timestamp=$(date +%F\ %T)
|
||||
|
||||
if [[ "$(whoami)" == "root" ]]; then
|
||||
echo "$timestamp" "$label" "$1" | tee -a $log_location
|
||||
else
|
||||
echo "$timestamp" "$label" "$1"
|
||||
# Check to make sure that the log isn't the same as the last, if it is then don't log and increment a timer.
|
||||
if [[ ${log_message} == ${previous_log_message} ]]; then
|
||||
let logrepeat=$logrepeat+1
|
||||
return
|
||||
fi
|
||||
previous_log_message=$log_message
|
||||
|
||||
# Once we finally stop getting duplicate logs output the number of times we got a duplicate.
|
||||
if [[ $logrepeat -gt 1 ]];then
|
||||
echo "$timestamp" : "${log_priority} : $label : Last Log repeated ${logrepeat} times" | tee -a $log_location
|
||||
|
||||
if [[ ! -z $datadogAPI ]]; then
|
||||
curl -s -X POST https://http-intake.logs.datadoghq.com/v1/input -H "Content-Type: text/plain" -H "DD-API-KEY: $datadogAPI" -d "${log_priority} : $mdmURL : $APPLICATION : $VERSION : $SESSION : Last Log repeated ${logrepeat} times" > /dev/null
|
||||
fi
|
||||
logrepeat=0
|
||||
fi
|
||||
|
||||
# If the datadogAPI key value is set and our logging level is greater than or equal to our set level
|
||||
# then post to Datadog's HTTPs endpoint.
|
||||
if [[ -n $datadogAPI && ${levels[$log_priority]} -ge ${levels[$datadogLoggingLevel]} ]]; then
|
||||
while IFS= read -r logmessage; do
|
||||
curl -s -X POST https://http-intake.logs.datadoghq.com/v1/input -H "Content-Type: text/plain" -H "DD-API-KEY: $datadogAPI" -d "${log_priority} : $mdmURL : Installomator-${label} : ${VERSIONDATE//-/} : $SESSION : ${logmessage}" > /dev/null
|
||||
done <<< "$log_message"
|
||||
fi
|
||||
|
||||
# Extra spaces
|
||||
space_char=""
|
||||
if [[ ${#log_priority} -eq 3 ]]; then
|
||||
space_char=" "
|
||||
elif [[ ${#log_priority} -eq 4 ]]; then
|
||||
space_char=" "
|
||||
fi
|
||||
# If our logging level is greaterthan or equal to our set level then output locally.
|
||||
if [[ ${levels[$log_priority]} -ge ${levels[$LOGGING]} ]]; then
|
||||
while IFS= read -r logmessage; do
|
||||
if [[ "$(whoami)" == "root" ]]; then
|
||||
echo "$timestamp" : "${log_priority}${space_char} : $label : ${logmessage}" | tee -a $log_location
|
||||
else
|
||||
echo "$timestamp" : "${log_priority}${space_char} : $label : ${logmessage}"
|
||||
fi
|
||||
done <<< "$log_message"
|
||||
fi
|
||||
}
|
||||
|
||||
# Used to remove dupplicate lines in large log output,
|
||||
# for example from msupdate command after it finishes running.
|
||||
deduplicatelogs() {
|
||||
loginput=${1:-"Log"}
|
||||
logoutput=""
|
||||
# Read each line of the incoming log individually, match it with the previous.
|
||||
# If it matches increment logrepeate then skip to the next line.
|
||||
while read log; do
|
||||
if [[ $log == $previous_log ]];then
|
||||
let logrepeat=$logrepeat+1
|
||||
continue
|
||||
fi
|
||||
|
||||
previous_log="$log"
|
||||
if [[ $logrepeat -gt 1 ]];then
|
||||
logoutput+="Last Log repeated ${logrepeat} times\n"
|
||||
logrepeat=0
|
||||
fi
|
||||
|
||||
logoutput+="$log\n"
|
||||
done <<< "$loginput"
|
||||
}
|
||||
|
||||
# will get the latest release download from a github repo
|
||||
@@ -100,8 +161,7 @@ downloadURLFromGit() { # $1 git user name, $2 git repo name
|
||||
| awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
|
||||
fi
|
||||
if [ -z "$downloadURL" ]; then
|
||||
cleanupAndExit 9 "could not retrieve download URL for $gitusername/$gitreponame"
|
||||
#exit 9
|
||||
cleanupAndExit 9 "could not retrieve download URL for $gitusername/$gitreponame" ERROR
|
||||
else
|
||||
echo "$downloadURL"
|
||||
return 0
|
||||
@@ -169,9 +229,9 @@ getAppVersion() {
|
||||
applist=$(mdfind "kind:application $appName" -0 )
|
||||
fi
|
||||
if [[ -z applist ]]; then
|
||||
printlog "No previous app found"
|
||||
printlog "No previous app found" DEBUG
|
||||
else
|
||||
printlog "App(s) found: ${applist}"
|
||||
printlog "App(s) found: ${applist}" DEBUG
|
||||
fi
|
||||
|
||||
appPathArray=( ${(0)applist} )
|
||||
@@ -182,7 +242,7 @@ getAppVersion() {
|
||||
installedAppPath=$filteredAppPaths[1]
|
||||
#appversion=$(mdls -name kMDItemVersion -raw $installedAppPath )
|
||||
appversion=$(defaults read $installedAppPath/Contents/Info.plist $versionKey) #Not dependant on Spotlight indexing
|
||||
printlog "found app at $installedAppPath, version $appversion"
|
||||
printlog "found app at $installedAppPath, version $appversion, on versionKey $versionKey"
|
||||
updateDetected="YES"
|
||||
# Is current app from App Store
|
||||
if [[ -d "$installedAppPath"/Contents/_MASReceipt ]];then
|
||||
@@ -191,7 +251,7 @@ getAppVersion() {
|
||||
printlog "Replacing App Store apps, no matter the version"
|
||||
appversion=0
|
||||
else
|
||||
cleanupAndExit 1 "App previously installed from App Store, and we respect that"
|
||||
cleanupAndExit 1 "App previously installed from App Store, and we respect that" ERROR
|
||||
fi
|
||||
fi
|
||||
else
|
||||
@@ -205,7 +265,7 @@ getAppVersion() {
|
||||
checkRunningProcesses() {
|
||||
# don't check in DEBUG mode 1
|
||||
if [[ $DEBUG -eq 1 ]]; then
|
||||
printlog "DEBUG mode 1, not checking for blocking processes"
|
||||
printlog "DEBUG mode 1, not checking for blocking processes" DEBUG
|
||||
return
|
||||
fi
|
||||
|
||||
@@ -238,7 +298,7 @@ checkRunningProcesses() {
|
||||
prompt_user|prompt_user_then_kill)
|
||||
button=$(displaydialog "Quit “$x” to continue updating? (Leave this dialogue if you want to activate this update later)." "The application “$x” needs to be updated.")
|
||||
if [[ $button = "Not Now" ]]; then
|
||||
cleanupAndExit 10 "user aborted update"
|
||||
cleanupAndExit 10 "user aborted update" ERROR
|
||||
else
|
||||
if [[ $i > 2 && $BLOCKING_PROCESS_ACTION = "prompt_user_then_kill" ]]; then
|
||||
printlog "Changing BLOCKING_PROCESS_ACTION to kill"
|
||||
@@ -283,7 +343,7 @@ checkRunningProcesses() {
|
||||
fi
|
||||
;;
|
||||
silent_fail)
|
||||
cleanupAndExit 12 "blocking process '$x' found, aborting"
|
||||
cleanupAndExit 12 "blocking process '$x' found, aborting" ERROR
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -294,10 +354,10 @@ checkRunningProcesses() {
|
||||
done
|
||||
|
||||
if [[ $countedProcesses -ne 0 ]]; then
|
||||
cleanupAndExit 11 "could not quit all processes, aborting..."
|
||||
cleanupAndExit 11 "could not quit all processes, aborting..." ERROR
|
||||
fi
|
||||
|
||||
printlog "no more blocking processes, continue with update"
|
||||
printlog "no more blocking processes, continue with update" REQ
|
||||
}
|
||||
|
||||
reopenClosedProcess() {
|
||||
@@ -312,7 +372,7 @@ reopenClosedProcess() {
|
||||
|
||||
# don't reopen in DEBUG mode 1
|
||||
if [[ $DEBUG -eq 1 ]]; then
|
||||
printlog "DEBUG mode 1, not reopening anything"
|
||||
printlog "DEBUG mode 1, not reopening anything" DEBUG
|
||||
return
|
||||
fi
|
||||
|
||||
@@ -325,7 +385,7 @@ reopenClosedProcess() {
|
||||
processuser=$(ps aux | grep -i "${appName}" | grep -vi "grep" | awk '{print $1}')
|
||||
printlog "Reopened ${appName} as $processuser"
|
||||
else
|
||||
printlog "App not closed, so no reopen."
|
||||
printlog "App not closed, so no reopen." DEBUG
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -335,42 +395,49 @@ installAppWithPath() { # $1: path to app to install in $targetDir
|
||||
|
||||
# check if app exists
|
||||
if [ ! -e "$appPath" ]; then
|
||||
cleanupAndExit 8 "could not find: $appPath"
|
||||
cleanupAndExit 8 "could not find: $appPath" DEBUG
|
||||
fi
|
||||
|
||||
# verify with spctl
|
||||
printlog "Verifying: $appPath"
|
||||
if ! teamID=$(spctl -a -vv "$appPath" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' ); then
|
||||
cleanupAndExit 4 "Error verifying $appPath"
|
||||
fi
|
||||
printlog "Verifying: $appPath" INFO
|
||||
printlog "App size: $(du -sh "$appPath")" DEBUG
|
||||
appVerify=$(spctl -a -vv "$appPath" 2>&1 )
|
||||
appVerifyStatus=$(echo $?)
|
||||
teamID=$(echo $appVerify | awk '/origin=/ {print $NF }' | tr -d '()' )
|
||||
deduplicatelogs "$appVerify"
|
||||
|
||||
printlog "Team ID matching: $teamID (expected: $expectedTeamID )"
|
||||
if [[ $appVerifyStatus -ne 0 ]] ; then
|
||||
#if ! teamID=$(spctl -a -vv "$appPath" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' ); then
|
||||
cleanupAndExit 4 "Error verifying $appPath error:\n$logoutput" ERROR
|
||||
fi
|
||||
printlog "Debugging enabled, App Verification output was:\n$logoutput" DEBUG
|
||||
printlog "Team ID matching: $teamID (expected: $expectedTeamID )" INFO
|
||||
|
||||
if [ "$expectedTeamID" != "$teamID" ]; then
|
||||
cleanupAndExit 5 "Team IDs do not match"
|
||||
cleanupAndExit 5 "Team IDs do not match" ERROR
|
||||
fi
|
||||
|
||||
# app versioncheck
|
||||
appNewVersion=$(defaults read $appPath/Contents/Info.plist $versionKey)
|
||||
if [[ -n $appNewVersion && $appversion == $appNewVersion ]]; then
|
||||
printlog "Downloaded version of $name is $appNewVersion, same as installed."
|
||||
printlog "Downloaded version of $name is $appNewVersion on versionKey $versionKey, same as installed."
|
||||
if [[ $INSTALL != "force" ]]; then
|
||||
message="$name, version $appNewVersion, is the latest version."
|
||||
if [[ $currentUser != "loginwindow" && $NOTIFY == "all" ]]; then
|
||||
printlog "notifying"
|
||||
displaynotification "$message" "No update for $name!"
|
||||
fi
|
||||
cleanupAndExit 0 "No new version to install"
|
||||
cleanupAndExit 0 "No new version to install" INFO
|
||||
else
|
||||
printlog "Using force to install anyway."
|
||||
fi
|
||||
else
|
||||
printlog "Downloaded version of $name is $appNewVersion (replacing version $appversion)."
|
||||
printlog "Downloaded version of $name is $appNewVersion on versionKey $versionKey (replacing version $appversion)."
|
||||
fi
|
||||
|
||||
# macOS versioncheck
|
||||
minimumOSversion=$(defaults read $appPath/Contents/Info.plist LSMinimumSystemVersion)
|
||||
if [[ $minimumOSversion =~ '[0-9.]*' ]]; then
|
||||
minimumOSversion=$(defaults read $appPath/Contents/Info.plist LSMinimumSystemVersion 2>/dev/null )
|
||||
if [[ -n $minimumOSversion && $minimumOSversion =~ '[0-9.]*' ]]; then
|
||||
printlog "App has LSMinimumSystemVersion: $minimumOSversion"
|
||||
if ! is-at-least $minimumOSversion $installedOSversion; then
|
||||
printlog "App requires higher System Version than installed: $installedOSversion"
|
||||
@@ -379,19 +446,19 @@ installAppWithPath() { # $1: path to app to install in $targetDir
|
||||
printlog "notifying"
|
||||
displaynotification "$message" "Error updating $name!"
|
||||
fi
|
||||
cleanupAndExit 6 "Installed macOS is too old for this app."
|
||||
cleanupAndExit 6 "Installed macOS is too old for this app." INFO
|
||||
fi
|
||||
fi
|
||||
|
||||
# skip install for DEBUG 1
|
||||
if [ "$DEBUG" -eq 1 ]; then
|
||||
printlog "DEBUG mode 1 enabled, skipping remove, copy and chown steps"
|
||||
printlog "DEBUG mode 1 enabled, skipping remove, copy and chown steps" DEBUG
|
||||
return 0
|
||||
fi
|
||||
|
||||
# skip install for DEBUG 2
|
||||
if [ "$DEBUG" -eq 2 ]; then
|
||||
printlog "DEBUG mode 2 enabled, exiting"
|
||||
printlog "DEBUG mode 2 enabled, not installing anything, exiting" DEBUG
|
||||
cleanupAndExit 0
|
||||
fi
|
||||
|
||||
@@ -400,14 +467,19 @@ installAppWithPath() { # $1: path to app to install in $targetDir
|
||||
|
||||
# remove existing application
|
||||
if [ -e "$targetDir/$appName" ]; then
|
||||
printlog "Removing existing $targetDir/$appName"
|
||||
rm -Rf "$targetDir/$appName"
|
||||
printlog "Removing existing $targetDir/$appName" DEBUG
|
||||
deleteAppOut=$(rm -Rfv "$targetDir/$appName" 2>&1)
|
||||
tempName="$targetDir/$appName"
|
||||
tempNameLength=$((${#tempName} + 10))
|
||||
deleteAppOut=$(echo $deleteAppOut | cut -c 1-$tempNameLength)
|
||||
deduplicatelogs "$deleteAppOut"
|
||||
printlog "Debugging enabled, App removing output was:\n$logoutput" DEBUG
|
||||
fi
|
||||
|
||||
# copy app to /Applications
|
||||
printlog "Copy $appPath to $targetDir"
|
||||
if ! ditto "$appPath" "$targetDir/$appName"; then
|
||||
cleanupAndExit 7 "Error while copying"
|
||||
cleanupAndExit 7 "Error while copying" ERROR
|
||||
fi
|
||||
|
||||
# set ownership to current user
|
||||
@@ -415,24 +487,24 @@ installAppWithPath() { # $1: path to app to install in $targetDir
|
||||
printlog "Changing owner to $currentUser"
|
||||
chown -R "$currentUser" "$targetDir/$appName"
|
||||
else
|
||||
printlog "No user logged in or SYSTEMOWNER=1, setting owner to root:wheel"
|
||||
printlog "No user logged in or SYSTEMOWNER=1, setting owner to root:wheel"
|
||||
chown -R root:wheel "$targetDir/$appName"
|
||||
fi
|
||||
|
||||
elif [[ ! -z $CLIInstaller ]]; then
|
||||
mountname=$(dirname $appPath)
|
||||
printlog "CLIInstaller exists, running installer command $mountname/$CLIInstaller $CLIArguments" #INFO
|
||||
printlog "CLIInstaller exists, running installer command $mountname/$CLIInstaller $CLIArguments" INFO
|
||||
|
||||
CLIoutput=$("$mountname/$CLIInstaller" "${CLIArguments[@]}" 2>&1)
|
||||
CLIstatus=$(echo $?)
|
||||
logoutput="$CLIoutput" # dedupliatelogs "$CLIoutput"
|
||||
deduplicatelogs "$CLIoutput"
|
||||
|
||||
if [ $CLIstatus -ne 0 ] ; then
|
||||
cleanupAndExit 3 "Error installing $mountname/$CLIInstaller $CLIArguments error:\n$logoutput" #ERROR
|
||||
cleanupAndExit 3 "Error installing $mountname/$CLIInstaller $CLIArguments error:\n$logoutput" ERROR
|
||||
else
|
||||
printlog "Succesfully ran $mountname/$CLIInstaller $CLIArguments"
|
||||
printlog "Succesfully ran $mountname/$CLIInstaller $CLIArguments" INFO
|
||||
fi
|
||||
printlog "Debugging enabled, update tool output was:\n$logoutput" #DEBUG
|
||||
printlog "Debugging enabled, update tool output was:\n$logoutput" DEBUG
|
||||
fi
|
||||
|
||||
}
|
||||
@@ -441,16 +513,21 @@ mountDMG() {
|
||||
# mount the dmg
|
||||
printlog "Mounting $tmpDir/$archiveName"
|
||||
# always pipe 'Y\n' in case the dmg requires an agreement
|
||||
if ! dmgmount=$(echo 'Y'$'\n' | hdiutil attach "$tmpDir/$archiveName" -nobrowse -readonly | tail -n 1 | cut -c 54- ); then
|
||||
cleanupAndExit 3 "Error mounting $tmpDir/$archiveName"
|
||||
dmgmountOut=$(echo 'Y'$'\n' | hdiutil attach "$tmpDir/$archiveName" -nobrowse -readonly )
|
||||
dmgmountStatus=$(echo $?)
|
||||
dmgmount=$(echo $dmgmountOut | tail -n 1 | cut -c 54- )
|
||||
deduplicatelogs "$dmgmountOut"
|
||||
|
||||
if [[ $dmgmountStatus -ne 0 ]] ; then
|
||||
#if ! dmgmount=$(echo 'Y'$'\n' | hdiutil attach "$tmpDir/$archiveName" -nobrowse -readonly | tail -n 1 | cut -c 54- ); then
|
||||
cleanupAndExit 3 "Error mounting $tmpDir/$archiveName error:\n$logoutput" ERROR
|
||||
fi
|
||||
|
||||
if [[ ! -e $dmgmount ]]; then
|
||||
printlog "Error mounting $tmpDir/$archiveName"
|
||||
cleanupAndExit 3
|
||||
cleanupAndExit 3 "Error accessing mountpoint for $tmpDir/$archiveName error:\n$logoutput" ERROR
|
||||
fi
|
||||
|
||||
printlog "Mounted: $dmgmount"
|
||||
printlog "Debugging enabled, dmgmount output was:\n$logoutput" DEBUG
|
||||
|
||||
printlog "Mounted: $dmgmount" INFO
|
||||
}
|
||||
|
||||
installFromDMG() {
|
||||
@@ -461,25 +538,34 @@ installFromDMG() {
|
||||
installFromPKG() {
|
||||
# verify with spctl
|
||||
printlog "Verifying: $archiveName"
|
||||
|
||||
if ! spctlout=$(spctl -a -vv -t install "$archiveName" 2>&1 ); then
|
||||
printlog "Error verifying $archiveName"
|
||||
cleanupAndExit 4
|
||||
printlog "File list: $(ls -lh "$archiveName")" DEBUG
|
||||
printlog "File type: $(file "$archiveName")" DEBUG
|
||||
spctlOut=$(spctl -a -vv -t install "$archiveName" 2>&1 )
|
||||
spctlStatus=$(echo $?)
|
||||
printlog "spctlOut is $spctlOut" DEBUG
|
||||
|
||||
teamID=$(echo $spctlOut | awk -F '(' '/origin=/ {print $2 }' | tr -d '()' )
|
||||
# Apple signed software has no teamID, grab entire origin instead
|
||||
if [[ -z $teamID ]]; then
|
||||
teamID=$(echo $spctlOut | awk -F '=' '/origin=/ {print $NF }')
|
||||
fi
|
||||
|
||||
teamID=$(echo $spctlout | awk -F '(' '/origin=/ {print $2 }' | tr -d '()' )
|
||||
deduplicatelogs "$spctlOut"
|
||||
|
||||
if [[ $spctlStatus -ne 0 ]] ; then
|
||||
#if ! spctlout=$(spctl -a -vv -t install "$archiveName" 2>&1 ); then
|
||||
cleanupAndExit 4 "Error verifying $archiveName error:\n$logoutput" ERROR
|
||||
fi
|
||||
|
||||
# Apple signed software has no teamID, grab entire origin instead
|
||||
if [[ -z $teamID ]]; then
|
||||
teamID=$(echo $spctlout | awk -F '=' '/origin=/ {print $NF }')
|
||||
fi
|
||||
|
||||
|
||||
printlog "Team ID: $teamID (expected: $expectedTeamID )"
|
||||
|
||||
if [ "$expectedTeamID" != "$teamID" ]; then
|
||||
printlog "Team IDs do not match!"
|
||||
cleanupAndExit 5
|
||||
cleanupAndExit 5 "Team IDs do not match!" ERROR
|
||||
fi
|
||||
|
||||
# Check version of pkg to be installed if packageID is set
|
||||
@@ -499,7 +585,7 @@ installFromPKG() {
|
||||
printlog "notifying"
|
||||
displaynotification "$message" "No update for $name!"
|
||||
fi
|
||||
cleanupAndExit 0 "No new version to install"
|
||||
cleanupAndExit 0 "No new version to install" INFO
|
||||
else
|
||||
printlog "Using force to install anyway."
|
||||
fi
|
||||
@@ -508,22 +594,38 @@ installFromPKG() {
|
||||
|
||||
# skip install for DEBUG 1
|
||||
if [ "$DEBUG" -eq 1 ]; then
|
||||
printlog "DEBUG enabled, skipping installation"
|
||||
printlog "DEBUG enabled, skipping installation" DEBUG
|
||||
return 0
|
||||
fi
|
||||
|
||||
# skip install for DEBUG 2
|
||||
if [ "$DEBUG" -eq 2 ]; then
|
||||
printlog "DEBUG mode 2 enabled, exiting"
|
||||
cleanupAndExit 0
|
||||
cleanupAndExit 0 "DEBUG mode 2 enabled, exiting" DEBUG
|
||||
fi
|
||||
|
||||
# install pkg
|
||||
printlog "Installing $archiveName to $targetDir"
|
||||
if ! installer -pkg "$archiveName" -tgt "$targetDir" ; then
|
||||
printlog "error installing $archiveName"
|
||||
cleanupAndExit 9
|
||||
pkgInstall=$(installer -verbose -dumplog -pkg "$archiveName" -tgt "$targetDir" 2>&1)
|
||||
pkgInstallStatus=$(echo $?)
|
||||
sleep 1
|
||||
pkgEndTime=$(date "+$LogDateFormat")
|
||||
pkgInstall+=$(echo "\nOutput of /var/log/install.log below this line.\n")
|
||||
pkgInstall+=$(echo "----------------------------------------------------------\n")
|
||||
pkgInstall+=$(awk -v "b=$starttime" -v "e=$pkgEndTime" -F ',' '$1 >= b && $1 <= e' /var/log/install.log)
|
||||
deduplicatelogs "$pkgInstall"
|
||||
|
||||
if [[ $pkgInstallStatus -ne 0 ]] && [[ $logoutput == *"requires Rosetta 2"* ]] && [[ $rosetta2 == no ]]; then
|
||||
printlog "Package requires Rosetta 2, Installing Rosetta 2 and Installing Package" INFO
|
||||
/usr/sbin/softwareupdate --install-rosetta --agree-to-license
|
||||
rosetta2=yes
|
||||
installFromPKG
|
||||
fi
|
||||
|
||||
if [[ $pkginstallstatus -ne 0 ]] ; then
|
||||
#if ! installer -pkg "$archiveName" -tgt "$targetDir" ; then
|
||||
cleanupAndExit 9 "Error installing $archiveName error:\n$logoutput" ERROR
|
||||
fi
|
||||
printlog "Debugging enabled, installer output was:\n$logoutput" DEBUG
|
||||
}
|
||||
|
||||
installFromZIP() {
|
||||
@@ -556,10 +658,10 @@ installPkgInDmg() {
|
||||
# locate pkg in dmg
|
||||
if [[ -z $pkgName ]]; then
|
||||
# find first file ending with 'pkg'
|
||||
findfiles=$(find "$dmgmount" -iname "*.pkg" -maxdepth 1 )
|
||||
findfiles=$(find "$dmgmount" -iname "*.pkg" -type f -maxdepth 1 )
|
||||
filearray=( ${(f)findfiles} )
|
||||
if [[ ${#filearray} -eq 0 ]]; then
|
||||
cleanupAndExit 20 "couldn't find pkg in dmg $archiveName"
|
||||
cleanupAndExit 20 "couldn't find pkg in dmg $archiveName" ERROR
|
||||
fi
|
||||
archiveName="${filearray[1]}"
|
||||
printlog "found pkg: $archiveName"
|
||||
@@ -571,7 +673,7 @@ installPkgInDmg() {
|
||||
findfiles=$(find "$tmpDir" -iname "$pkgName")
|
||||
filearray=( ${(f)findfiles} )
|
||||
if [[ ${#filearray} -eq 0 ]]; then
|
||||
cleanupAndExit 20 "couldn't find pkg “$pkgName” in zip $archiveName"
|
||||
cleanupAndExit 20 "couldn't find pkg “$pkgName” in zip $archiveName" ERROR
|
||||
fi
|
||||
# it is now safe to overwrite archiveName for installFromPKG
|
||||
archiveName="${filearray[1]}"
|
||||
@@ -591,23 +693,23 @@ installPkgInZip() {
|
||||
# locate pkg in zip
|
||||
if [[ -z $pkgName ]]; then
|
||||
# find first file ending with 'pkg'
|
||||
findfiles=$(find "$tmpDir" -iname "*.pkg" -maxdepth 2 )
|
||||
findfiles=$(find "$tmpDir" -iname "*.pkg" -type f -maxdepth 2 )
|
||||
filearray=( ${(f)findfiles} )
|
||||
if [[ ${#filearray} -eq 0 ]]; then
|
||||
cleanupAndExit 20 "couldn't find pkg in zip $archiveName"
|
||||
cleanupAndExit 20 "couldn't find pkg in zip $archiveName" ERROR
|
||||
fi
|
||||
# it is now safe to overwrite archiveName for installFromPKG
|
||||
archiveName="${filearray[1]}"
|
||||
printlog "found pkg: $archiveName"
|
||||
else
|
||||
if ls "$tmpDir/$pkgName" ; then
|
||||
if [[ -s "$tmpDir/$pkgName" ]]; then
|
||||
archiveName="$tmpDir/$pkgName"
|
||||
else
|
||||
# try searching for pkg
|
||||
findfiles=$(find "$tmpDir" -iname "$pkgName")
|
||||
filearray=( ${(f)findfiles} )
|
||||
if [[ ${#filearray} -eq 0 ]]; then
|
||||
cleanupAndExit 20 "couldn't find pkg “$pkgName” in zip $archiveName"
|
||||
cleanupAndExit 20 "couldn't find pkg “$pkgName” in zip $archiveName" ERROR
|
||||
fi
|
||||
# it is now safe to overwrite archiveName for installFromPKG
|
||||
archiveName="${filearray[1]}"
|
||||
@@ -630,7 +732,7 @@ installAppInDmgInZip() {
|
||||
findfiles=$(find "$tmpDir" -iname "*.dmg" -maxdepth 2 )
|
||||
filearray=( ${(f)findfiles} )
|
||||
if [[ ${#filearray} -eq 0 ]]; then
|
||||
cleanupAndExit 20 "couldn't find dmg in zip $archiveName"
|
||||
cleanupAndExit 20 "couldn't find dmg in zip $archiveName" ERROR
|
||||
fi
|
||||
archiveName="$(basename ${filearray[1]})"
|
||||
# it is now safe to overwrite archiveName for installFromDMG
|
||||
@@ -649,12 +751,29 @@ runUpdateTool() {
|
||||
if [[ -x $updateTool ]]; then
|
||||
printlog "running $updateTool $updateToolArguments"
|
||||
if [[ -n $updateToolRunAsCurrentUser ]]; then
|
||||
runAsUser $updateTool ${updateToolArguments}
|
||||
updateOutput=$(runAsUser $updateTool ${updateToolArguments} 2>&1)
|
||||
updateStatus=$(echo $?)
|
||||
else
|
||||
$updateTool ${updateToolArguments}
|
||||
updateOutput=$($updateTool ${updateToolArguments} 2>&1)
|
||||
updateStatus=$(echo $?)
|
||||
fi
|
||||
if [[ $? -ne 0 ]]; then
|
||||
cleanupAndExit 15 "Error running $updateTool"
|
||||
sleep 1
|
||||
updateEndTime=$(date "+$updateToolLogDateFormat")
|
||||
deduplicatelogs $updateOutput
|
||||
if [[ -n $updateToolLog ]]; then
|
||||
updateOutput+=$(echo "Output of Installer log of $updateToolLog below this line.\n")
|
||||
updateOutput+=$(echo "----------------------------------------------------------\n")
|
||||
updateOutput+=$(awk -v "b=$updatestarttime" -v "e=$updateEndTime" -F ',' '$1 >= b && $1 <= e' $updateToolLog)
|
||||
fi
|
||||
|
||||
if [[ $updateStatus -ne 0 ]]; then
|
||||
printlog "Error running $updateTool, Procceding with normal installation. Exit Status: $updateStatus Error:\n$logoutput" WARN
|
||||
return 1
|
||||
if [[ $type == updateronly ]]; then
|
||||
cleanupAndExit 77 "No Download URL Set, this is an update only application and the updater failed" WARN
|
||||
fi
|
||||
elif [[ $updateStatus -eq 0 ]]; then
|
||||
printlog "Debugging enabled, update tool output was:\n$logoutput" DEBUG
|
||||
fi
|
||||
else
|
||||
printlog "couldn't find $updateTool, continuing normally"
|
||||
@@ -686,4 +805,30 @@ finishing() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Detect if there is an app actively making a display sleep assertion, e.g.
|
||||
# KeyNote, PowerPoint, Zoom, or Webex.
|
||||
# See: https://developer.apple.com/documentation/iokit/iopmlib_h/iopmassertiontypes
|
||||
hasDisplaySleepAssertion() {
|
||||
# Get the names of all apps with active display sleep assertions
|
||||
local apps="$(/usr/bin/pmset -g assertions | /usr/bin/awk '/NoDisplaySleepAssertion | PreventUserIdleDisplaySleep/ && match($0,/\(.+\)/) && ! /coreaudiod/ {gsub(/^.*\(/,"",$0); gsub(/\).*$/,"",$0); print};')"
|
||||
|
||||
if [[ ! "${apps}" ]]; then
|
||||
# No display sleep assertions detected
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Create an array of apps that need to be ignored
|
||||
local ignore_array=("${(@s/,/)IGNORE_DND_APPS}")
|
||||
|
||||
for app in ${(f)apps}; do
|
||||
if (( ! ${ignore_array[(Ie)${app}]} )); then
|
||||
# Relevant app with display sleep assertion detected
|
||||
printlog "Display sleep assertion detected by ${app}."
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
# No relevant display sleep assertion detected
|
||||
return 1
|
||||
}
|
||||
|
||||
|
||||
@@ -126,6 +126,18 @@ REOPEN="yes"
|
||||
# instead of just the label name.
|
||||
|
||||
|
||||
# Interrupt Do Not Disturb (DND) full screen apps
|
||||
INTERRUPT_DND="yes"
|
||||
# options:
|
||||
# - yes Script will run without checking for DND full screen apps.
|
||||
# - no Script will exit when an active DND full screen app is detected.
|
||||
|
||||
# Comma separated list of app names to ignore when evaluating DND
|
||||
IGNORE_DND_APPS=""
|
||||
# example that will ignore browsers when evaluating DND:
|
||||
# IGNORE_DND_APPS="firefox,Google Chrome,Safari,Microsoft Edge,Opera,Amphetamine,caffeinate"
|
||||
|
||||
|
||||
# NOTE: How labels work
|
||||
|
||||
# Each workflow label needs to be listed in the case statement below.
|
||||
@@ -156,6 +168,12 @@ REOPEN="yes"
|
||||
# URL to download the dmg.
|
||||
# Can be generated with a series of commands (see BBEdit for an example).
|
||||
#
|
||||
# - curlOptions: (array, optional)
|
||||
# Options to the curl command, needed for curl to be able to download the software.
|
||||
# Usually used for adding extra headers that some servers need in order to serve the file.
|
||||
# curlOptions=( -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15" )
|
||||
# (See “mocha”-labels, for examples on labels, and buildLabel.sh for header-examples.)
|
||||
#
|
||||
# - appNewVersion: (optional)
|
||||
# Version of the downloaded software.
|
||||
# If given, it will be compared to the installed version, to see if the download is different.
|
||||
@@ -246,3 +264,40 @@ REOPEN="yes"
|
||||
# installer that should be located after mounting/expanding the downloaded archive.
|
||||
# See label adobecreativeclouddesktop
|
||||
#
|
||||
### Logging
|
||||
# Logging behavior
|
||||
LOGGING="INFO"
|
||||
# options:
|
||||
# - DEBUG Everything is logged
|
||||
# - INFO (default) normal logging level
|
||||
# - WARN only warning
|
||||
# - ERROR only errors
|
||||
# - REQ ????
|
||||
|
||||
# MDM profile name
|
||||
MDMProfileName=""
|
||||
# options:
|
||||
# - MDM Profile Addigy has this name on the profile
|
||||
# - Mosyle Corporation MDM Mosyle uses this name on the profile
|
||||
# From the LOGO variable we can know if Addigy og Mosyle is used, so if that variable
|
||||
# is either of these, and this variable is empty, then we will auto detect this.
|
||||
|
||||
# Datadog logging used
|
||||
datadogAPI=""
|
||||
# Simply add your own API key for this in order to have logs sent to Datadog
|
||||
# See more here: https://www.datadoghq.com/product/log-management/
|
||||
|
||||
# Log Date format used when parsing logs for debugging, this is the default used by
|
||||
# install.log, override this in the case statements if you need something custom per
|
||||
# application (See adobeillustrator). Using stadard GNU Date formatting.
|
||||
LogDateFormat="%Y-%m-%d %H:%M:%S"
|
||||
|
||||
# Get the start time for parsing install.log if we fail.
|
||||
starttime=$(date "+$LogDateFormat")
|
||||
|
||||
# Check if we have rosetta installed
|
||||
if [[ $(/usr/bin/arch) == "arm64" ]]; then
|
||||
if ! arch -x86_64 /usr/bin/true >/dev/null 2>&1; then # pgrep oahd >/dev/null 2>&1
|
||||
rosetta2=no
|
||||
fi
|
||||
fi
|
||||
|
||||
8
fragments/labels/diskspace.sh
Normal file
8
fragments/labels/diskspace.sh
Normal file
@@ -0,0 +1,8 @@
|
||||
diskspace)
|
||||
name="diskspace"
|
||||
type="pkg"
|
||||
packageID="com.scriptingosx.diskspace"
|
||||
downloadURL="$(downloadURLFromGit scriptingosx diskspace)"
|
||||
appNewVersion="$(versionFromGit scriptingosx diskspace)"
|
||||
expectedTeamID="JME5BW3F3R"
|
||||
;;
|
||||
@@ -1,7 +1,7 @@
|
||||
eshareosx)
|
||||
name="e-Share"
|
||||
type="pkg"
|
||||
packageID="com.ncryptedcloud.e-Share.pkg"
|
||||
#packageID="com.ncryptedcloud.e-Share.pkg"
|
||||
downloadURL=https://www.ncryptedcloud.com/static/downloads/osx/$(curl -fs https://www.ncryptedcloud.com/static/downloads/osx/ | grep -o -i "href.*\".*\"" | cut -d '"' -f2)
|
||||
versionKey="CFBundleVersion"
|
||||
appNewVersion=$( echo "${downloadURL}" | sed -E 's/.*\/[a-zA-Z\-]*_([0-9.]*)\.pkg/\1/g' )
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
evernote)
|
||||
name="Evernote"
|
||||
type="dmg"
|
||||
downloadURL=$(curl -fs -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15)" "https://evernote.com/download" | grep -i ".dmg" | cut -d '"' -f2)
|
||||
downloadURL=$(curl -fs -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15)" "https://evernote.com/download" | grep -i ".dmg" | grep -ioe "href.*" | cut -d '"' -f2)
|
||||
appNewVersion=$( echo "${downloadURL}" | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)-.*/\1/g' )
|
||||
expectedTeamID="Q79WDW8YH9"
|
||||
appName="Evernote.app"
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
golang)
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
name="GoLang"
|
||||
type="pkg"
|
||||
packageID="org.golang.go"
|
||||
downloadURL="$(curl -fsIL "https://golang.org$(curl -fs "https://golang.org/dl/" | grep -i "downloadBox" | grep "pkg" | tr '"' '\n' | grep "pkg")" | grep -i "^location" | awk '{print $2}' | tr -d '\r\n')"
|
||||
appNewVersion="$( echo "${downloadURL}" | sed -E 's/.*\/(go[0-9.]*)\..*/\1/g' )" # Version includes letters "go"
|
||||
downloadURL="https://go.dev$(curl -fs "https://go.dev/dl/" | grep -i "downloadBox" | grep "pkg" | tr '"' '\n' | grep "pkg")"
|
||||
appNewVersion="$( echo "${downloadURL}" | sed -E 's/.*\/(go[0-9.]*)\..*/\1/g' )" # Version includes letters "go" in the beginning
|
||||
expectedTeamID="EQHXZ8M8AV"
|
||||
blockingProcesses=( NONE )
|
||||
;;
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
logitechoptions)
|
||||
name="Logitech Options"
|
||||
type="pkgInZip"
|
||||
downloadURL=$(curl -fs https://support.logi.com/api/v2/help_center/en-us/articles.json | tr "," "\n" | grep -A 10 "macOS" | grep -oie "https.*/.*/options.*\.zip")
|
||||
appNewVersion=$(curl -fs https://support.logi.com/api/v2/help_center/en-us/articles.json | tr "," "\n" | grep -A 10 "macOS" | grep -B 5 -ie "https.*/.*/options.*\.zip" | grep "Software Version" | sed 's/\\u[0-9a-z][0-9a-z][0-9a-z][0-9a-z]//g' | grep -ioe "Software Version.*[0-9.]*" | tr "/" "\n" | grep -oe "[0-9.]*" | head -1)
|
||||
#downloadURL=$(curl -fs "https://support.logi.com/api/v2/help_center/en-us/articles.json?label_names=webcontent=productdownload,webos=mac-macos-x-11.0" | tr "," "\n" | grep -A 10 "macOS" | grep -oie "https.*/.*/options/.*\.zip" | head -1)
|
||||
downloadURL="https://download01.logi.com/web/ftp/pub/techsupport/options/options_installer.zip"
|
||||
appNewVersion=$(curl -fs "https://support.logi.com/api/v2/help_center/en-us/articles.json?label_names=webcontent=productdownload,webos=mac-macos-x-11.0" | tr "," "\n" | grep -A 10 "macOS" | grep -B 5 -ie "https.*/.*/options/.*\.zip" | grep "Software Version" | sed 's/\\u[0-9a-z][0-9a-z][0-9a-z][0-9a-z]//g' | grep -ioe "Software Version.*[0-9.]*" | tr "/" "\n" | grep -oe "[0-9.]*" | head -1)
|
||||
#pkgName="LogiMgr Installer "*".app/Contents/Resources/LogiMgr.pkg"
|
||||
pkgName=LogiMgr.pkg
|
||||
expectedTeamID="QED4VVPZWA"
|
||||
|
||||
@@ -3,7 +3,7 @@ mattermost)
|
||||
type="dmg"
|
||||
archiveName="mac-universal.dmg"
|
||||
downloadURL=$(downloadURLFromGit mattermost desktop)
|
||||
appNewVersion=$(versionFromGit mattermost desktop )
|
||||
appNewVersion=$(versionFromGit mattermost desktop)
|
||||
expectedTeamID="UQ8HT4Q2XM"
|
||||
Mattermost Helper (Renderer).app app.asar
|
||||
blockingProcesses=( "Mattermost Helper.app" "Mattermost Helper (Renderer).app" "Mattermost Helper (GPU).app" "Mattermost Helper (Plugin).app" )
|
||||
;;
|
||||
|
||||
16
fragments/labels/mochakeyboard.sh
Normal file
16
fragments/labels/mochakeyboard.sh
Normal file
@@ -0,0 +1,16 @@
|
||||
mochakeyboard)
|
||||
name="Mocha Keyboard"
|
||||
type="appInDmgInZip"
|
||||
downloadURL="https://mochasoft.dk/mochakeyboard.dmg.zip"
|
||||
curlOptions=( -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15"
|
||||
-H "accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
|
||||
-H "accept-encoding: gzip, deflate, br"
|
||||
-H "accept-language: en-US,en;q=0.9"
|
||||
-H "sec-fetch-dest: document"
|
||||
-H "sec-fetch-mode: navigate"
|
||||
-H "sec-fetch-user: ?1"
|
||||
-H "sec-gpc: 1"
|
||||
-H "upgrade-insecure-requests: 1" )
|
||||
appNewVersion=""
|
||||
expectedTeamID="RR9F5EPNVW"
|
||||
;;
|
||||
16
fragments/labels/mochatelnet.sh
Normal file
16
fragments/labels/mochatelnet.sh
Normal file
@@ -0,0 +1,16 @@
|
||||
mochatelnet)
|
||||
name="Telnet"
|
||||
type="appInDmgInZip"
|
||||
downloadURL="https://mochasoft.dk/telnet.dmg.zip"
|
||||
curlOptions=( -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15"
|
||||
-H "accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
|
||||
-H "accept-encoding: gzip, deflate, br"
|
||||
-H "accept-language: en-US,en;q=0.9"
|
||||
-H "sec-fetch-dest: document"
|
||||
-H "sec-fetch-mode: navigate"
|
||||
-H "sec-fetch-user: ?1"
|
||||
-H "sec-gpc: 1"
|
||||
-H "upgrade-insecure-requests: 1" )
|
||||
appNewVersion=""
|
||||
expectedTeamID="RR9F5EPNVW"
|
||||
;;
|
||||
16
fragments/labels/mochatn3270.sh
Normal file
16
fragments/labels/mochatn3270.sh
Normal file
@@ -0,0 +1,16 @@
|
||||
mochatn3270)
|
||||
name="TN3270"
|
||||
type="appInDmgInZip"
|
||||
downloadURL="https://mochasoft.dk/tn3270.dmg.zip"
|
||||
curlOptions=( -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15"
|
||||
-H "accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
|
||||
-H "accept-encoding: gzip, deflate, br"
|
||||
-H "accept-language: en-US,en;q=0.9"
|
||||
-H "sec-fetch-dest: document"
|
||||
-H "sec-fetch-mode: navigate"
|
||||
-H "sec-fetch-user: ?1"
|
||||
-H "sec-gpc: 1"
|
||||
-H "upgrade-insecure-requests: 1" )
|
||||
appNewVersion=""
|
||||
expectedTeamID="RR9F5EPNVW"
|
||||
;;
|
||||
16
fragments/labels/mochatn3812.sh
Normal file
16
fragments/labels/mochatn3812.sh
Normal file
@@ -0,0 +1,16 @@
|
||||
mochatn3812)
|
||||
name="TN3812"
|
||||
type="appInDmgInZip"
|
||||
downloadURL="https://mochasoft.dk/tn3812.dmg.zip"
|
||||
curlOptions=( -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15"
|
||||
-H "accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
|
||||
-H "accept-encoding: gzip, deflate, br"
|
||||
-H "accept-language: en-US,en;q=0.9"
|
||||
-H "sec-fetch-dest: document"
|
||||
-H "sec-fetch-mode: navigate"
|
||||
-H "sec-fetch-user: ?1"
|
||||
-H "sec-gpc: 1"
|
||||
-H "upgrade-insecure-requests: 1" )
|
||||
appNewVersion=""
|
||||
expectedTeamID="Frydendal"
|
||||
;;
|
||||
16
fragments/labels/mochatn5250.sh
Normal file
16
fragments/labels/mochatn5250.sh
Normal file
@@ -0,0 +1,16 @@
|
||||
mochatn5250)
|
||||
name="TN5250"
|
||||
type="appInDmgInZip"
|
||||
downloadURL="https://mochasoft.dk/tn5250.dmg.zip"
|
||||
curlOptions=( -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15"
|
||||
-H "accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
|
||||
-H "accept-encoding: gzip, deflate, br"
|
||||
-H "accept-language: en-US,en;q=0.9"
|
||||
-H "sec-fetch-dest: document"
|
||||
-H "sec-fetch-mode: navigate"
|
||||
-H "sec-fetch-user: ?1"
|
||||
-H "sec-gpc: 1"
|
||||
-H "upgrade-insecure-requests: 1" )
|
||||
appNewVersion=""
|
||||
expectedTeamID="RR9F5EPNVW"
|
||||
;;
|
||||
@@ -1,3 +1,4 @@
|
||||
promiseutility|\
|
||||
promiseutilityr)
|
||||
name="Promise Utility"
|
||||
type="pkgInDmg"
|
||||
@@ -2,6 +2,6 @@ tom4aconverter)
|
||||
name="To M4A Converter"
|
||||
type="dmg"
|
||||
downloadURL="https://amvidia.com/downloads/to-m4a-converter-mac.dmg"
|
||||
appNewVersion=curl -sf "https://amvidia.com/to-m4a-converter" | grep -o -E '"softwareVersion":.'"{8}" | sed 's/\"//g' | awk -F ': ' '{print $2}'
|
||||
appNewVersion=$(curl -sf "https://amvidia.com/to-m4a-converter" | grep -o -E '"softwareVersion":.'"{8}" | sed 's/\"//g' | awk -F ': ' '{print $2}')
|
||||
expectedTeamID="F2TH9XX9CJ"
|
||||
;;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
wacomdrivers)
|
||||
name="Wacom Desktop Center"
|
||||
type="pkgInDmg"
|
||||
downloadURL="$(curl -fs https://www.wacom.com/en-us/support/product-support/drivers | grep -e "drivers/mac/professional.*dmg" | head -1 | sed -e 's/data-download-link="//g' -e 's/"//' | awk '{$1=$1}{ print }' | sed 's/\r//')"
|
||||
downloadURL="$(curl -fs https://www.wacom.com/en-us/support/product-support/drivers | grep -e "drivers/mac/professional.*dmg" | head -1 | tr '"' "\n" | grep -i http)"
|
||||
expectedTeamID="EG27766DY7"
|
||||
pkgName="Install Wacom Tablet.pkg"
|
||||
appNewVersion="$(curl -fs https://www.wacom.com/en-us/support/product-support/drivers | grep mac/professional/releasenotes | head -1 | awk -F"|" '{print $1}' | awk -F"Driver" '{print $3}' | sed -e 's/ (.*//g' | tr -d ' ')"
|
||||
#pkgName="Install Wacom Tablet.pkg"
|
||||
appNewVersion="$(curl -fs https://www.wacom.com/en-us/support/product-support/drivers | grep mac/professional/releasenotes | head -1 | tr '"' "\n" | grep -e "Driver [0-9][-0-9.]*" | sed -E 's/Driver ([-0-9.]*).*/\1/g')"
|
||||
;;
|
||||
|
||||
@@ -2,6 +2,7 @@ wallyezflash)
|
||||
name="Wally"
|
||||
type="dmg"
|
||||
downloadURL="https://configure.zsa.io/wally/osx"
|
||||
# 2022-02-07: Info.plist is totally wrong defined and contains no version information
|
||||
#appNewVersion=$(curl -fsIL "${downloadURL}" | grep -i ^location | head -1 | sed -E 's/.*\/[a-zA-Z\-]*-([0-9.]*)\..*/\1/g')
|
||||
expectedTeamID="V32BWKSNYH"
|
||||
#versionKey="CFBundleVersion"
|
||||
|
||||
@@ -15,8 +15,16 @@ fi
|
||||
|
||||
# MARK: application download and installation starts here
|
||||
|
||||
if [[ ${INTERRUPT_DND} = "no" ]]; then
|
||||
# Check if a fullscreen app is active
|
||||
if hasDisplaySleepAssertion; then
|
||||
cleanupAndExit 1 "active display sleep assertion detected, aborting"
|
||||
fi
|
||||
fi
|
||||
|
||||
printlog "BLOCKING_PROCESS_ACTION=${BLOCKING_PROCESS_ACTION}"
|
||||
printlog "NOTIFY=${NOTIFY}"
|
||||
printlog "LOGGING=${LOGGING}"
|
||||
|
||||
# Finding LOGO to use in dialogs
|
||||
case $LOGO in
|
||||
@@ -35,14 +43,17 @@ case $LOGO in
|
||||
mosyleb)
|
||||
# Mosyle Business
|
||||
LOGO="/Applications/Self-Service.app/Contents/Resources/AppIcon.icns"
|
||||
if [[ -z $MDMProfileName ]]; then; MDMProfileName="Mosyle Corporation MDM"; fi
|
||||
;;
|
||||
mosylem)
|
||||
# Mosyle Manager (education)
|
||||
LOGO="/Applications/Manager.app/Contents/Resources/AppIcon.icns"
|
||||
if [[ -z $MDMProfileName ]]; then; MDMProfileName="Mosyle Corporation MDM"; fi
|
||||
;;
|
||||
addigy)
|
||||
# Addigy
|
||||
LOGO="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
|
||||
if [[ -z $MDMProfileName ]]; then; MDMProfileName="MDM Profile"; fi
|
||||
;;
|
||||
esac
|
||||
if [[ ! -a "${LOGO}" ]]; then
|
||||
@@ -54,6 +65,8 @@ if [[ ! -a "${LOGO}" ]]; then
|
||||
fi
|
||||
printlog "LOGO=${LOGO}"
|
||||
|
||||
printlog "Label type: $type"
|
||||
|
||||
# MARK: extract info from data
|
||||
if [ -z "$archiveName" ]; then
|
||||
case $type in
|
||||
@@ -74,6 +87,7 @@ if [ -z "$archiveName" ]; then
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
printlog "archiveName: $archiveName" DEBUG
|
||||
|
||||
if [ -z "$appName" ]; then
|
||||
# when not given derive from name
|
||||
@@ -112,7 +126,7 @@ else
|
||||
fi
|
||||
|
||||
# MARK: change directory to temporary working directory
|
||||
printlog "Changing directory to $tmpDir"
|
||||
printlog "Changing directory to $tmpDir" DEBUG
|
||||
if ! cd "$tmpDir"; then
|
||||
printlog "error changing directory $tmpDir"
|
||||
cleanupAndExit 1
|
||||
@@ -168,8 +182,8 @@ fi
|
||||
if [ -f "$archiveName" ] && [ "$DEBUG" -eq 1 ]; then
|
||||
printlog "$archiveName exists and DEBUG mode 1 enabled, skipping download"
|
||||
else
|
||||
# download the dmg
|
||||
printlog "Downloading $downloadURL to $archiveName"
|
||||
# download
|
||||
printlog "Downloading $downloadURL to $archiveName" REQ
|
||||
if [[ $currentUser != "loginwindow" && $NOTIFY == "all" ]]; then
|
||||
printlog "notifying"
|
||||
if [[ $updateDetected == "YES" ]]; then
|
||||
@@ -178,19 +192,28 @@ else
|
||||
displaynotification "Downloading new $name" "Download in progress …"
|
||||
fi
|
||||
fi
|
||||
if ! curl --location --fail --silent "$downloadURL" -o "$archiveName"; then
|
||||
curlDownload=$(curl -v -fsL --show-error ${curlOptions} "$downloadURL" -o "$archiveName" 2>&1)
|
||||
curlDownloadStatus=$(echo $?)
|
||||
deduplicatelogs "$curlDownload"
|
||||
if [[ $curlDownloadStatus -ne 0 ]]; then
|
||||
#if ! curl --location --fail --silent "$downloadURL" -o "$archiveName"; then
|
||||
printlog "error downloading $downloadURL"
|
||||
message="$name update/installation failed. This will be logged, so IT can follow up."
|
||||
if [[ $currentUser != "loginwindow" && $NOTIFY == "all" ]]; then
|
||||
printlog "notifying"
|
||||
if [[ $updateDetected == "YES" ]]; then
|
||||
displaynotification "$message" "Error updating $name"
|
||||
displaynotification "$message" "Error updating $name" ERROR
|
||||
else
|
||||
displaynotification "$message" "Error installing $name"
|
||||
displaynotification "$message" "Error installing $name" ERROR
|
||||
fi
|
||||
fi
|
||||
cleanupAndExit 2
|
||||
printlog "File list: $(ls -lh "$archiveName")" ERROR
|
||||
printlog "File type: $(file "$archiveName")" ERROR
|
||||
cleanupAndExit 2 "Error downloading $downloadURL error:\n$logoutput" ERROR
|
||||
fi
|
||||
printlog "File list: $(ls -lh "$archiveName")" DEBUG
|
||||
printlog "File type: $(file "$archiveName")" DEBUG
|
||||
printlog "curl output was:\n$logoutput" DEBUG
|
||||
fi
|
||||
|
||||
# MARK: when user is logged in, and app is running, prompt user to quit app
|
||||
@@ -207,7 +230,7 @@ else
|
||||
fi
|
||||
|
||||
# MARK: install the download
|
||||
printlog "Installing $name"
|
||||
printlog "Installing $name" REQ
|
||||
if [[ $currentUser != "loginwindow" && $NOTIFY == "all" ]]; then
|
||||
printlog "notifying"
|
||||
if [[ $updateDetected == "YES" ]]; then
|
||||
@@ -219,7 +242,7 @@ fi
|
||||
|
||||
if [ -n "$installerTool" ]; then
|
||||
# installerTool defined, and we use that for installation
|
||||
printlog "installerTool used: $installerTool"
|
||||
printlog "installerTool used: $installerTool" REQ
|
||||
appName="$installerTool"
|
||||
fi
|
||||
|
||||
|
||||
Reference in New Issue
Block a user