mirror of
https://github.com/dredx/prole.git
synced 2026-09-24 17:54:32 +00:00
- Include new `prole.spec` for build configurations and dependencies. - Add Terraform state handling for OpenTofu in `k3s` cluster. - Provision multiple Kubernetes resources in `prole-db` namespace: namespace, services, ConfigMaps, StatefulSets, Ingress rules, and PersistentVolumes. - Integrate deployment and configuration enhancements for `garage`, `prole`, and related components.
327 lines
11 KiB
Bash
Executable File
327 lines
11 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -u
|
|
|
|
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
|
# shellcheck disable=SC1090
|
|
source "$SCRIPT_DIR/prole_cfg.sh"
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
Usage: init_common_services.sh [-n|--namespace NS] [-k|--kerberos] <update|start|status>
|
|
|
|
Deploys common infrastructure services (ArgoCD, OpenBao, OpenTofu, Garage)
|
|
into the given Kubernetes namespace. Use -k to include the Kerberos/KDC service.
|
|
EOF
|
|
}
|
|
|
|
NS=""
|
|
ACTION="update"
|
|
ENABLE_KERBEROS=0
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
-m|--mode)
|
|
shift
|
|
prole_set_mode "${1:-}"
|
|
shift
|
|
;;
|
|
-m=*|--mode=*)
|
|
prole_set_mode "${1#*=}"
|
|
shift
|
|
;;
|
|
-n|--namespace)
|
|
shift
|
|
NS="${1:-}"
|
|
shift
|
|
;;
|
|
-n=*|--namespace=*)
|
|
NS="${1#*=}"
|
|
shift
|
|
;;
|
|
-k|--kerberos)
|
|
ENABLE_KERBEROS=1
|
|
shift
|
|
;;
|
|
update|start|status)
|
|
ACTION="$1"
|
|
shift
|
|
;;
|
|
-h|--help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
usage
|
|
exit 2
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [ -z "$NS" ]; then
|
|
NS="${SERVICE_NAMESPACE:-${NAMESPACE:-}}"
|
|
fi
|
|
if [ -z "$NS" ]; then
|
|
NS="default"
|
|
fi
|
|
|
|
ARGOCD_NS="${ARGOCD_NAMESPACE:-argocd}"
|
|
REGISTRY_NS="${REGISTRY_NAMESPACE:-default}"
|
|
|
|
prole_ensure_kubeconfig >/dev/null 2>&1 || true
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Pre-import container images from $PROLE_DATA/docker-import/*.tar
|
|
# ---------------------------------------------------------------------------
|
|
# final_deployment.sh exports images as
|
|
# $PROLE_DATA/docker-import/<safe_name>.tar
|
|
# where safe_name = image ref with / and : replaced by _.
|
|
# Loading these tars into the local container runtime before the sub-scripts
|
|
# deploy pods avoids slow image pulls from remote registries.
|
|
# ---------------------------------------------------------------------------
|
|
|
|
_resolve_prole_data() {
|
|
local d="${PROLE_DATA:-}"
|
|
if [[ -z "$d" ]]; then
|
|
if [[ -f "$SCRIPT_DIR/../env.sh" ]]; then
|
|
# shellcheck disable=SC1090
|
|
source "$SCRIPT_DIR/../env.sh"
|
|
d="${PROLE_DATA:-}"
|
|
fi
|
|
fi
|
|
echo "${d:-}"
|
|
}
|
|
|
|
_preload_docker_images() {
|
|
local prole_data
|
|
prole_data=$(_resolve_prole_data)
|
|
local import_dir="${DOCKER_IMPORT_DIR:-${prole_data:+${prole_data}/docker-import}}"
|
|
|
|
if [[ -z "$import_dir" || ! -d "$import_dir" ]]; then
|
|
echo "[SKIP] No docker-import directory found; images will be pulled from registries."
|
|
return 0
|
|
fi
|
|
|
|
local tar_files
|
|
tar_files=$(find "$import_dir" -maxdepth 1 -name '*.tar' -type f 2>/dev/null || true)
|
|
if [[ -z "$tar_files" ]]; then
|
|
echo "[SKIP] docker-import directory exists but contains no .tar files."
|
|
return 0
|
|
fi
|
|
|
|
local mode="${PROLE_MODE:-k3d}"
|
|
echo "Pre-loading container images from $import_dir (mode=$mode) ..."
|
|
|
|
case "$mode" in
|
|
k3d)
|
|
if ! command -v k3d >/dev/null 2>&1; then
|
|
echo "WARN: k3d not available; skipping docker-import pre-load." >&2
|
|
return 0
|
|
fi
|
|
local cluster_name="${K3D_CLUSTER_NAME:-prole-dev-cluster}"
|
|
local tar_file
|
|
while IFS= read -r tar_file; do
|
|
echo " Importing $(basename "$tar_file") into k3d cluster '$cluster_name' ..."
|
|
if k3d image import "$tar_file" -c "$cluster_name" >/dev/null 2>&1; then
|
|
echo " [OK] $(basename "$tar_file")"
|
|
else
|
|
echo " [WARN] Failed to import $(basename "$tar_file"); image will be pulled at deploy time." >&2
|
|
fi
|
|
done <<< "$tar_files"
|
|
;;
|
|
k3s)
|
|
# For k3s running from macOS: load tarballs into Docker, then push to
|
|
# the in-cluster registry:2. Falls back to Ansible ctr import if the
|
|
# registry push fails.
|
|
local registry="${LOCAL_REGISTRY:-}"
|
|
if [[ -z "$registry" ]]; then
|
|
# Derive from k3s server URL
|
|
local _srv="${PROLE_K3S_SERVER:-}"
|
|
if [[ -n "$_srv" ]]; then
|
|
_srv="${_srv#https://}"; _srv="${_srv#http://}"; _srv="${_srv%%/*}"; _srv="${_srv%%:*}"
|
|
[[ -n "$_srv" ]] && registry="${_srv}:5000"
|
|
fi
|
|
fi
|
|
local tar_file
|
|
while IFS= read -r tar_file; do
|
|
local base_name
|
|
base_name=$(basename "$tar_file" .tar)
|
|
echo " Loading $(basename "$tar_file") into local Docker ..."
|
|
local loaded_image=""
|
|
loaded_image=$(docker load -i "$tar_file" 2>/dev/null | sed -n 's/^Loaded image: //p' || true)
|
|
if [[ -z "$loaded_image" ]]; then
|
|
# Try to derive image name from tarball filename (safe_name convention)
|
|
loaded_image="${base_name//_//}"
|
|
loaded_image="${loaded_image%/*}:${loaded_image##*/}"
|
|
fi
|
|
if [[ -n "$registry" && -n "$loaded_image" ]]; then
|
|
local remote_tag="${registry}/${loaded_image}"
|
|
docker tag "$loaded_image" "$remote_tag" 2>/dev/null || true
|
|
echo " Pushing $remote_tag to registry ..."
|
|
if docker push "$remote_tag" 2>/dev/null; then
|
|
echo " [OK] $(basename "$tar_file") → $remote_tag"
|
|
continue
|
|
fi
|
|
echo " [WARN] Registry push failed; image will be pulled at deploy time." >&2
|
|
else
|
|
echo " [WARN] No registry configured; image will be pulled at deploy time." >&2
|
|
fi
|
|
done <<< "$tar_files"
|
|
;;
|
|
*)
|
|
echo "WARN: Unknown mode '$mode'; skipping docker-import pre-load." >&2
|
|
;;
|
|
esac
|
|
|
|
echo "Pre-load complete."
|
|
}
|
|
|
|
case "$ACTION" in
|
|
start|update|reload|initialize|restart)
|
|
_preload_docker_images
|
|
;;
|
|
esac
|
|
|
|
if [ -x "$SCRIPT_DIR/init_service_layer.sh" ]; then
|
|
if [[ "$ENABLE_KERBEROS" == "1" ]]; then
|
|
"$SCRIPT_DIR/init_service_layer.sh" -n "$NS" -k "$ACTION"
|
|
else
|
|
"$SCRIPT_DIR/init_service_layer.sh" -n "$NS" "$ACTION"
|
|
fi
|
|
exit $?
|
|
fi
|
|
|
|
if [[ -n "${COMMON_SERVICES_INIT_LOG:-}" ]]; then
|
|
mkdir -p "$(dirname "$COMMON_SERVICES_INIT_LOG")"
|
|
exec > >(tee -a "$COMMON_SERVICES_INIT_LOG") 2>&1
|
|
fi
|
|
|
|
OPENBAO_NAME=${OPENBAO_NAME:-openbao}
|
|
OPENTOFU_NAME=${OPENTOFU_NAME:-opentofu}
|
|
ARGOCD_SERVER_NAME=${ARGOCD_SERVER_NAME:-argocd-server}
|
|
GARAGE_NAME=${GARAGE_NAME:-garage}
|
|
OPENTOFU_CONFIGMAP=${OPENTOFU_CONFIGMAP:-opentofu-nginx}
|
|
OPENTOFU_SECRET=${OPENTOFU_SECRET:-opentofu-admin}
|
|
OPENBAO_KRB5_CONFIGMAP=${OPENBAO_KRB5_CONFIGMAP:-prole-krb5-conf}
|
|
GARAGE_CONFIGMAP=${GARAGE_CONFIGMAP:-garage-config}
|
|
GARAGE_SECRET_NAME=${GARAGE_SECRET_NAME:-garage-secrets}
|
|
|
|
find_namespaces() {
|
|
local kind="$1"
|
|
local name="$2"
|
|
kubectl get "$kind" -A --no-headers 2>/dev/null | awk -v n="$name" '$2==n {print $1}' | sort -u
|
|
}
|
|
|
|
collect_other_namespaces() {
|
|
local target="$1"
|
|
shift
|
|
local name="$1"
|
|
shift
|
|
local kinds=("$@")
|
|
local found=""
|
|
local kind
|
|
for kind in "${kinds[@]}"; do
|
|
found+=$(find_namespaces "$kind" "$name")
|
|
found+=$'\n'
|
|
done
|
|
printf '%s\n' "$found" | awk -v target="$target" 'NF && $1 != target {print $1}' | sort -u
|
|
}
|
|
|
|
migrate_common_services() {
|
|
local old_ns
|
|
|
|
for old_ns in $(collect_other_namespaces "$NS" "$OPENBAO_NAME" statefulset deployment service); do
|
|
echo "Found OpenBao in namespace '$old_ns'; removing before deploy to '$NS' ..."
|
|
kubectl delete -n "$old_ns" statefulset "$OPENBAO_NAME" --ignore-not-found >/dev/null 2>&1 || true
|
|
kubectl delete -n "$old_ns" deploy "$OPENBAO_NAME" --ignore-not-found >/dev/null 2>&1 || true
|
|
kubectl delete -n "$old_ns" svc "$OPENBAO_NAME" --ignore-not-found >/dev/null 2>&1 || true
|
|
kubectl delete -n "$old_ns" configmap "$OPENBAO_KRB5_CONFIGMAP" --ignore-not-found >/dev/null 2>&1 || true
|
|
done
|
|
|
|
for old_ns in $(collect_other_namespaces "$NS" "$OPENTOFU_NAME" deployment service); do
|
|
echo "Found OpenTofu in namespace '$old_ns'; removing before deploy to '$NS' ..."
|
|
if [ -x "$SCRIPT_DIR/init_opentofu.sh" ]; then
|
|
"$SCRIPT_DIR/init_opentofu.sh" -n "$old_ns" stop || true
|
|
else
|
|
kubectl delete -n "$old_ns" deploy "$OPENTOFU_NAME" --ignore-not-found >/dev/null 2>&1 || true
|
|
kubectl delete -n "$old_ns" svc "$OPENTOFU_NAME" --ignore-not-found >/dev/null 2>&1 || true
|
|
fi
|
|
kubectl delete -n "$old_ns" configmap "$OPENTOFU_CONFIGMAP" --ignore-not-found >/dev/null 2>&1 || true
|
|
kubectl delete -n "$old_ns" secret "$OPENTOFU_SECRET" --ignore-not-found >/dev/null 2>&1 || true
|
|
done
|
|
|
|
for old_ns in $(collect_other_namespaces "$ARGOCD_NS" "$ARGOCD_SERVER_NAME" deployment service); do
|
|
echo "Found ArgoCD in namespace '$old_ns'; removing before deploy to '$ARGOCD_NS' ..."
|
|
if [ -x "$SCRIPT_DIR/init_registry.sh" ]; then
|
|
REGISTRY_NAMESPACE="$REGISTRY_NS" "$SCRIPT_DIR/init_registry.sh" -n "$old_ns" stop || true
|
|
else
|
|
kubectl delete -n "$old_ns" deploy "$ARGOCD_SERVER_NAME" --ignore-not-found >/dev/null 2>&1 || true
|
|
kubectl delete -n "$old_ns" svc "$ARGOCD_SERVER_NAME" --ignore-not-found >/dev/null 2>&1 || true
|
|
fi
|
|
done
|
|
|
|
for old_ns in $(collect_other_namespaces "$NS" "$GARAGE_NAME" statefulset service); do
|
|
echo "Found Garage in namespace '$old_ns'; removing before deploy to '$NS' ..."
|
|
kubectl delete -n "$old_ns" statefulset "$GARAGE_NAME" --ignore-not-found >/dev/null 2>&1 || true
|
|
kubectl delete -n "$old_ns" svc "$GARAGE_NAME" --ignore-not-found >/dev/null 2>&1 || true
|
|
kubectl delete -n "$old_ns" configmap "$GARAGE_CONFIGMAP" --ignore-not-found >/dev/null 2>&1 || true
|
|
kubectl delete -n "$old_ns" secret "$GARAGE_SECRET_NAME" --ignore-not-found >/dev/null 2>&1 || true
|
|
done
|
|
}
|
|
|
|
echo "Deploying common services (namespace=$NS, action=$ACTION)"
|
|
|
|
rc=0
|
|
|
|
case "$ACTION" in
|
|
start|update|reload|initialize|restart)
|
|
migrate_common_services
|
|
;;
|
|
esac
|
|
|
|
if [ -x "$SCRIPT_DIR/init_openbao.sh" ]; then
|
|
ROLLOUT_TIMEOUT="${ROLLOUT_TIMEOUT:-300s}" "$SCRIPT_DIR/init_openbao.sh" -n "$NS" "$ACTION" || rc=$?
|
|
else
|
|
echo "WARN: init_openbao.sh not found; skipping OpenBao."
|
|
fi
|
|
|
|
if [ -x "$SCRIPT_DIR/init_opentofu.sh" ]; then
|
|
ROLLOUT_TIMEOUT="${ROLLOUT_TIMEOUT:-300s}" "$SCRIPT_DIR/init_opentofu.sh" -n "$NS" "$ACTION" || rc=$?
|
|
else
|
|
echo "WARN: init_opentofu.sh not found; skipping OpenTofu."
|
|
fi
|
|
|
|
if [ -x "$SCRIPT_DIR/init_registry.sh" ]; then
|
|
ARGOCD_NAMESPACE="$ARGOCD_NS" REGISTRY_NAMESPACE="$REGISTRY_NS" \
|
|
"$SCRIPT_DIR/init_registry.sh" -n "$ARGOCD_NS" --registry-namespace "$REGISTRY_NS" "$ACTION" || rc=$?
|
|
else
|
|
echo "WARN: init_registry.sh not found; ArgoCD deploy skipped."
|
|
fi
|
|
|
|
if [ -x "$SCRIPT_DIR/init_garage_store.sh" ]; then
|
|
garage_action="$ACTION"
|
|
case "$garage_action" in
|
|
update|reload|initialize) garage_action="start" ;;
|
|
esac
|
|
NAMESPACE="$NS" SERVICE_NAMESPACE="$NS" GARAGE_NAMESPACE="$NS" ROLLOUT_TIMEOUT="${ROLLOUT_TIMEOUT:-300s}" \
|
|
"$SCRIPT_DIR/init_garage_store.sh" "$garage_action" || rc=$?
|
|
else
|
|
echo "WARN: init_garage_store.sh not found; garage deploy skipped."
|
|
fi
|
|
|
|
if [[ "$ENABLE_KERBEROS" == "1" ]]; then
|
|
if [ -x "$SCRIPT_DIR/init_kdc.sh" ]; then
|
|
kdc_action="$ACTION"
|
|
case "$kdc_action" in
|
|
stop) kdc_action="cleanup" ;;
|
|
status) kdc_action="status" ;;
|
|
*) kdc_action="update" ;;
|
|
esac
|
|
SERVICE_NAMESPACE="$NS" PROLE_KDC_NAMESPACE="$NS" \
|
|
"$SCRIPT_DIR/init_kdc.sh" "$kdc_action" || rc=$?
|
|
else
|
|
echo "WARN: init_kdc.sh not found; kerberos deploy skipped."
|
|
fi
|
|
fi
|
|
|
|
exit "$rc"
|