#!/usr/bin/env bash # # SPDX-FileCopyrightText: 2021 René de Hesselle # # 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 "$@"