PSA/ee/appliance/scripts/reset-appliance-data.sh
Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

259 lines
7.2 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
KUBECONFIG_PATH="${KUBECONFIG:-}"
APP_NAMESPACE="msp"
RELEASE_NAMESPACE="alga-system"
RESET_NAMESPACE="appliance-reset"
STORAGE_PATH="/var/mnt/alga-data/local-path-provisioner"
FLUX_NAMESPACE="flux-system"
GITOPS_SOURCE_NAME="alga-appliance"
GITOPS_KUSTOMIZATION_NAME="alga-appliance"
FORCE=false
DRY_RUN=false
usage() {
cat <<'EOF'
Usage:
reset-appliance-data.sh --kubeconfig <path> --force [options]
Options:
--kubeconfig <path> Kubeconfig path
--app-namespace <name> Application namespace to delete (default: msp)
--release-namespace <name> Release namespace to delete (default: alga-system)
--reset-namespace <name> Temporary namespace for the wipe job (default: appliance-reset)
--storage-path <path> Host path used by local-path storage (default: /var/mnt/alga-data/local-path-provisioner)
--flux-namespace <name> Flux namespace containing appliance source objects (default: flux-system)
--gitops-source <name> Flux source name to delete before reset (default: alga-appliance)
--gitops-kustomization <name>
Kustomization name to delete before reset (default: alga-appliance)
--force Confirm destructive wipe
--dry-run Print the planned commands without mutating the cluster
--help Show this help
EOF
}
require_command() {
if ! command -v "$1" >/dev/null 2>&1; then
echo "Required command not found: $1" >&2
exit 1
fi
}
run_cmd() {
if $DRY_RUN; then
printf '+'
for arg in "$@"; do
printf ' %q' "$arg"
done
printf '\n'
return 0
fi
"$@"
}
kubectl_cmd() {
run_cmd kubectl --kubeconfig "$KUBECONFIG_PATH" "$@"
}
namespace_exists() {
kubectl --kubeconfig "$KUBECONFIG_PATH" get namespace "$1" >/dev/null 2>&1
}
delete_namespace() {
local namespace="$1"
if ! namespace_exists "$namespace"; then
return 0
fi
kubectl_cmd delete namespace "$namespace" --ignore-not-found=true --wait=false
if $DRY_RUN; then
echo "+ kubectl --kubeconfig $KUBECONFIG_PATH wait --for=delete namespace/$namespace --timeout=10m"
return 0
fi
kubectl --kubeconfig "$KUBECONFIG_PATH" wait --for=delete "namespace/$namespace" --timeout=10m || true
}
delete_gitops_objects() {
if $DRY_RUN; then
echo "+ kubectl --kubeconfig $KUBECONFIG_PATH -n $FLUX_NAMESPACE delete kustomization.kustomize.toolkit.fluxcd.io/$GITOPS_KUSTOMIZATION_NAME --ignore-not-found=true"
echo "+ kubectl --kubeconfig $KUBECONFIG_PATH -n $FLUX_NAMESPACE delete ocirepository.source.toolkit.fluxcd.io/$GITOPS_SOURCE_NAME --ignore-not-found=true"
echo "+ kubectl --kubeconfig $KUBECONFIG_PATH -n $FLUX_NAMESPACE delete gitrepository.source.toolkit.fluxcd.io/$GITOPS_SOURCE_NAME --ignore-not-found=true"
return 0
fi
if namespace_exists "$FLUX_NAMESPACE"; then
kubectl --kubeconfig "$KUBECONFIG_PATH" -n "$FLUX_NAMESPACE" delete "kustomization.kustomize.toolkit.fluxcd.io/$GITOPS_KUSTOMIZATION_NAME" --ignore-not-found=true >/dev/null
kubectl --kubeconfig "$KUBECONFIG_PATH" -n "$FLUX_NAMESPACE" delete "ocirepository.source.toolkit.fluxcd.io/$GITOPS_SOURCE_NAME" --ignore-not-found=true >/dev/null
kubectl --kubeconfig "$KUBECONFIG_PATH" -n "$FLUX_NAMESPACE" delete "gitrepository.source.toolkit.fluxcd.io/$GITOPS_SOURCE_NAME" --ignore-not-found=true >/dev/null
fi
}
delete_local_path_pvs() {
local pv_names=""
if ! $DRY_RUN; then
pv_names="$(kubectl --kubeconfig "$KUBECONFIG_PATH" get pv -o json | jq -r --arg ns "$APP_NAMESPACE" '
.items[]
| select(.spec.storageClassName == "local-path")
| select((.spec.claimRef.namespace // "") == $ns)
| .metadata.name
')"
fi
if [ -z "$pv_names" ] && ! $DRY_RUN; then
return 0
fi
if $DRY_RUN; then
echo "+ delete local-path PVs bound to namespace $APP_NAMESPACE"
return 0
fi
while IFS= read -r pv_name; do
[ -n "$pv_name" ] || continue
kubectl --kubeconfig "$KUBECONFIG_PATH" delete pv "$pv_name" --ignore-not-found=true >/dev/null
done <<EOF
$pv_names
EOF
}
run_reset_job() {
local manifest
manifest="$(cat <<EOF
apiVersion: v1
kind: Namespace
metadata:
name: ${RESET_NAMESPACE}
labels:
pod-security.kubernetes.io/enforce: privileged
pod-security.kubernetes.io/audit: privileged
pod-security.kubernetes.io/warn: privileged
---
apiVersion: batch/v1
kind: Job
metadata:
name: appliance-data-reset
namespace: ${RESET_NAMESPACE}
spec:
backoffLimit: 0
template:
spec:
restartPolicy: Never
containers:
- name: wipe
image: busybox:1.36
securityContext:
privileged: true
command:
- sh
- -ec
- |
target="/host${STORAGE_PATH}"
mkdir -p "\$target"
find "\$target" -mindepth 1 -maxdepth 1 -print -exec rm -rf {} +
volumeMounts:
- name: host-root
mountPath: /host
volumes:
- name: host-root
hostPath:
path: /
type: Directory
EOF
)"
if $DRY_RUN; then
echo "+ kubectl --kubeconfig $KUBECONFIG_PATH apply -f -"
printf '%s\n' "$manifest"
echo "+ kubectl --kubeconfig $KUBECONFIG_PATH -n $RESET_NAMESPACE wait --for=condition=complete --timeout=10m job/appliance-data-reset"
echo "+ kubectl --kubeconfig $KUBECONFIG_PATH delete namespace $RESET_NAMESPACE --ignore-not-found=true"
return 0
fi
printf '%s\n' "$manifest" | kubectl --kubeconfig "$KUBECONFIG_PATH" apply -f -
kubectl --kubeconfig "$KUBECONFIG_PATH" -n "$RESET_NAMESPACE" wait --for=condition=complete --timeout=10m job/appliance-data-reset
kubectl --kubeconfig "$KUBECONFIG_PATH" -n "$RESET_NAMESPACE" logs job/appliance-data-reset >/dev/null || true
kubectl --kubeconfig "$KUBECONFIG_PATH" delete namespace "$RESET_NAMESPACE" --ignore-not-found=true >/dev/null
}
while [ "$#" -gt 0 ]; do
case "$1" in
--kubeconfig)
KUBECONFIG_PATH="$2"
shift 2
;;
--app-namespace)
APP_NAMESPACE="$2"
shift 2
;;
--release-namespace)
RELEASE_NAMESPACE="$2"
shift 2
;;
--reset-namespace)
RESET_NAMESPACE="$2"
shift 2
;;
--storage-path)
STORAGE_PATH="$2"
shift 2
;;
--flux-namespace)
FLUX_NAMESPACE="$2"
shift 2
;;
--gitops-source)
GITOPS_SOURCE_NAME="$2"
shift 2
;;
--gitops-kustomization)
GITOPS_KUSTOMIZATION_NAME="$2"
shift 2
;;
--force)
FORCE=true
shift
;;
--dry-run)
DRY_RUN=true
shift
;;
--help|-h)
usage
exit 0
;;
*)
echo "Unknown argument: $1" >&2
usage >&2
exit 1
;;
esac
done
require_command jq
require_command kubectl
if [ -z "$KUBECONFIG_PATH" ]; then
echo "Kubeconfig path is required via --kubeconfig or KUBECONFIG." >&2
exit 1
fi
if ! $FORCE; then
echo "This command is destructive. Re-run with --force to wipe appliance namespaces and local-path data." >&2
exit 1
fi
delete_gitops_objects
delete_namespace "$RELEASE_NAMESPACE"
delete_namespace "$APP_NAMESPACE"
delete_local_path_pvs
run_reset_job
echo "Appliance namespaces and local-path data were wiped."