Luigit
repositories / bugabinga.net

bugabinga.net

personal infrastructure for bugabinga!

owned by admin

scripts/local/build-remote-image.sh

Raw
#!/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}"