#!/usr/bin/env bash set -euo pipefail [[ "$#" -eq 5 ]] || { echo "usage: build-remote-image.sh HOST PORT USER IMAGE CONTEXT" >&2 exit 2 } host="$1" port="$2" user="$3" image="$4" context="$5" repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" command -v tar >/dev/null 2>&1 || { echo "missing local tar" >&2 exit 1 } [[ "${user}" =~ ^[a-z_][a-z0-9_-]*$ ]] || { echo "unsafe user name: ${user}" >&2 exit 2 } [[ "${image}" =~ ^[A-Za-z0-9._/@:-]+$ ]] || { echo "unsafe image name: ${image}" >&2 exit 2 } [[ -d "${context}" && -f "${context}/Containerfile" ]] || { echo "invalid image context: ${context}" >&2 exit 2 } context="$(cd "${context}" && pwd -P)" git_root="$(git -C "${context}" rev-parse --show-toplevel)" git_prefix="$(git -C "${context}" rev-parse --show-prefix)" git -C "${context}" diff --quiet -- . || { echo "image context has unstaged changes: ${context}" >&2 exit 2 } git -C "${context}" diff --cached --quiet -- . || { echo "image context has staged changes: ${context}" >&2 exit 2 } untracked="$(git -C "${git_root}" ls-files --others --exclude-standard -- "${git_prefix:-.}")" [[ -z "${untracked}" ]] || { echo "image context has untracked files: ${context}" >&2 printf '%s\n' "${untracked}" >&2 exit 2 } treeish="HEAD" if [[ -n "${git_prefix}" ]]; then treeish="HEAD:${git_prefix%/}" fi echo "installing remote image builder on ${host}" remote_builder="/tmp/bugabinga-build-rootless-image.sh" ssh -p "${port}" "root@${host}" "cat > '${remote_builder}' && chmod 700 '${remote_builder}'" <"${repo_root}/scripts/remote/build-rootless-image.sh" sleep 2 cleanup_remote_builder() { ssh -p "${port}" "root@${host}" "rm -f '${remote_builder}'" >/dev/null 2>&1 || true } trap cleanup_remote_builder EXIT echo "building ${image} from tracked ${treeish} files in ${user} rootless podman storage on ${host}" git -C "${git_root}" archive --format=tar "${treeish}" | ssh -p "${port}" "root@${host}" "'${remote_builder}' '${user}' '${image}'" sleep 2 echo "built ${image} on ${host} as ${user}"