66# Run this with your current directory being the path where this script is located
77
88# Harcoded versions
9- RP_SHA=" 93f3fea5290b761b1c25c15f46f7c76641d94d58 "
10- MP_SHA=" 71c57fcfdf43692adcd41fa7305be08f66bae3e5 "
9+ RP_SHA=" 06b3052afe49c400aa4196f2aada15c0992e3725 "
10+ MP_SHA=" 0fcd47faf0fb2b4e8a0256a77be315a3cb6ab319 "
1111MACOS_VERSION=11 # use 10.9 for non-universal
1212PYTHON_PRERELEASE_VERSION=
1313PYTHON_BASEURL=" https://www.python.org/ftp/python/%s/python-%s${PYTHON_PRERELEASE_VERSION} -macos%s.pkg"
@@ -18,7 +18,6 @@ RP_BINDIR="/tmp/relocatable-python"
1818MP_BINDIR=" /tmp/munki-pkg"
1919CONSOLEUSER=$( /usr/bin/stat -f " %Su" /dev/console)
2020PIPCACHEDIR=" /Users/${CONSOLEUSER} /Library/Caches/pip"
21- # NOTARY_PASS="" # Store as a repo secret
2221XCODE_PATH=" /Applications/Xcode_13.2.1.app"
2322XCODE_NOTARY_PATH=" $XCODE_PATH /Contents/Developer/usr/bin/notarytool"
2423XCODE_STAPLER_PATH=" $XCODE_PATH /Contents/Developer/usr/bin/stapler"
4948 echo " "
5049 echo " recommended"
5150 echo " A python framework with libraries for commonly used tools like autopkg and munki"
52- echo " "
53- echo " opionated"
54- echo " A python framework with libraries for as many macadmin tools as possible"
5551 exit 1
5652fi
5753
58- if [ -n " $3 " ]; then
59- PYTHON_VERSION=$3
54+ if [ -n " $4 " ]; then
55+ PYTHON_VERSION=$4
6056else
61- PYTHON_VERSION=3.9.5
57+ PYTHON_VERSION=3.9.10
6258fi
6359# Set python bin version based on PYTHON_VERSION
6460PYTHON_BIN_VERSION=" ${PYTHON_VERSION% .* } "
6561
66- if [ -n " $4 " ]; then
67- DATE=$4
62+ if [ -n " $5 " ]; then
63+ DATE=$5
6864else
6965 DATE=$( /bin/date -u " +%m%d%Y%H%M%S" )
7066fi
@@ -77,9 +73,6 @@ RP_ZIP="/tmp/relocatable-python.zip"
7773MP_ZIP=" /tmp/munki-pkg.zip"
7874echo " Creating Python Framework - $TYPE "
7975
80- # Setup notary item
81- $XCODE_NOTARY_PATH store-credentials --apple-id " macadmins@cleverdevops.com" --team-id " 9GQZ7KUFR6" --password " $NOTARY_PASS " macadminpython
82-
8376# Create framework path if not present with 777 so sudo is not needed
8477if [ ! -d " ${FRAMEWORKDIR} " ]; then
8578 /usr/bin/sudo /bin/mkdir -m 777 -p " ${FRAMEWORKDIR} "
118111# remove existing Python package folders and recreate
119112if [ -d " $TOOLSDIR /$TYPE " ]; then
120113 /bin/rm -rf " $TOOLSDIR /$TYPE "
121- /bin/mkdir -p " $TOOLSDIR /$TYPE /payload/ ${FRAMEWORKDIR} "
114+ /bin/mkdir -p " $TOOLSDIR /$TYPE /payload${FRAMEWORKDIR} "
122115 /bin/mkdir -p " $TOOLSDIR /$TYPE /payload/usr/local/bin"
123116 /usr/bin/sudo /usr/sbin/chown -R ${CONSOLEUSER} :wheel " $TOOLSDIR /$TYPE "
124117else
125- /bin/mkdir -p " $TOOLSDIR /$TYPE /payload/ ${FRAMEWORKDIR} "
118+ /bin/mkdir -p " $TOOLSDIR /$TYPE /payload${FRAMEWORKDIR} "
126119 /bin/mkdir -p " $TOOLSDIR /$TYPE /payload/usr/local/bin"
127120 /usr/bin/sudo /usr/sbin/chown -R ${CONSOLEUSER} :wheel " $TOOLSDIR /$TYPE "
128121fi
@@ -134,6 +127,7 @@ RP_EXTRACT_BINDIR="${RP_BINDIR}/relocatable-python-${RP_SHA}"
134127--python-version " ${PYTHON_VERSION} " \
135128--os-version " ${MACOS_VERSION} " \
136129--upgrade-pip \
130+ --no-unsign \
137131--pip-requirements " ${TOOLSDIR} /requirements_${TYPE} .txt" \
138132--destination " ${FRAMEWORKDIR} "
139133
145139
146140# move the framework to the Python package folder
147141echo " Moving Python.framework to payload folder"
148- /bin/mv " ${FRAMEWORKDIR} /Python.framework" " $TOOLSDIR /$TYPE /payload/ ${FRAMEWORKDIR} /Python3.framework"
142+ /bin/mv " ${FRAMEWORKDIR} /Python.framework" " $TOOLSDIR /$TYPE /payload${FRAMEWORKDIR} /Python3.framework"
149143
150- # ad-hoc re-sign the framework so it will run on Apple Silicon
151- echo " Adding ad-hoc code signing so the framework will run on Apple Silicon..."
152- /usr/bin/codesign -s - --deep --force --preserve-metadata=identifier,entitlements,flags,runtime " $TOOLSDIR /$TYPE /payload/${FRAMEWORKDIR} /Python3.framework/Versions/${PYTHON_BIN_VERSION} /Resources/Python.app"
153- /usr/bin/codesign -s - --force --preserve-metadata=identifier,entitlements,flags,runtime " $TOOLSDIR /$TYPE /payload/${FRAMEWORKDIR} /Python3.framework/Versions/Current/Python"
154- /usr/bin/find " $TOOLSDIR /$TYPE /payload/${FRAMEWORKDIR} /Python3.framework/Versions/Current/bin/" -type f -perm -u=x -exec /usr/bin/codesign -s - --preserve-metadata=identifier,entitlements,flags,runtime -f {} \;
155- /usr/bin/find " $TOOLSDIR /$TYPE /payload/${FRAMEWORKDIR} /Python3.framework/Versions/Current/lib/" -type f -perm -u=x -exec /usr/bin/codesign -s - --preserve-metadata=identifier,entitlements,flags,runtime -f {} \;
156- /usr/bin/find " $TOOLSDIR /$TYPE /payload/${FRAMEWORKDIR} /Python3.framework/Versions/Current/lib/" -type f -name " *dylib" -exec /usr/bin/codesign -s - --preserve-metadata=identifier,entitlements,flags,runtime -f {} \;
144+ # re-sign the framework so it will run on Apple Silicon
145+ if [ -n " $3 " ]; then
146+ echo " Adding developer id code signing so the framework will run on Apple Silicon..."
147+ /usr/bin/find " $TOOLSDIR /$TYPE /payload${FRAMEWORKDIR} /Python3.framework/Versions/${PYTHON_BIN_VERSION} /bin" -type f -perm -u=x -exec /usr/bin/codesign --sign " $3 " --timestamp --preserve-metadata=identifier,entitlements,flags,runtime -f {} \;
148+ /usr/bin/find " $TOOLSDIR /$TYPE /payload${FRAMEWORKDIR} /Python3.framework/Versions/${PYTHON_BIN_VERSION} /lib" -type f -perm -u=x -exec /usr/bin/codesign --sign " $3 " --timestamp --preserve-metadata=identifier,entitlements,flags,runtime -f {} \;
149+ /usr/bin/find " $TOOLSDIR /$TYPE /payload${FRAMEWORKDIR} /Python3.framework/Versions/${PYTHON_BIN_VERSION} /lib" -type f -name " *dylib" -exec /usr/bin/codesign --sign " $3 " --timestamp --preserve-metadata=identifier,entitlements,flags,runtime -f {} \;
150+ /usr/bin/codesign --sign " $3 " --timestamp --deep --force --preserve-metadata=identifier,entitlements,flags,runtime " $TOOLSDIR /$TYPE /payload${FRAMEWORKDIR} /Python3.framework/Versions/${PYTHON_BIN_VERSION} /Resources/Python.app"
151+ /usr/bin/codesign --sign " $3 " --timestamp --force --preserve-metadata=identifier,entitlements,flags,runtime " $TOOLSDIR /$TYPE /payload${FRAMEWORKDIR} /Python3.framework/Versions/${PYTHON_BIN_VERSION} /Python"
152+ /usr/bin/codesign --sign " $3 " --timestamp --force --preserve-metadata=identifier,entitlements,flags,runtime " $TOOLSDIR /$TYPE /payload${FRAMEWORKDIR} /Python3.framework/Versions/Current/Python"
153+ else
154+ echo " Adding ad-hoc code signing so the framework will run on Apple Silicon..."
155+ /usr/bin/find " $TOOLSDIR /$TYPE /payload${FRAMEWORKDIR} /Python3.framework/Versions/${PYTHON_BIN_VERSION} /bin" -type f -perm -u=x -exec /usr/bin/codesign -s - --preserve-metadata=identifier,entitlements,flags,runtime -f {} \;
156+ /usr/bin/find " $TOOLSDIR /$TYPE /payload${FRAMEWORKDIR} /Python3.framework/Versions/${PYTHON_BIN_VERSION} /lib" -type f -perm -u=x -exec /usr/bin/codesign -s - --preserve-metadata=identifier,entitlements,flags,runtime -f {} \;
157+ /usr/bin/find " $TOOLSDIR /$TYPE /payload${FRAMEWORKDIR} /Python3.framework/Versions/${PYTHON_BIN_VERSION} /lib" -type f -name " *dylib" -exec /usr/bin/codesign -s - --preserve-metadata=identifier,entitlements,flags,runtime -f {} \;
158+ /usr/bin/codesign -s - --deep --force --preserve-metadata=identifier,entitlements,flags,runtime " $TOOLSDIR /$TYPE /payload${FRAMEWORKDIR} /Python3.framework/Versions/${PYTHON_BIN_VERSION} /Resources/Python.app"
159+ /usr/bin/codesign -s - --force --preserve-metadata=identifier,entitlements,flags,runtime " $TOOLSDIR /$TYPE /payload${FRAMEWORKDIR} /Python3.framework/Versions/${PYTHON_BIN_VERSION} /Python"
160+ /usr/bin/codesign -s - --force --preserve-metadata=identifier,entitlements,flags,runtime " $TOOLSDIR /$TYPE /payload${FRAMEWORKDIR} Python3.framework/Versions/Current/Python"
161+ fi
157162
158163# confirm truly universal
159- TOTAL_DYLIB=$( /usr/bin/find " $TOOLSDIR /$TYPE /payload/ ${FRAMEWORKDIR} /Python3.framework/Versions/Current /lib" -name " *.dylib" | /usr/bin/wc -l | /usr/bin/xargs)
160- UNIVERSAL_DYLIB=$( /usr/bin/find " $TOOLSDIR /$TYPE /payload/ ${FRAMEWORKDIR} /Python3.framework/Versions/Current /lib" -name " *.dylib" | /usr/bin/xargs file | /usr/bin/grep " 2 architectures" | /usr/bin/wc -l | /usr/bin/xargs)
164+ TOTAL_DYLIB=$( /usr/bin/find " $TOOLSDIR /$TYPE /payload${FRAMEWORKDIR} /Python3.framework/Versions/${PYTHON_BIN_VERSION} /lib" -name " *.dylib" | /usr/bin/wc -l | /usr/bin/xargs)
165+ UNIVERSAL_DYLIB=$( /usr/bin/find " $TOOLSDIR /$TYPE /payload${FRAMEWORKDIR} /Python3.framework/Versions/${PYTHON_BIN_VERSION} /lib" -name " *.dylib" | /usr/bin/xargs file | /usr/bin/grep " 2 architectures" | /usr/bin/wc -l | /usr/bin/xargs)
161166if [ " ${TOTAL_DYLIB} " != " ${UNIVERSAL_DYLIB} " ] ; then
162167 echo " Dynamic Libraries do not match, resulting in a non-universal Python framework."
163168 echo " Total Dynamic Libraries found: ${TOTAL_DYLIB} "
167172
168173echo " Dynamic Libraries are confirmed as universal"
169174
170- TOTAL_SO=$( /usr/bin/find " $TOOLSDIR /$TYPE /payload/ ${FRAMEWORKDIR} /Python3.framework/Versions/Current /lib" -name " *.so" | /usr/bin/wc -l | /usr/bin/xargs)
171- UNIVERSAL_SO=$( /usr/bin/find " $TOOLSDIR /$TYPE /payload/ ${FRAMEWORKDIR} /Python3.framework/Versions/Current /lib" -name " *.so" | /usr/bin/xargs file | /usr/bin/grep " 2 architectures" | /usr/bin/wc -l | /usr/bin/xargs)
175+ TOTAL_SO=$( /usr/bin/find " $TOOLSDIR /$TYPE /payload${FRAMEWORKDIR} /Python3.framework/Versions/${PYTHON_BIN_VERSION} /lib" -name " *.so" | /usr/bin/wc -l | /usr/bin/xargs)
176+ UNIVERSAL_SO=$( /usr/bin/find " $TOOLSDIR /$TYPE /payload${FRAMEWORKDIR} /Python3.framework/Versions/${PYTHON_BIN_VERSION} /lib" -name " *.so" | /usr/bin/xargs file | /usr/bin/grep " 2 architectures" | /usr/bin/wc -l | /usr/bin/xargs)
172177if [ " ${TOTAL_SO} " != " ${UNIVERSAL_SO} " ] ; then
173178 echo " Shared objects do not match, resulting in a non-universal Python framework."
174179 echo " Total shared objects found: ${TOTAL_SO} "
175180 echo " Universal shared objects found: ${UNIVERSAL_SO} "
176- UNIVERSAL_SO_ARRAY=(" ${(@ f)$(/ usr/ bin/ find " $TOOLSDIR /$TYPE /payload/ ${FRAMEWORKDIR} /Python3.framework/Versions/Current /lib" -name " *.so" | / usr/ bin/ xargs file | / usr/ bin/ grep " 2 architectures" | awk ' {print $1;}' | sed ' s/:*$//g' )} " )
177- TOTAL_SO_ARRAY=(" ${(@ f)$(/ usr/ bin/ find " $TOOLSDIR /$TYPE /payload/ ${FRAMEWORKDIR} /Python3.framework/Versions/Current /lib" -name " *.so" )} " )
181+ UNIVERSAL_SO_ARRAY=(" ${(@ f)$(/ usr/ bin/ find " $TOOLSDIR /$TYPE /payload${FRAMEWORKDIR} /Python3.framework/Versions/${PYTHON_BIN_VERSION} /lib" -name " *.so" | / usr/ bin/ xargs file | / usr/ bin/ grep " 2 architectures" | awk ' {print $1;}' | sed ' s/:*$//g' )} " )
182+ TOTAL_SO_ARRAY=(" ${(@ f)$(/ usr/ bin/ find " $TOOLSDIR /$TYPE /payload${FRAMEWORKDIR} /Python3.framework/Versions/${PYTHON_BIN_VERSION} /lib" -name " *.so" )} " )
178183 echo ${TOTAL_SO_ARRAY[@]} ${UNIVERSAL_SO_ARRAY[@]} | tr ' ' ' \n' | sort | uniq -u
179184 exit 1
180185fi
181186
182187echo " Shared objects are confirmed as universal"
183188
189+ # Print out some information about the signatures
190+ /usr/sbin/spctl -a -vvvv " $TOOLSDIR /$TYPE /payload${FRAMEWORKDIR} /Python3.framework/Versions/${PYTHON_BIN_VERSION} /Python"
191+ /usr/sbin/spctl -a -vvvv " $TOOLSDIR /$TYPE /payload${FRAMEWORKDIR} /Python3.framework/Versions/${PYTHON_BIN_VERSION} /lib/libssl.1.1.dylib"
192+
184193# make a symbolic link to help with interactive use
185194/bin/ln -s " $PYTHON_BIN " " $TOOLSDIR /$TYPE /payload/usr/local/bin/managed_python3"
186195
@@ -237,6 +246,7 @@ if [ -n "$2" ]; then
237246 "version": "$PYTHON_VERSION .$DATE ",
238247 "name": "python_${TYPE} _signed-$PYTHON_VERSION .$DATE .pkg",
239248 "install_location": "/",
249+ "preserve_xattr": true,
240250 "signing_info": {
241251 "identity": "$2 ",
242252 "timestamp": true
@@ -249,10 +259,13 @@ SIGNED_JSONFILE
249259 if [ " ${PKG_RESULT} " != " 0" ]; then
250260 echo " Could not sign package: ${PKG_RESULT} " 1>&2
251261 else
252- # Notarize and staple the package
253- # If these fail, it will bail on the entire process
254- $XCODE_NOTARY_PATH submit " $TOOLSDIR /$TYPE /build/python_${TYPE} _signed-$PYTHON_VERSION .$DATE .pkg" --keychain-profile " macadminpython" --wait
255- $XCODE_STAPLER_PATH staple " $TOOLSDIR /$TYPE /build/python_${TYPE} _signed-$PYTHON_VERSION .$DATE .pkg"
262+ if [ -n " $6 " ]; then
263+ # Notarize and staple the package
264+ $XCODE_NOTARY_PATH store-credentials --apple-id " macadmins@cleverdevops.com" --team-id " 9GQZ7KUFR6" --password " $NOTARY_PASS " macadminpython
265+ # If these fail, it will bail on the entire process
266+ $XCODE_NOTARY_PATH submit " $TOOLSDIR /$TYPE /build/python_${TYPE} _signed-$PYTHON_VERSION .$DATE .pkg" --keychain-profile " macadminpython" --wait
267+ $XCODE_STAPLER_PATH staple " $TOOLSDIR /$TYPE /build/python_${TYPE} _signed-$PYTHON_VERSION .$DATE .pkg"
268+ fi
256269 # Move the signed + notarized pkg
257270 /bin/mv " $TOOLSDIR /$TYPE /build/python_${TYPE} _signed-$PYTHON_VERSION .$DATE .pkg" " $OUTPUTSDIR "
258271 fi
262275
263276# Zip and move the framework
264277ZIPFILE=" Python3.framework_$TYPE -$PYTHON_VERSION .$DATE .zip"
265- /usr/bin/ditto -c -k --sequesterRsrc " $TOOLSDIR /$TYPE /payload/ ${FRAMEWORKDIR} /" ${ZIPFILE}
278+ /usr/bin/ditto -c -k --sequesterRsrc " $TOOLSDIR /$TYPE /payload${FRAMEWORKDIR} /" ${ZIPFILE}
266279/bin/mv ${ZIPFILE} " $OUTPUTSDIR "
267280
268281# Ensure outputs directory is owned by the current user
0 commit comments