first "working" implementation of pkg support

This commit is contained in:
Armin Briegel
2020-03-10 10:55:51 +01:00
parent 37b19fd089
commit 7a59d2fac1

View File

@@ -31,31 +31,31 @@ fi
# #
# the team ID is the ten-digit ID at the end of the line starting with 'origin=' # the team ID is the ten-digit ID at the end of the line starting with 'origin='
# #
# - dmgName: (optional) # - archiveName: (optional)
# The name of the downloaded dmg # The name of the downloaded dmg
# When not given the dmgName is derived from the last part of the downloadURL # When not given the archiveName is derived from the last part of the downloadURL
# #
# - appName: (optional) # - appName: (optional)
# file name of the app bundle in the dmg to verify and copy (include .app) # file name of the app bundle in the dmg to verify and copy (include .app)
# When not given, the App name is derived from the dmgName by removing the extension # When not given, the App name is derived from the archiveName by removing the extension
# and adding .app # and adding .app
# #
# - targetDir: (optional) # - targetDir: (optional)
# Applications will be copied to this directory, remember to omit trailing '/' # Applications will be copied to this directory, remember to omit trailing '/'
# default value is '/Applications' # default value is '/Applications' for dmg and zip installations
# for pkgs default targetDir is "/"
targetDir="/Applications"
# todos: # todos:
# TODO: add pkg support # TODO: add pkg support
# TODO: add zip support
# TODO: check for running processes and either abort or prompt user # TODO: check for running processes and either abort or prompt user
# TODO: log version of installed software # TODO: log version of installed software
# TODO: notification when done # TODO: notification when done
# functions to help with getting info # functions to help with getting info
# will get the latest release download from a github repo
downloadURLFromGit() { # $1 git user name, $2 git repo name downloadURLFromGit() { # $1 git user name, $2 git repo name
gitusername=${1?:"no git user name"} gitusername=${1?:"no git user name"}
gitreponame=${2?:"no git repo name"} gitreponame=${2?:"no git repo name"}
@@ -89,13 +89,17 @@ case $identifier in
;; ;;
Firefox) Firefox)
downloadURL="https://download.mozilla.org/?product=firefox-latest&os=osx&lang=en-US" downloadURL="https://download.mozilla.org/?product=firefox-latest&os=osx&lang=en-US"
dmgName="Firefox.dmg" archiveName="Firefox.dmg"
expectedTeamID="43AQ936H96" expectedTeamID="43AQ936H96"
;; ;;
WhatsApp) WhatsApp)
downloadURL="https://web.whatsapp.com/desktop/mac/files/WhatsApp.dmg" downloadURL="https://web.whatsapp.com/desktop/mac/files/WhatsApp.dmg"
expectedTeamID="57T9237FN3" expectedTeamID="57T9237FN3"
;; ;;
desktoppr)
downloadURL=$(downloadURLFromGit "scriptingosx" "desktoppr")
expectedTeamID="JME5BW3F3R"
;;
# these identifiers exist for testing # these identifiers exist for testing
brokenDownloadURL) brokenDownloadURL)
@@ -120,14 +124,7 @@ case $identifier in
;; ;;
esac esac
if [ -z "$dmgName" ]; then # functions
dmgName="${downloadURL##*/}"
fi
if [ -z "$appName" ]; then
appName="${dmgName%%.*}.app"
fi
cleanupAndExit() { # $1 = exit code cleanupAndExit() { # $1 = exit code
if [ "$DEBUG" -eq 0 ]; then if [ "$DEBUG" -eq 0 ]; then
# remove the temporary working directory when done # remove the temporary working directory when done
@@ -145,6 +142,140 @@ cleanupAndExit() { # $1 = exit code
exit "$1" exit "$1"
} }
installFromDMG() {
# mount the dmg
echo "Mounting $tmpDir/$archiveName"
# set -o pipefail
if ! dmgmount=$(hdiutil attach "$tmpDir/$archiveName" -nobrowse -readonly | tail -n 1 | cut -c 54- ); then
echo "Error mounting $tmpDir/$archiveName"
cleanupAndExit 3
fi
echo "Mounted: $dmgmount"
# check if app exists
if [ ! -e "$dmgmount/$appName" ]; then
echo "could not find: $dmgmount/$appName"
cleanupAndExit 8
fi
# verify with spctl
echo "Verifying: $dmgmount/$appName"
if ! teamID=$(spctl -a -vv "$dmgmount/$appName" 2>&1 | awk '/origin=/ {print $NF }' ); then
echo "Error verifying $dmgmount/$appName"
cleanupAndExit 4
fi
echo "Team ID: $teamID (expected: $expectedTeamID )"
if [ "($expectedTeamID)" != "$teamID" ]; then
echo "Team IDs do not match!"
cleanupAndExit 5
fi
# check for root
if [ "$(whoami)" != "root" ]; then
# not running as root
if [ "$DEBUG" -eq 0 ]; then
echo "not running as root, exiting"
cleanupAndExit 6
fi
echo "DEBUG enabled, skipping copy and chown steps"
return 0
fi
# remove existing application
if [ -e "$targetDir/$appName" ]; then
echo "Removing existing $targetDir/$appName"
rm -Rf "$targetDir/$appName"
fi
# copy app to /Applications
echo "Copy $dmgmount/$appName to $targetDir"
if ! ditto "$dmgmount/$appName" "$targetDir"; then
echo "Error while copying!"
cleanupAndExit 7
fi
# set ownership to current user
currentUser=$( echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ && ! /loginwindow/ { print $3 }' )
if [ -n "$currentUser" ]; then
echo "Changing owner to $currentUser"
chown -R "$currentUser" "$targetDir/$appName"
else
echo "No user logged in, not changing user"
fi
}
installFromPKG() {
# verify with spctl
echo "Verifying: $archiveName"
if ! teamID=$(spctl -a -vv -t install "$archiveName" 2>&1 | awk '/origin=/ {print $NF }' ); then
echo "Error verifying $archiveName"
cleanupAndExit 4
fi
echo "Team ID: $teamID (expected: $expectedTeamID )"
if [ "($expectedTeamID)" != "$teamID" ]; then
echo "Team IDs do not match!"
cleanupAndExit 5
fi
# check for root
if [ "$(whoami)" != "root" ]; then
# not running as root
if [ "$DEBUG" -eq 0 ]; then
echo "not running as root, exiting"
cleanupAndExit 6
fi
echo "DEBUG enabled, skipping installation"
return 0
fi
# install pkg
echo "Installing $archiveName to $targetDir"
if ! installer -pkg "$archiveName" -tgt "$targetDir" ; then
echo "error installing $archiveName"
cleanupAndExit 9
fi
}
# main
# extract info from data
if [ -z "$archiveName" ]; then
# when not given use last element of URL
archiveName="${downloadURL##*/}"
fi
if [ -z "$type" ]; then
# when not given use extension of archiveName
type="${archiveName##*.}"
fi
if [ -z "$appName" ]; then
# when not given derive from archiveName
appName="${archiveName%.*}.app"
fi
if [ -z "$targetDir" ]; then
case $type in
dmg)
targetDir="/Applications"
;;
pkg)
targetDir="/"
;;
*)
echo "Cannot handle type $type"
cleanupAndExit 99
;;
esac
fi
# create temporary working directory # create temporary working directory
tmpDir=$(mktemp -d ) tmpDir=$(mktemp -d )
if [ "$DEBUG" -eq 1 ]; then if [ "$DEBUG" -eq 1 ]; then
@@ -162,80 +293,30 @@ fi
# TODO: when user is logged in, and app is running, prompt user to quit app # TODO: when user is logged in, and app is running, prompt user to quit app
if [ -f "$dmgName" ] && [ "$DEBUG" -eq 1 ]; then if [ -f "$archiveName" ] && [ "$DEBUG" -eq 1 ]; then
echo "$dmgName exists and DEBUG enabled, skipping download" echo "$archiveName exists and DEBUG enabled, skipping download"
else else
# download the dmg # download the dmg
echo "Downloading $downloadURL to $dmgName" echo "Downloading $downloadURL to $archiveName"
if ! curl --location --fail --silent "$downloadURL" -o "$dmgName"; then if ! curl --location --fail --silent "$downloadURL" -o "$archiveName"; then
echo "error downloading $downloadURL" echo "error downloading $downloadURL"
cleanupAndExit 2 cleanupAndExit 2
fi fi
fi fi
# mount the dmg case $type in
echo "Mounting $tmpDir/$dmgName" dmg)
# set -o pipefail installFromDMG
if ! dmgmount=$(hdiutil attach "$tmpDir/$dmgName" -nobrowse -readonly | tail -n 1 | cut -c 54- ); then ;;
echo "Error mounting $tmpDir/$dmgName" pkg)
cleanupAndExit 3 installFromPKG
fi ;;
echo "Mounted: $dmgmount" *)
echo "Cannot handle type $type"
cleanupAndExit 99
;;
esac
# check if app exists
if [ ! -e "$dmgmount/$appName" ]; then
echo "could not find: $dmgmount/$appName"
cleanupAndExit 8
fi
# verify with spctl
echo "Verifying: $dmgmount/$appName"
if ! teamID=$(spctl -a -vv "$dmgmount/$appName" 2>&1 | awk '/origin=/ {print $NF }' ); then
echo "Error verifying $dmgmount/$appName"
cleanupAndExit 4
fi
echo "Team ID: $teamID (expected: $expectedTeamID )"
if [ "($expectedTeamID)" != "$teamID" ]; then
echo "Team IDs do not match!"
cleanupAndExit 5
fi
# check for root
if [ "$(whoami)" != "root" ]; then
# not running as root
if [ "$DEBUG" -eq 0 ]; then
echo "not running as root, exiting"
cleanupAndExit 6
fi
echo "DEBUG enabled, skipping copy and chown steps"
cleanupAndExit 0
fi
# remove existing application
if [ -e "$targetDir/$appName" ]; then
echo "Removing existing $targetDir/$appName"
rm -Rf "$targetDir/$appName"
fi
# copy app to /Applications
echo "Copy $dmgmount/$appName to $targetDir"
if ! ditto "$dmgmount/$appName" "$targetDir"; then
echo "Error while copying!"
cleanupAndExit 7
fi
# set ownership to current user
currentUser=$( echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ && ! /loginwindow/ { print $3 }' )
if [ -n "$currentUser" ]; then
echo "Changing owner to $currentUser"
chown -R "$currentUser" "$targetDir/$appName"
else
echo "No user logged in, not changing user"
fi
# TODO: notify when done # TODO: notify when done