mirror of
https://github.com/dockur/macos.git
synced 2026-03-11 08:34:24 +00:00
feat: Generate unique machine serials (#132)
This commit is contained in:
parent
ddff7a3f92
commit
c6ec08c0b5
5 changed files with 166 additions and 148 deletions
53
Dockerfile
53
Dockerfile
|
|
@ -1,6 +1,21 @@
|
|||
FROM --platform=linux/amd64 debian:trixie-slim AS builder
|
||||
FROM --platform=$BUILDPLATFORM alpine AS builder
|
||||
|
||||
ARG VERSION_OPENCORE="1.0.2"
|
||||
ARG REPO_OPENCORE="https://github.com/acidanthera/OpenCorePkg"
|
||||
ADD $REPO_OPENCORE/releases/download/$VERSION_OPENCORE/OpenCore-$VERSION_OPENCORE-RELEASE.zip /tmp/opencore.zip
|
||||
|
||||
RUN apk --update add unzip && \
|
||||
unzip /tmp/opencore.zip -d /tmp/oc && \
|
||||
cp /tmp/oc/Utilities/macserial/macserial.linux /macserial && \
|
||||
rm -rf /tmp/* /var/tmp/* /var/cache/apk/*
|
||||
|
||||
FROM scratch AS runner
|
||||
COPY --from=qemux/qemu-docker:6.08 / /
|
||||
|
||||
ARG VERSION_ARG="0.0"
|
||||
ARG VERSION_KVM_OPENCORE="v21"
|
||||
ARG VERSION_OSX_KVM="326053dd61f49375d5dfb28ee715d38b04b5cd8e"
|
||||
ARG REPO_OSX_KVM="https://raw.githubusercontent.com/kholia/OSX-KVM"
|
||||
ARG REPO_KVM_OPENCORE="https://github.com/thenickdude/KVM-Opencore"
|
||||
|
||||
ARG DEBCONF_NOWARNINGS="yes"
|
||||
|
|
@ -10,41 +25,17 @@ ARG DEBCONF_NONINTERACTIVE_SEEN="true"
|
|||
RUN set -eu && \
|
||||
apt-get update && \
|
||||
apt-get --no-install-recommends -y install \
|
||||
xxd \
|
||||
fdisk \
|
||||
mtools && \
|
||||
apt-get clean && \
|
||||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
COPY --chmod=755 ./src/build.sh /run
|
||||
COPY --chmod=644 ./config.plist /run
|
||||
|
||||
ADD $REPO_KVM_OPENCORE/releases/download/$VERSION_KVM_OPENCORE/OpenCore-$VERSION_KVM_OPENCORE.iso.gz /tmp/opencore.iso.gz
|
||||
|
||||
RUN gzip -d /tmp/opencore.iso.gz && \
|
||||
run/build.sh /tmp/opencore.iso /run/config.plist && \
|
||||
rm -rf /tmp/*
|
||||
|
||||
FROM scratch AS runner
|
||||
COPY --from=qemux/qemu-docker:6.07 / /
|
||||
|
||||
ARG VERSION_ARG="0.0"
|
||||
ARG VERSION_OSX_KVM="326053dd61f49375d5dfb28ee715d38b04b5cd8e"
|
||||
ARG REPO_OSX_KVM="https://raw.githubusercontent.com/kholia/OSX-KVM"
|
||||
|
||||
ARG DEBCONF_NOWARNINGS="yes"
|
||||
ARG DEBIAN_FRONTEND="noninteractive"
|
||||
ARG DEBCONF_NONINTERACTIVE_SEEN="true"
|
||||
|
||||
RUN set -eu && \
|
||||
apt-get update && \
|
||||
apt-get --no-install-recommends -y install \
|
||||
mtools \
|
||||
python3 && \
|
||||
apt-get clean && \
|
||||
echo "$VERSION_ARG" > /run/version && \
|
||||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
COPY --chmod=755 ./src /run/
|
||||
COPY --chmod=644 --from=builder /images /images
|
||||
COPY --chmod=644 ./config.plist /
|
||||
COPY --chmod=755 --from=builder /macserial /usr/local/bin/
|
||||
|
||||
ADD --chmod=644 \
|
||||
$REPO_OSX_KVM/$VERSION_OSX_KVM/OVMF_CODE.fd \
|
||||
|
|
@ -52,8 +43,10 @@ ADD --chmod=644 \
|
|||
$REPO_OSX_KVM/$VERSION_OSX_KVM/OVMF_VARS-1024x768.fd \
|
||||
$REPO_OSX_KVM/$VERSION_OSX_KVM/OVMF_VARS-1920x1080.fd /usr/share/OVMF/
|
||||
|
||||
EXPOSE 8006 5900
|
||||
ADD $REPO_KVM_OPENCORE/releases/download/$VERSION_KVM_OPENCORE/OpenCore-$VERSION_KVM_OPENCORE.iso.gz /opencore.iso.gz
|
||||
|
||||
VOLUME /storage
|
||||
EXPOSE 8006 5900
|
||||
|
||||
ENV VERSION="13"
|
||||
ENV RAM_SIZE="4G"
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ kubectl apply -f https://raw.githubusercontent.com/dockur/macos/refs/heads/maste
|
|||
|
||||
- Choose `Disk Utility` and then select the largest `Apple Inc. VirtIO Block Media` disk.
|
||||
|
||||
- Click the `Erase` button to format the disk, and give it any recognizable name you like.
|
||||
- Click the `Erase` button to format the disk to APFS, and give it any recognizable name you like.
|
||||
|
||||
- Close the current window and proceed the installation by clicking `Reinstall macOS`.
|
||||
|
||||
|
|
|
|||
127
src/boot.sh
127
src/boot.sh
|
|
@ -2,34 +2,28 @@
|
|||
set -Eeuo pipefail
|
||||
|
||||
# Docker environment variables
|
||||
: "${BOOT_MODE:="full"}" # Boot mode
|
||||
: "${BOOT_MODE:="macos"}" # Boot mode
|
||||
|
||||
BOOT_DESC=""
|
||||
BOOT_OPTS=""
|
||||
SECURE="off"
|
||||
OVMF="/usr/share/OVMF"
|
||||
|
||||
case "${BOOT_MODE,,}" in
|
||||
"full" )
|
||||
case "${HEIGHT,,}" in
|
||||
"1080" )
|
||||
DEST="$PROCESS"
|
||||
BOOT_DESC=" 1920x1080"
|
||||
ROM="OVMF_CODE.fd"
|
||||
VARS="OVMF_VARS-1920x1080.fd"
|
||||
;;
|
||||
"hd" )
|
||||
"768" )
|
||||
DEST="${PROCESS}_hd"
|
||||
BOOT_DESC=" 1024x768"
|
||||
ROM="OVMF_CODE.fd"
|
||||
VARS="OVMF_VARS-1024x768.fd"
|
||||
;;
|
||||
"default" )
|
||||
BOOT_DESC=""
|
||||
*)
|
||||
ROM="OVMF_CODE.fd"
|
||||
VARS="OVMF_VARS.fd"
|
||||
DEST="${PROCESS}_default"
|
||||
;;
|
||||
*)
|
||||
error "Unknown BOOT_MODE, value \"${BOOT_MODE}\" is not recognized!" && exit 33
|
||||
DEST="${PROCESS}_${HEIGHT}"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
|
@ -58,31 +52,104 @@ fi
|
|||
BOOT_OPTS+=" -drive if=pflash,format=raw,readonly=on,file=$DEST.rom"
|
||||
BOOT_OPTS+=" -drive if=pflash,format=raw,file=$DEST.vars"
|
||||
|
||||
# OpenCoreBoot
|
||||
BOOT_DRIVE_ID="OpenCore"
|
||||
BOOT_DRIVE="$STORAGE/boot.img"
|
||||
BOOT_VERSION="$STORAGE/boot.version"
|
||||
BOOT_FILE="/images/OpenCore.img.gz"
|
||||
BOOT_SIZE=$(stat -c%s "$BOOT_FILE")
|
||||
IMG="$STORAGE/boot.img"
|
||||
|
||||
CURRENT_SIZE=""
|
||||
if [ -f "$BOOT_VERSION" ]; then
|
||||
CURRENT_SIZE=$(<"$BOOT_VERSION")
|
||||
fi
|
||||
if [ ! -f "$IMG" ]; then
|
||||
|
||||
if [ "$CURRENT_SIZE" != "$BOOT_SIZE" ]; then
|
||||
rm -f "$BOOT_DRIVE" 2>/dev/null || true
|
||||
fi
|
||||
FILE="OpenCore.img"
|
||||
IMG="/tmp/$FILE"
|
||||
rm -f "$IMG"
|
||||
|
||||
if [ ! -f "$BOOT_DRIVE" ] || [ ! -s "$BOOT_DRIVE" ]; then
|
||||
msg="Extracting boot image"
|
||||
# OpenCoreBoot
|
||||
ISO="/opencore.iso"
|
||||
OUT="/tmp/extract"
|
||||
|
||||
rm -rf "$OUT"
|
||||
mkdir -p "$OUT"
|
||||
|
||||
msg="Building boot image"
|
||||
info "$msg..." && html "$msg..."
|
||||
gzip -dkc "$BOOT_FILE" > "$BOOT_DRIVE"
|
||||
echo "$BOOT_SIZE" > "$BOOT_VERSION"
|
||||
|
||||
[ ! -f "$ISO" ] && gzip -dk "$ISO.gz"
|
||||
|
||||
if [ ! -f "$ISO" ] || [ ! -s "$ISO" ]; then
|
||||
error "Could not find image file \"$ISO\"." && exit 10
|
||||
fi
|
||||
|
||||
START=$(sfdisk -l "$ISO" | grep -i -m 1 "EFI System" | awk '{print $2}')
|
||||
mcopy -bspmQ -i "$ISO@@${START}S" ::EFI "$OUT"
|
||||
|
||||
CFG="$OUT/EFI/OC/config.plist"
|
||||
cp /config.plist "$CFG"
|
||||
|
||||
ROM="${MAC//[^[:alnum:]]/}"
|
||||
ROM="${ROM,,}"
|
||||
BROM=$(echo "$ROM" | xxd -r -p | base64)
|
||||
RESOLUTION="${WIDTH}x${HEIGHT}@32"
|
||||
|
||||
sed -r -i -e 's|<data>m7zhIYfl</data>|<data>'"${BROM}"'</data>|g' "$CFG"
|
||||
sed -r -i -e 's|<string>iMacPro1,1</string>|<string>'"${MODEL}"'</string>|g' "$CFG"
|
||||
sed -r -i -e 's|<string>C02TM2ZBHX87</string>|<string>'"${SN}"'</string>|g' "$CFG"
|
||||
sed -r -i -e 's|<string>C02717306J9JG361M</string>|<string>'"${MLB}"'</string>|g' "$CFG"
|
||||
sed -r -i -e 's|<string>1920x1080@32</string>|<string>'"${RESOLUTION}"'</string>|g' "$CFG"
|
||||
sed -r -i -e 's|<string>007076A6-F2A2-4461-BBE5-BAD019F8025A</string>|<string>'"${UUID}"'</string>|g' "$CFG"
|
||||
|
||||
# Build image
|
||||
|
||||
MB=256
|
||||
CLUSTER=4
|
||||
START=2048
|
||||
SECTOR=512
|
||||
FIRST_LBA=34
|
||||
|
||||
SIZE=$(( MB*1024*1024 ))
|
||||
OFFSET=$(( START*SECTOR ))
|
||||
TOTAL=$(( SIZE-(FIRST_LBA*SECTOR) ))
|
||||
LAST_LBA=$(( TOTAL/SECTOR ))
|
||||
COUNT=$(( LAST_LBA-(START-1) ))
|
||||
|
||||
if ! truncate -s "$SIZE" "$IMG"; then
|
||||
rm -f "$IMG"
|
||||
error "Could not allocate space to create image $IMG ." && exit 11
|
||||
fi
|
||||
|
||||
PART="/tmp/partition.fdisk"
|
||||
|
||||
{ echo "label: gpt"
|
||||
echo "label-id: 1ACB1E00-3B8F-4B2A-86A4-D99ED21DCAEB"
|
||||
echo "device: $FILE"
|
||||
echo "unit: sectors"
|
||||
echo "first-lba: $FIRST_LBA"
|
||||
echo "last-lba: $LAST_LBA"
|
||||
echo "sector-size: $SECTOR"
|
||||
echo ""
|
||||
echo "${FILE}1 : start=$START, size=$COUNT, type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B, uuid=05157F6E-0AE8-4D1A-BEA5-AC172453D02C, name=\"primary\""
|
||||
|
||||
} > "$PART"
|
||||
|
||||
sfdisk -q "$IMG" < "$PART"
|
||||
echo "drive c: file=\"$IMG\" partition=0 offset=$OFFSET" > /etc/mtools.conf
|
||||
|
||||
mformat -F -M "$SECTOR" -c "$CLUSTER" -T "$COUNT" -v "EFI" "C:"
|
||||
mcopy -bspmQ "$OUT/EFI" "C:"
|
||||
|
||||
rm -rf "$OUT"
|
||||
|
||||
if [[ "$DEBUG" == [Yy1]* ]]; then
|
||||
info ""
|
||||
info "Model: $MODEL"
|
||||
info "Rom: $ROM"
|
||||
info "Serial: $SN"
|
||||
info "Board: $MLB"
|
||||
info ""
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
BOOT_DRIVE_ID="OpenCore"
|
||||
|
||||
DISK_OPTS+=" -device virtio-blk-pci,drive=${BOOT_DRIVE_ID},bus=pcie.0,addr=0x5,bootindex=$BOOT_INDEX"
|
||||
DISK_OPTS+=" -drive file=$BOOT_DRIVE,id=$BOOT_DRIVE_ID,format=raw,cache=unsafe,readonly=on,if=none"
|
||||
DISK_OPTS+=" -drive file=$IMG,id=$BOOT_DRIVE_ID,format=raw,cache=unsafe,readonly=on,if=none"
|
||||
|
||||
CPU_VENDOR=$(lscpu | awk '/Vendor ID/{print $3}')
|
||||
DEFAULT_FLAGS="vendor=GenuineIntel,vmware-cpuid-freq=on,-pdpe1gb"
|
||||
|
|
|
|||
77
src/build.sh
77
src/build.sh
|
|
@ -1,77 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
DST="/images"
|
||||
OUT="/tmp/extract"
|
||||
|
||||
rm -rf "$OUT"
|
||||
rm -rf "$DST"
|
||||
|
||||
mkdir -p "$OUT"
|
||||
mkdir -p "$DST"
|
||||
|
||||
echo "Extracting template image..."
|
||||
|
||||
if [ ! -f "$1" ] || [ ! -s "$1" ]; then
|
||||
echo "Could not find image file \"$1\"." && exit 10
|
||||
fi
|
||||
|
||||
START=$(sfdisk -l "$1" | grep -i -m 1 "EFI System" | awk '{print $2}')
|
||||
mcopy -bspmQ -i "$1@@${START}S" ::EFI "$OUT"
|
||||
|
||||
echo "Building OpenCore image..."
|
||||
|
||||
cp "$2" "$OUT/EFI/OC/"
|
||||
|
||||
MB=256
|
||||
CLUSTER=4
|
||||
START=2048
|
||||
SECTOR=512
|
||||
FIRST_LBA=34
|
||||
|
||||
SIZE=$(( MB*1024*1024 ))
|
||||
OFFSET=$(( START*SECTOR ))
|
||||
TOTAL=$(( SIZE-(FIRST_LBA*SECTOR) ))
|
||||
LAST_LBA=$(( TOTAL/SECTOR ))
|
||||
COUNT=$(( LAST_LBA-(START-1) ))
|
||||
|
||||
FILE="OpenCore.img"
|
||||
IMG="/tmp/$FILE"
|
||||
rm -f "$IMG"
|
||||
|
||||
if ! truncate -s "$SIZE" "$IMG"; then
|
||||
rm -f "$IMG"
|
||||
echo "Could not allocate file $IMG for the OpenCore image." && exit 11
|
||||
fi
|
||||
|
||||
PART="/tmp/partition.fdisk"
|
||||
|
||||
{ echo "label: gpt"
|
||||
echo "label-id: 1ACB1E00-3B8F-4B2A-86A4-D99ED21DCAEB"
|
||||
echo "device: $FILE"
|
||||
echo "unit: sectors"
|
||||
echo "first-lba: $FIRST_LBA"
|
||||
echo "last-lba: $LAST_LBA"
|
||||
echo "sector-size: $SECTOR"
|
||||
echo ""
|
||||
echo "${FILE}1 : start=$START, size=$COUNT, type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B, uuid=05157F6E-0AE8-4D1A-BEA5-AC172453D02C, name=\"primary\""
|
||||
|
||||
} > "$PART"
|
||||
|
||||
sfdisk -q "$IMG" < "$PART"
|
||||
|
||||
echo "drive c: file=\"$IMG\" partition=0 offset=$OFFSET" > /etc/mtools.conf
|
||||
|
||||
mformat -F -M "$SECTOR" -c "$CLUSTER" -T "$COUNT" -v "EFI" "C:"
|
||||
|
||||
echo "Copying files to image..."
|
||||
|
||||
mcopy -bspmQ "$OUT/EFI" "C:"
|
||||
rm -rf "$OUT"
|
||||
|
||||
echo "Compressing image..."
|
||||
|
||||
gzip -c "$IMG" > "$DST/$FILE.gz"
|
||||
rm -f "$IMG"
|
||||
|
||||
echo "Finished succesfully!"
|
||||
|
|
@ -3,12 +3,14 @@ set -Eeuo pipefail
|
|||
|
||||
# Docker environment variables
|
||||
|
||||
: "${SN:=""}"
|
||||
: "${MLB:=""}"
|
||||
: "${MAC:=""}"
|
||||
: "${UUID:=""}"
|
||||
: "${MODEL:="iMacPro1,1"}"
|
||||
: "${VERSION:="13"}" # OSX Version
|
||||
: "${SN:=""}" # Device serial
|
||||
: "${MLB:=""}" # Board serial
|
||||
: "${MAC:=""}" # MAC address
|
||||
: "${UUID:=""}" # Unique ID
|
||||
: "${WIDTH:="1920"}" # Horizontal
|
||||
: "${HEIGHT:="1080"}" # Vertical
|
||||
: "${VERSION:="13"}" # OSX Version
|
||||
: "${MODEL:="iMacPro1,1"}" # Device model
|
||||
|
||||
TMP="$STORAGE/tmp"
|
||||
BASE_IMG_ID="InstallMedia"
|
||||
|
|
@ -76,8 +78,9 @@ generateID() {
|
|||
[ -s "$file" ] && UUID=$(<"$file")
|
||||
[ -n "$UUID" ] && return 0
|
||||
|
||||
UUID=$(cat /proc/sys/kernel/random/uuid)
|
||||
echo "${UUID^^}" > "$file"
|
||||
UUID=$(cat /proc/sys/kernel/random/uuid 2> /dev/null || uuidgen --random)
|
||||
UUID="${UUID^^}"
|
||||
echo "$UUID" > "$file"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
|
@ -92,7 +95,35 @@ generateAddress() {
|
|||
|
||||
# Generate Apple MAC address based on Docker container ID in hostname
|
||||
MAC=$(echo "$HOST" | md5sum | sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/00:16:cb:\3:\4:\5/')
|
||||
echo "${MAC^^}" > "$file"
|
||||
MAC="${MAC^^}"
|
||||
echo "$MAC" > "$file"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
generateSerial() {
|
||||
|
||||
local file="$STORAGE/$PROCESS.sn"
|
||||
local file2="$STORAGE/$PROCESS.mlb"
|
||||
|
||||
[ -n "$SN" ] && [ -n "$MLB" ] && return 0
|
||||
[ -s "$file" ] && SN=$(<"$file")
|
||||
[ -s "$file2" ] && MLB=$(<"$file2")
|
||||
[ -n "$SN" ] && [ -n "$MLB" ] && return 0
|
||||
|
||||
# Generate unique serial numbers for machine
|
||||
SN=$(/usr/local/bin/macserial --num 1 --model "${MODEL}" 2>/dev/null)
|
||||
|
||||
SN="${SN##*$'\n'}"
|
||||
[[ "$SN" != *" | "* ]] && error "$SN" && return 1
|
||||
|
||||
MLB=${SN#*|}
|
||||
MLB="${MLB#"${MLB%%[![:space:]]*}"}"
|
||||
SN="${SN%%|*}"
|
||||
SN="${SN%"${SN##*[![:space:]]}"}"
|
||||
|
||||
echo "$SN" > "$file"
|
||||
echo "$MLB" > "$file2"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
|
@ -121,8 +152,12 @@ if ! generateID; then
|
|||
error "Failed to generate UUID!" && exit 35
|
||||
fi
|
||||
|
||||
if ! generateSerial; then
|
||||
error "Failed to generate serialnumber!" && exit 36
|
||||
fi
|
||||
|
||||
if ! generateAddress; then
|
||||
error "Failed to generate MAC address!" && exit 36
|
||||
error "Failed to generate MAC address!" && exit 37
|
||||
fi
|
||||
|
||||
DISK_OPTS="-device virtio-blk-pci,drive=${BASE_IMG_ID},bus=pcie.0,addr=0x6"
|
||||
|
|
|
|||
Loading…
Reference in a new issue