diff options
Diffstat (limited to 'packaging/macos/jhb/usr/bin/archive')
-rwxr-xr-x | packaging/macos/jhb/usr/bin/archive | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/packaging/macos/jhb/usr/bin/archive b/packaging/macos/jhb/usr/bin/archive new file mode 100755 index 0000000..f84f0c8 --- /dev/null +++ b/packaging/macos/jhb/usr/bin/archive @@ -0,0 +1,205 @@ +#!/usr/bin/env bash +# +# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de> +# +# SPDX-License-Identifier: GPL-2.0-or-later + +### description ################################################################ + +# This is a helper to create release archives and mount them. + +### shellcheck ################################################################# + +# Nothing here. + +### dependencies ############################################################### + +#------------------------------------------------------ source jhb configuration + +source "$(dirname "${BASH_SOURCE[0]}")"/../../etc/jhb.conf.sh + +#------------------------------------------- source common functions from bash_d + +# bash_d is already available (it's part of jhb configuration) + +bash_d_include error + +### variables ################################################################## + +# Nothing here. + +### functions ################################################################## + +function create_tar +{ + local file=$ARTIFACT_DIR/$RELEASE_ARCHIVE + + echo_i "creating $file" + + tar -C "$WRK_DIR" -cp "$(basename "$VER_DIR")" | + XZ_OPT=-T0 "$BIN_DIR"/xz > "$file" + + shasum -a 256 "$file" > "$file".sha256 + cat "$file".sha256 +} + +function create_dmg +{ + local file=$ARTIFACT_DIR/$RELEASE_ARCHIVE + + ( # create dmg + local vol_name + vol_name=$(basename "$VER_DIR") + + cd "$WRK_DIR" || exit 1 + hdiutil create -fs HFS+ -ov -format UDBZ \ + -srcfolder "$vol_name" \ + -volname "$vol_name" \ + "$file" + ) + + ( # create and print checksum + cd "$(dirname "$file")" || exit 1 + shasum -a 256 "$(basename "$file")" > "$file".sha256 + cat "$file".sha256 + ) +} + +function mount_dmg +{ + local file=$REP_DIR/$RELEASE_ARCHIVE + local mountpoint=$VER_DIR + + if [ ! -d "$mountpoint" ]; then + mkdir -p "$mountpoint" + fi + + echo_i "mounting $(basename "$file") may take some time" + local device + device=$(hdiutil attach -nomount "$file" | grep "^/dev/disk" | + grep "Apple_HFS" | awk '{ print $1 }') + echo_i "$file attached to $device" + mount -o nobrowse,noowners,noquarantine,ro -t hfs "$device" "$mountpoint" + echo_i "$device mounted to $mountpoint" +} + +function unmount_dmg +{ + local mountpoint=$VER_DIR + + while : ; do # unmount everything (in reverse order) + local disk + disk=$(mount | grep "$mountpoint" | tail -n1 | awk '{ print $1 }') + disk=${disk%s[0-9]} # cut off slice specification + + if [ ${#disk} -eq 0 ]; then + break # nothing to do here + else + # We loop over the 'eject' since it occasionally timeouts. + while ! diskutil eject "$disk" > /dev/null; do + echo_w "retrying to eject $disk in 5 seconds" + sleep 5 + done + + echo_i "ejected $disk" + fi + done +} + +function download_dmg +{ + if [ ! -d "$REP_DIR" ]; then + mkdir -p "$REP_DIR" + fi + + for url in "${RELEASE_URLS[@]}"; do + local partial_download=$REP_DIR/${FUNCNAME[0]} # TMP_DIR not available yet + # download (at least) 100 kb of data + curl -L "$url" 2>/dev/null | head -c 100000 > "$partial_download" + # if we got 100 kb, it's not a "404 file not found" + if [ "$(stat -f%z "$partial_download")" -eq 100000 ]; then + echo_i "downloading $url" + curl -o "$REP_DIR/$RELEASE_ARCHIVE" -L -C - "$url" + break + fi + done + + rm "$partial_download" +} + +function install_dmg +{ + local overlay_size=${1:-1} # unit GiB, default 1 + + local file=$REP_DIR/$RELEASE_ARCHIVE + + # download and mount read-only disk image + if [ -f "$file" ]; then + echo_i "using $file" + else + download_dmg + fi + mount_dmg + + # create writable overlay + local device + device=$(hdiutil attach -nomount ram://$((overlay_size * 1024 * 2048)) | xargs) + newfs_hfs -v "$RELEASE_OVERLAY" "$device" >/dev/null + echo_i "$overlay_size GiB ram attached to $device" + mount -o nobrowse,rw,union -t hfs "$device" "$VER_DIR" + echo_i "$device union-mounted at $VER_DIR" + + # Sadly, there are some limitations involved with union-mounting: + # - Files are not visible to macOS' versions of 'ls' or 'find'. + # (The GNU versions do work though.) + # - You cannot write in a location without having written to its + # parent location first. That's why we need to pre-create all directories + # below. + # + # (Shadow-mounting a dmg is not a feasible alternative due to its + # bad write-performance.) + + # Create and run a script for mass-creating directories. + echo_i "setting up directories in overlay" + gfind "$VER_DIR" -mindepth 1 -type d \ + ! -path "$BLD_DIR/*" ! -path "$SRC_DIR/*" \ + -exec echo "mkdir {}" \; > "$VER_DIR"/create_dirs.sh + chmod 755 "$VER_DIR"/create_dirs.sh + "$VER_DIR"/create_dirs.sh + rm "$VER_DIR"/create_dirs.sh +} + +function uninstall_dmg +{ + unmount_dmg +} + +function main +{ + local command=$1 + local option=$2 + + case "$command" in + create_dmg) + create_dmg + ;; + create_tar) + create_tar + ;; + install_dmg) + install_dmg "$option" # option: overlay size in GiB, defaul is 1 + ;; + uninstall_dmg) + uninstall_dmg + ;; + *) + echo_e "usage: $0 {create_dmg|create_tar|install_dmg|uninstall_dmg}" + ;; + esac +} + +### main ####################################################################### + +error_trace_enable + +main "$@" |