Files
OrcaSlicer-bambulab/tools/pjarczak_bambu_runtime/macos/pjarczak_install_macos_runtime.sh
T
2026-05-11 19:29:55 +01:00

246 lines
6.3 KiB
Bash
Executable File

#!/bin/bash
set -euo pipefail
PACKAGE_DIR=""
PLUGIN_DIR=""
PLUGIN_CACHE_DIR=""
REPLACE_EXISTING=0
while [[ $# -gt 0 ]]; do
case "$1" in
-PackageDir)
PACKAGE_DIR="${2:-}"
shift 2
;;
-PluginDir)
PLUGIN_DIR="${2:-}"
shift 2
;;
-PluginCacheDir)
PLUGIN_CACHE_DIR="${2:-}"
shift 2
;;
-ReplaceExisting)
REPLACE_EXISTING=1
shift
;;
*)
echo "unknown argument: $1" >&2
exit 2
;;
esac
done
if [[ -z "$PLUGIN_DIR" ]]; then
PLUGIN_DIR="$PACKAGE_DIR"
fi
if [[ -z "$PLUGIN_DIR" ]]; then
echo "PluginDir is required" >&2
exit 2
fi
APP_SUPPORT_DIR="$HOME/Library/Application Support/OrcaSlicer/macos-bridge"
LOCAL_LIMA_ROOT="$APP_SUPPORT_DIR/lima"
LOCAL_LIMA_BIN="$LOCAL_LIMA_ROOT/bin"
RUNTIME_DIR="${PJARCZAK_MAC_RUNTIME_DIR:-$APP_SUPPORT_DIR/runtime}"
mkdir -p "$APP_SUPPORT_DIR" "$LOCAL_LIMA_ROOT" "$RUNTIME_DIR"
trim_file() {
local path="$1"
if [[ ! -f "$path" ]]; then
return 1
fi
LC_ALL=C tr -d '\r' < "$path" | head -n 1 | sed 's/^[[:space:]]*//;s/[[:space:]]*$//'
}
find_limactl() {
if [[ -n "${PJARCZAK_LIMACTL:-}" && -x "${PJARCZAK_LIMACTL}" ]]; then
printf '%s
' "$PJARCZAK_LIMACTL"
return 0
fi
if command -v limactl >/dev/null 2>&1; then
command -v limactl
return 0
fi
if [[ -x "$LOCAL_LIMA_BIN/limactl" ]]; then
printf '%s
' "$LOCAL_LIMA_BIN/limactl"
return 0
fi
for candidate in /opt/homebrew/bin/limactl /usr/local/bin/limactl; do
if [[ -x "$candidate" ]]; then
printf '%s
' "$candidate"
return 0
fi
done
return 1
}
resolve_lima_version_from_redirect() {
local effective_url=""
effective_url=$(curl -fsSL -o /dev/null -w '%{url_effective}' https://github.com/lima-vm/lima/releases/latest || true)
case "$effective_url" in
*/tag/*)
printf '%s
' "${effective_url##*/}"
return 0
;;
esac
return 1
}
resolve_lima_version() {
if [[ -n "${PJARCZAK_LIMA_VERSION:-}" ]]; then
printf '%s
' "$PJARCZAK_LIMA_VERSION"
return 0
fi
local version=""
version=$(curl -fsSL https://api.github.com/repos/lima-vm/lima/releases/latest | awk -F'"' '/"tag_name"[[:space:]]*:/ { print $4; exit }' || true)
if [[ -n "$version" ]]; then
printf '%s
' "$version"
return 0
fi
resolve_lima_version_from_redirect
}
install_lima_binary_locally() {
local version
version=$(resolve_lima_version)
if [[ -z "$version" ]]; then
echo "failed to resolve latest Lima version from GitHub API" >&2
return 1
fi
local host_arch
host_arch=$(uname -m)
case "$host_arch" in
arm64|aarch64)
host_arch=arm64
;;
x86_64|amd64)
host_arch=x86_64
;;
*)
echo "unsupported macOS architecture for Lima: $host_arch" >&2
return 1
;;
esac
local version_no_v="${version#v}"
local base_url="https://github.com/lima-vm/lima/releases/download/${version}"
local main_archive="lima-${version_no_v}-Darwin-${host_arch}.tar.gz"
local guest_archive="lima-additional-guestagents-${version_no_v}-Darwin-${host_arch}.tar.gz"
local tmpdir
tmpdir=$(mktemp -d)
trap 'rm -rf "$tmpdir"' RETURN
curl -fL --retry 3 --retry-delay 2 "$base_url/$main_archive" -o "$tmpdir/$main_archive"
tar -xzf "$tmpdir/$main_archive" -C "$LOCAL_LIMA_ROOT"
if curl -fL --retry 3 --retry-delay 2 "$base_url/$guest_archive" -o "$tmpdir/$guest_archive"; then
tar -xzf "$tmpdir/$guest_archive" -C "$LOCAL_LIMA_ROOT"
fi
[[ -x "$LOCAL_LIMA_BIN/limactl" ]]
}
ensure_lima_installed() {
LIMACTL=$(find_limactl || true)
if [[ -n "$LIMACTL" ]]; then
return 0
fi
if command -v brew >/dev/null 2>&1; then
brew install lima
LIMACTL=$(find_limactl || true)
if [[ -n "$LIMACTL" ]]; then
return 0
fi
fi
install_lima_binary_locally
LIMACTL=$(find_limactl || true)
[[ -n "$LIMACTL" ]]
}
maybe_install_rosetta() {
if [[ "$(uname -m)" != "arm64" ]]; then
return 0
fi
if pgrep -q oahd >/dev/null 2>&1; then
return 0
fi
/usr/sbin/softwareupdate --install-rosetta --agree-to-license >/dev/null 2>&1 || true
}
copy_runtime_payload() {
local src_dir="$1"
local dst_dir="$2"
local file
local required_files=(
libbambu_networking.so
libBambuSource.so
pjarczak_bambu_linux_host
pjarczak_bambu_linux_host_abi1
pjarczak_bambu_linux_host_abi0
ca-certificates.crt
slicer_base64.cer
)
for file in "${required_files[@]}"; do
if [[ ! -f "$src_dir/$file" ]]; then
echo "missing required runtime payload file: $file" >&2
exit 1
fi
cp -f "$src_dir/$file" "$dst_dir/$file"
done
for file in liblive555.so libagora_rtc_sdk.so libagora-fdkaac.so; do
if [[ -f "$src_dir/$file" ]]; then
cp -f "$src_dir/$file" "$dst_dir/$file"
fi
done
chmod 755 "$dst_dir/pjarczak_bambu_linux_host" "$dst_dir/pjarczak_bambu_linux_host_abi1" "$dst_dir/pjarczak_bambu_linux_host_abi0"
}
INSTANCE="${PJARCZAK_MAC_LIMA_INSTANCE:-}"
if [[ -z "$INSTANCE" ]]; then
INSTANCE=$(trim_file "$PLUGIN_DIR/pjarczak_lima_instance.txt" || true)
fi
if [[ -z "$INSTANCE" ]]; then
INSTANCE="orcaslicer-bambu-network"
fi
copy_runtime_payload "$PLUGIN_DIR" "$RUNTIME_DIR"
ensure_lima_installed
maybe_install_rosetta
START_ARGS=(start "--name=${INSTANCE}" --tty=false --mount-writable)
MACOS_MAJOR=$(sw_vers -productVersion | awk -F. '{print $1}')
if [[ "$MACOS_MAJOR" -ge 13 ]]; then
START_ARGS+=(--vm-type=vz --network=vzNAT)
if [[ "$(uname -m)" == "arm64" ]]; then
START_ARGS+=(--rosetta)
fi
fi
if [[ "$REPLACE_EXISTING" -eq 1 ]]; then
"$LIMACTL" stop "$INSTANCE" >/dev/null 2>&1 || true
fi
if ! "$LIMACTL" shell "$INSTANCE" -- /usr/bin/env true >/dev/null 2>&1; then
"$LIMACTL" "${START_ARGS[@]}" template:default
fi
"$LIMACTL" start-at-login "$INSTANCE" --enabled >/dev/null 2>&1 || true
"$LIMACTL" shell "$INSTANCE" -- /usr/bin/env true >/dev/null
printf 'runtime installed
'