-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
179 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
FROM ubuntu:24.04 AS baseos | ||
RUN apt update -y && apt install -y python3 curl xz-utils | ||
FROM ubuntu:24.04 AS bombuilder | ||
RUN apt update -y && apt install -y git build-essential autoconf libxml2-dev libssl-dev zlib1g-dev | ||
RUN git clone "https://github.com/maltob/bomutils.git" /tmp/bomutils | ||
WORKDIR /tmp/bomutils | ||
RUN make | ||
RUN git clone "https://github.com/mackyle/xar.git" /tmp/xar | ||
WORKDIR /tmp/xar/xar | ||
RUN sed -i 's/OpenSSL_add_all_ciphers/OPENSSL_init_crypto/g' configure.ac && ./autogen.sh && make | ||
FROM baseos AS add7z | ||
RUN curl https://www.7-zip.org/a/7z2408-linux-x64.tar.xz -o 7z.tar.xz && tar -xf 7z.tar.xz 7zzs && cp 7zzs /usr/bin/7zzs && chmod +x /usr/bin/7zzs | ||
FROM add7z AS app | ||
COPY --from=bombuilder /tmp/bomutils/build/bin/mkbom /usr/bin/ | ||
COPY --from=bombuilder /tmp/bomutils/build/bin/lsbom /usr/bin/ | ||
COPY --from=bombuilder /tmp/bomutils/build/bin/dumpbom /usr/bin/ | ||
COPY --from=bombuilder /tmp/xar/xar/src/xar /usr/bin/ | ||
RUN mkdir /app | ||
RUN mkdir /out | ||
COPY build_a_pkg.py /app/build_a_pkg.py | ||
WORKDIR /app/ | ||
VOLUME /out | ||
VOLUME /app/input | ||
CMD python /app/build_a_pkg.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
FROM fedora:41 AS baseos | ||
RUN dnf update -y && dnf install -y xar dmg2img hfsplus-tools python3 curl | ||
FROM fedora:41 AS bomBuilder | ||
RUN dnf install -y git make g++ ld automake | ||
RUN git clone "https://github.com/maltob/bomutils.git" /tmp/bomutils | ||
WORKDIR /tmp/bomutils | ||
RUN make | ||
FROM baseos AS add7z | ||
RUN curl https://www.7-zip.org/a/7z2408-linux-x64.tar.xz -o 7z.tar.xz && tar -xf 7z.tar.xz 7zzs && cp 7zzs /usr/bin/7zzs && chmod +x /usr/bin/7zzs | ||
FROM add7z AS app | ||
COPY --from=bomBuilder /tmp/bomutils/build/bin/mkbom /usr/bin/ | ||
COPY --from=bomBuilder /tmp/bomutils/build/bin/lsbom /usr/bin/ | ||
COPY --from=bomBuilder /tmp/bomutils/build/bin/dumpbom /usr/bin/ | ||
RUN mkdir /app | ||
RUN mkdir /out | ||
COPY build_a_pkg.py /app/build_a_pkg.py | ||
WORKDIR /app/ | ||
VOLUME /out | ||
VOLUME /app/input | ||
CMD python /app/build_a_pkg.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
import subprocess | ||
import os | ||
import pathlib | ||
import shutil | ||
import plistlib | ||
from string import Template | ||
import tempfile | ||
|
||
|
||
class MacOSAppInfo: | ||
CFBundleIdentifier: str | ||
CFBundleVersion: str | ||
CFBundleName: str | ||
CFBundleExecutable: str | ||
CFBundleDisplayName: str | ||
LSMinimumSystemVersion: str | ||
|
||
def load_from_info_plist(self,path: str): | ||
with open(path, 'rb') as iplfd: | ||
plist = plistlib.load(iplfd) | ||
if 'CFBundleIdentifier' in plist: | ||
self.CFBundleIdentifier = plist["CFBundleIdentifier"] | ||
if 'CFBundleVersion' in plist: | ||
self.CFBundleVersion = plist["CFBundleVersion"] | ||
if 'CFBundleName' in plist: | ||
self.CFBundleName = plist["CFBundleName"] | ||
if 'CFBundleExecutable' in plist: | ||
self.CFBundleExecutable = plist["CFBundleExecutable"] | ||
if 'CFBundleDisplayName' in plist: | ||
self.CFBundleDisplayName = plist["CFBundleDisplayName"] | ||
if 'LSMinimumSystemVersion' in plist: | ||
self.LSMinimumSystemVersion = plist["LSMinimumSystemVersion"] | ||
|
||
def extract_dmg_app_and_contents(dmg_path: str, destination: str): | ||
with tempfile.TemporaryDirectory("dmg_") as tdir: | ||
convert_result = subprocess.run(['/usr/bin/7zzs', 'x', dmg_path,f"-o{tdir}"],shell=False) | ||
for app in pathlib.Path(tdir).glob("*/*.app"): | ||
shutil.copytree(app.absolute(),destination+"/"+app.name,dirs_exist_ok=True) | ||
for pkg in pathlib.Path(tdir).glob("*/*.pkg"): | ||
shutil.copyfile(pkg.absolute(),destination+"/"+pkg.name) | ||
_input_path = "input" | ||
|
||
#Check if we mapped a volume for working on | ||
if not os.path.isdir(_input_path): | ||
exit(1) | ||
|
||
#Has a dmg - we should mount it and pull the app out | ||
for dmg in pathlib.Path(_input_path).glob("*.dmg"): | ||
dmg_path = dmg.absolute() | ||
extract_dmg_app_and_contents(dmg_path= dmg_path, destination=_input_path) | ||
|
||
has_app: bool = False | ||
for app in pathlib.Path(_input_path).glob("*.app"): | ||
has_app = True | ||
|
||
has_pkg: bool = False | ||
for pkg in pathlib.Path(_input_path).glob("*.pkg"): | ||
shutil.copyfile(pkg.absolute(),f"/out/{pkg.name}") | ||
has_pkg = True | ||
|
||
#If the DMG has a package - we can stop | ||
if has_pkg: | ||
exit(0) | ||
|
||
if not has_app: | ||
print("No app to package!") | ||
exit(1) | ||
|
||
#Package the app | ||
#Root is where we create the payload from | ||
#Flat is where we make the pkg from with root GZ'd into a Payload file | ||
with tempfile.TemporaryDirectory("app_") as _package_base_path: | ||
pathlib.Path(f"{_package_base_path}/flat/Resources/en.lproj").mkdir(parents=True) | ||
pathlib.Path(f"{_package_base_path}/flat/base.pkg").mkdir(parents=True) | ||
pathlib.Path(f"{_package_base_path}/root/Applications").mkdir(parents=True) | ||
|
||
app_name = "ConvertedApp" | ||
appInfo = MacOSAppInfo() | ||
#Copy over all apps | ||
for app in pathlib.Path(_input_path).glob("*.app"): | ||
shutil.copytree(app.absolute(),f"{_package_base_path}/root/Applications/{app.name}") | ||
app_name = app.name | ||
appInfo.load_from_info_plist(f"{_package_base_path}/root/Applications/{app.name}/Contents/Info.plist") | ||
|
||
|
||
identifier = "com.converted."+app_name | ||
|
||
|
||
#Get file counts and size for MacOS to use for progress and estimation of the install size | ||
file_count = 0 | ||
file_size = 0 | ||
for item in pathlib.Path(f"{_package_base_path}/root/").rglob("*"): | ||
if item.is_file() : | ||
file_count+= 1 | ||
file_size += item.stat().st_size | ||
|
||
#Add the metadata | ||
package_info_template_src = '' | ||
with open('templates/PackageInfo.template','r') as pi_file: | ||
package_info_template_src = pi_file.read() | ||
|
||
package_info_template = Template(package_info_template_src) | ||
package_info = package_info_template.substitute(IDENTIFIER=appInfo.CFBundleIdentifier,CFBUNDLE_IDENTIFIER=appInfo.CFBundleIdentifier,INSTALL_KBYTES=int(round(file_size/1024,ndigits=0)),NUMBER_OF_FILES=file_count,CFBUNDLEVERSION=appInfo.CFBundleVersion,PKG_VERSION="1.0",INSTALL_LOCATION="/",APP_PATH=f"./Applications/{app_name}",MIN_OS_VERSION="11.0",APP_NAME=app_name) | ||
|
||
#Make a Distribution file https://developer.apple.com/library/archive/documentation/DeveloperTools/Reference/DistributionDefinitionRef/Chapters/Distribution_XML_Ref.html | ||
distribution_template_src = '' | ||
with open('templates/Distribution.template','r') as di_file: | ||
distribution_template_src = di_file.read() | ||
distribution_template = Template(distribution_template_src) | ||
distribution = distribution_template.substitute(IDENTIFIER=appInfo.CFBundleIdentifier,CFBUNDLE_IDENTIFIER=appInfo.CFBundleIdentifier,INSTALL_KBYTES=int(round(file_size/1024,ndigits=0)),NUMBER_OF_FILES=file_count,CFBUNDLEVERSION=appInfo.CFBundleVersion,PKG_VERSION="1.0",INSTALL_LOCATION="/",APP_PATH=f"./Applications/{app_name}",MIN_OS_VERSION="11.0",APP_NAME=app_name) | ||
|
||
|
||
with open(f"{_package_base_path}/flat/base.pkg/PackageInfo", "w") as pkgInfoFd: | ||
pkgInfoFd.write(package_info) | ||
|
||
|
||
with open(f"{_package_base_path}/flat/Distribution", "w") as distFd: | ||
distFd.write(distribution) | ||
|
||
#Package it up to CPIO and GZIP | ||
subprocess.call(f"( cd {_package_base_path}/root && find . | cpio -o --format odc --owner 0:80 | gzip -c ) > {_package_base_path}/flat/base.pkg/Payload",shell=True) | ||
subprocess.call(f"mkbom -u 0 -g 80 {_package_base_path}/root {_package_base_path}/flat/base.pkg/Bom",shell=True) | ||
subprocess.call(f"cd {_package_base_path}/flat/ && xar --compression none -cf \"/out/{appInfo.CFBundleIdentifier}.pkg\" *",shell=True) | ||
subprocess.call(f"( cd {_package_base_path} && pwd )",shell=True) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#assumes ubuntu:24.04 | ||
|
||
apt update -y && apt install -y python3 curl xz-utils git build-essential autoconf libxml2-dev libssl-dev zlib1g-dev | ||
curl https://www.7-zip.org/a/7z2408-linux-x64.tar.xz -o 7z.tar.xz && tar -xf 7z.tar.xz 7zzs && cp 7zzs /usr/bin/7zzs && chmod +x /usr/bin/7zzs | ||
git clone "https://github.com/maltob/bomutils.git" /tmp/bomutils | ||
git clone "https://github.com/mackyle/xar.git" /tmp/xar | ||
cd /tmp/bomutils/ | ||
make && make install | ||
cd /tmp/xar/xar | ||
sed -i 's/OpenSSL_add_all_ciphers/OPENSSL_init_crypto/g' configure.ac && ./autogen.sh && make && make install |