Skip to content

Instantly share code, notes, and snippets.

@talkingmoose

talkingmoose/MegaPKGr.zsh

Last active Nov 17, 2020
Embed
What would you like to do?
The pkgbuild binary and Jamf Composer don't support adding single files of 8 GB or more to a package. Some apps like Install macOS Big Sur.app include files larger than 8 GB in their bundles. This script will create a deployable PKG file from apps whose bundles include those large files.
#!/bin/zsh
:<<ABOUT_THIS_SCRIPT
-------------------------------------------------------------------------------
Written by:William Smith
Professional Services Engineer
Jamf
bill@talkingmoose.net
https://gist.github.com/e9ed319226c6da30dd633725e48a97b0
Originally posted: October 15, 2020
Purpose: Creates a deployable PKG file from an app whose app bundle
contains one or more files larger than the 8 GB limit supported by pkgbuild
or Jamf Composer.
Instructions:
1. Save the script to a file named MegaPKGr.zsh on your Mac.
2. If necessary, run 'chmod +x /path/to/MegaPKGr.zsh' to make it execu-
table.
3. To run the script, open Terminal and enter:
/path/to/MegaPKGr.zsh /path/to/large.app
Except where otherwise noted, this work is licensed under
http://creativecommons.org/licenses/by/4.0/
"If you try to save wisdom until the world is wise, Father,
the world will never have it."
-------------------------------------------------------------------------------
ABOUT_THIS_SCRIPT
function logmessage() {
echo -ne "$1\r"
/bin/sleep 1
}
function logresult() {
if [ $? = 0 ] ; then
echo "$1"
/bin/date "+%Y-%m-%d %H:%M:%S $1" >> "$logFile"
/bin/sleep 1
else
echo "$2"
/bin/date "+%Y-%m-%d %H:%M:%S $2" >> "$logFile"
echo "Aborting script"
/bin/date "+%Y-%m-%d %H:%M:%S Aborting script" >> "$logFile"
cleanup
exit 1
fi
}
function cleanup() {
logmessage "Removing temporary items..."
/bin/rm -Rf "$tempDirectory"
logresult "Succeeded removing temporary items" "Failed removing temporary items"
}
# need to run this script with elevated privileges
if [ $EUID -ne 0 ]; then
echo
echo "This script requires elevated privileges. Run it again with \"sudo\"."
echo
exit 0
fi
# define log file location
logFile="/Library/Logs/MegaPKGr.log"
# choose app for packaging
appPath="$1"
while [[ "$appPath" = "" ]]
do
echo
echo "Drag the app for packaging into this Terminal window and press return."
echo "To abort this script, press Control-C."
echo
read -p "App path: " appPath
done
app=$( /usr/bin/basename "$appPath" )
echo
# the time right now
startTime=$( /bin/date '+%s' )
# verify disk space needed to package app
appSize=$( /usr/bin/du -md 0 "$appPath" | /usr/bin/awk '{ print $1 }' )
logmessage "Size of \"$app\" in MB: $appSize"
availableSpace=$( /bin/df -g /System/Volumes/Data | /usr/bin/grep dev | /usr/bin/awk '{ print $4 }' )
logmessage "Available disk space: $availableSpace GB "
neededSpace=$(( appSize * 3 / 1024 ))
logmessage "Disk space required to build package: $neededSpace GB "
[ $availableSpace -gt $neededSpace ]
logresult "Disk has enough free space to build \"$app.pkg\"" "Disk does not have enough free space to build \"$app.pkg\""
echo "Log file is located in /Library/Logs/MegaPKGr.log"
echo
# create temporary working directory
logmessage "Creating temporary working directory..."
tempDirectory=$( /usr/bin/mktemp -d "/private/tmp/MegaPKGr.XXXXXX" )
logresult "Succeeded creating temporary working directory" "Failed creating temporary working directory"
# create dmg from the app to create a single file
logmessage "Creating disk image (DMG) archive of \"$app\"..."
/usr/bin/hdiutil create -quiet "$tempDirectory/$app.dmg" -ov -volname MegaPKGr -fs APFS -srcfolder "$appPath"
logresult "Succeeded creating DMG archive of $app" "Failed creating DMG archive of $app"
# create folder structure for pkgbuild
logmessage "Ceating pkgbuild ROOT directory..."
/bin/mkdir -p "$tempDirectory/ROOT/private/tmp/MegaPKGrFileParts" && cd "$tempDirectory/ROOT/private/tmp/MegaPKGrFileParts"
logresult "Succeeded creating pkgbuild ROOT directory" "Failed creating pkgbuild ROOT directory"
logmessage "Creating pkgbuild Scripts directory"
/bin/mkdir -p "$tempDirectory/Scripts"
logresult "Succeeded creating pkgbuild Scripts directory" "Failed creating pkgbuild Scripts directory"
# split archive file into 500 MB file chunks
logmessage "Creating 500 MB file chunks from archive file..."
/usr/bin/split -b 500m "$tempDirectory/$app.dmg"
logresult "Succeeded creating 500 MB file chunks from archive file" "Failed creating 500 MB file chunks from archive file"
# create postinstall script for pkgbuild
logmessage "Creating pkgbuild postinstall script..."
/bin/cat << 'EOF' > "$tempDirectory/Scripts/postinstall"
#!/bin/bash
function logresult() {
if [ $? = 0 ] ; then
echo "$1"
else
echo "$2"
exit 1
fi
}
function cleanup() {
/bin/rm -Rf "$tempDirectory/" "/private/tmp/MegaPKGr"*
logresult "[RESULT: $?] Succeeded removing temporary items" "[ERROR: $?] Failed removing temporary items"
}
# create temporary working directory
echo "Creating temporary working directory"
tempDirectory=$( /usr/bin/mktemp -d "/private/tmp/MegaPKGr.XXXXXX" )
logresult "[RESULT: $?] Succeeded creating temporary working directory" "[ERROR: $?] Failed creating temporary working directory"
# change directory to temporary working directory
echo "Changing directory to working directory '$tempDirectory'"
cd "$tempDirectory"
logresult "[RESULT: $?] Succeeded changing to temporary working directory" "[ERROR: $?] Failed changing to temporary working directory"
# recombine file parts
echo "Recombining file parts"
/bin/cat /private/tmp/MegaPKGrFileParts/xa* > "$tempDirectory/MegaPKGrFileParts.dmg"
logresult "[RESULT: $?] Succeeded recombining MegaPKGrFileParts file parts" "[ERROR: $?] Failed recombining MegaPKGrFileParts file parts"
# copy the application to original location
echo "Extracting archived file"
# mounting recombined DMG
/usr/bin/hdiutil attach -nobrowse "$tempDirectory/MegaPKGrFileParts.dmg"
logresult "[RESULT: $?] Succeeded mounting DMG" "[ERROR: $?] Failed mounting DMG"
# dittoing DMG contents to local disk
/usr/bin/ditto -rsrc "/Volumes/MegaPKGr/" /Applications
logresult "[RESULT: $?] Succeeded dittoing files to specified location" "[ERROR: $?] Failed dittoing files to specified location"
# unmounting recombined DMG
/sbin/umount "/Volumes/MegaPKGr"
logresult "[RESULT: $?] Succeeded unmounting DMG" "[ERROR: $?] Failed unmounting DMG"
# delete temporary files
echo "Deleting temporary items"
cleanup
exit 0
EOF
/bin/chmod +x "$tempDirectory/Scripts/postinstall"
logresult "Succeeded creating pkgbuild postinstall script" "Failed creating pkgbuild postinstall script"
# create installer package
currentDirectory=$( /usr/bin/dirname "$0" )
logmessage "Creating package \"$app.pkg\"..."
/usr/bin/pkgbuild --quiet --identifier net.talkingmoose.MegaPKGr --version "1.0.0" --scripts "$tempDirectory/Scripts" --root "$tempDirectory/ROOT" "$currentDirectory/$app.pkg"
logresult "Succeeded creating package \"$app.pkg\" in the same folder as this script" "Failed creating package \"$app.pkg\" in the same folder as this script"
# remove temporary files
logmessage "Removing temporary items..."
cleanup
echo
# calculate and report script run time
stopTime=$( /bin/date '+%s' )
seconds=$(( $stopTime-$startTime ))
formattedTime=$( /bin/date -j -f "%s" "$seconds" '+%M minutes and %S seconds' )
logresult "Packaging time: $formattedTime"
echo
exit 0
@dev-yeet

This comment has been minimized.

Copy link

@dev-yeet dev-yeet commented Oct 23, 2020

fyi for anyone else that can't read like me /path/to/MegaPKGr.zsh actually means /path/to/MegaPKGr.zsh

./MegaPKGr.zsh will run but the script, but will not dump the package in the same directory (or anywhere from what I can tell)

great script, and thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.