#!/usr/bin/env bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REGISTRY_TOOL="${SCRIPT_DIR}/instance-registry.py" REGISTRY_PATH_DEFAULT="${SCRIPT_DIR}/runtime/registry/instances.json" INSTANCE_ID="" INSTANCE_SLUG="" CONTAINER_NAME="" REGISTRY_PATH="${REGISTRY_PATH:-$REGISTRY_PATH_DEFAULT}" PURGE_DATA=0 usage() { cat <<'EOF' Usage: ./remove-instance.sh [--instance-id | --slug | --container-name ] [options] Options: --instance-id Remove by instance id. --slug Remove by instance slug. --container-name Remove by container name. --purge-data Delete instance data directory after container removal. --registry Registry JSON path. --help Show this help. EOF } log() { printf '[remove-instance] %s\n' "$*" } die() { printf '[remove-instance] %s\n' "$*" >&2 exit 1 } purge_instance_root() { local instance_root="$1" local image_name="$2" [[ -d "$instance_root" ]] || return 0 docker run --rm \ -v "${instance_root}:/target" \ --entrypoint /bin/sh \ "$image_name" \ -c 'rm -rf /target/* /target/.[!.]* /target/..?*' >/dev/null rmdir "$instance_root" } while [[ $# -gt 0 ]]; do case "$1" in --instance-id) INSTANCE_ID="${2:-}" shift 2 ;; --slug) INSTANCE_SLUG="${2:-}" shift 2 ;; --container-name) CONTAINER_NAME="${2:-}" shift 2 ;; --registry) REGISTRY_PATH="${2:-}" shift 2 ;; --purge-data) PURGE_DATA=1 shift ;; --help|-h) usage exit 0 ;; *) die "unknown argument: $1" ;; esac done if [[ -z "$INSTANCE_ID$INSTANCE_SLUG$CONTAINER_NAME" ]]; then die "one of --instance-id, --slug or --container-name is required" fi REGISTRY_GET_ARGS=(--registry "$REGISTRY_PATH" get) if [[ -n "$INSTANCE_ID" ]]; then REGISTRY_GET_ARGS+=(--instance-id "$INSTANCE_ID") fi if [[ -n "$INSTANCE_SLUG" ]]; then REGISTRY_GET_ARGS+=(--slug "$INSTANCE_SLUG") fi if [[ -n "$CONTAINER_NAME" ]]; then REGISTRY_GET_ARGS+=(--container-name "$CONTAINER_NAME") fi if ! RECORD_JSON="$("$REGISTRY_TOOL" "${REGISTRY_GET_ARGS[@]}" 2>/dev/null)"; then die "instance not found in registry" fi INSTANCE_ID="$(printf '%s' "$RECORD_JSON" | python3 -c 'import json,sys; print(json.load(sys.stdin)["instance_id"])')" INSTANCE_SLUG="$(printf '%s' "$RECORD_JSON" | python3 -c 'import json,sys; print(json.load(sys.stdin)["instance_slug"])')" CONTAINER_NAME="$(printf '%s' "$RECORD_JSON" | python3 -c 'import json,sys; print(json.load(sys.stdin)["container_name"])')" INSTANCE_ROOT="$(printf '%s' "$RECORD_JSON" | python3 -c 'import json,sys; print(json.load(sys.stdin)["instance_root"])')" IMAGE_NAME="$(printf '%s' "$RECORD_JSON" | python3 -c 'import json,sys; print(json.load(sys.stdin)["image_name"])')" if docker container inspect "$CONTAINER_NAME" >/dev/null 2>&1; then log "removing container ${CONTAINER_NAME}" docker rm -f "$CONTAINER_NAME" >/dev/null else log "container ${CONTAINER_NAME} already absent" fi "$REGISTRY_TOOL" --registry "$REGISTRY_PATH" remove --instance-id "$INSTANCE_ID" >/dev/null if [[ "$PURGE_DATA" -eq 1 ]]; then log "purging instance data ${INSTANCE_ROOT}" purge_instance_root "$INSTANCE_ROOT" "$IMAGE_NAME" fi cat <