prole/etc/init_redis.sh

171 lines
6.0 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# init_redis.sh
# Purpose:
# - Deploy Redis as a shared common service via Bitnami Helm chart
# - Provides a pub/sub-capable Redis instance for knoe CLI, desktop, and GitLab
# - Runs in knoe-system (or SERVICE_NAMESPACE) so all services can reach it
# - Service endpoint: redis-master.<namespace>.svc.cluster.local:6379
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
# Shared option parsing for common core scripts
# shellcheck disable=SC1090
source "$SCRIPT_DIR/common_core_lib.sh"
# Inject default config if not provided
_has_config=0
for _arg in "$@"; do
[[ "$_arg" == "-c" || "$_arg" == "--config" || "$_arg" == -c=* || "$_arg" == --config=* ]] && _has_config=1
done
if [[ $_has_config -eq 0 ]]; then
_default_cfg="$(common_core_default_config_path "$SCRIPT_DIR" || true)"
if [[ -n "$_default_cfg" ]]; then
set -- "-c" "$_default_cfg" "$@"
fi
fi
unset _has_config _arg _default_cfg
common_core_preparse_config "$@"
# shellcheck disable=SC1090
source "$SCRIPT_DIR/knoe_cfg.sh"
set -- "${COMMON_CORE_ARGS[@]}"
common_core_parse_args "$@"
if [[ -z "${KNOE_MODE:-}" ]]; then
export KNOE_MODE="k3s"
fi
if [[ "${COMMON_CORE_HELP:-0}" == 1 ]]; then
common_core_usage "$0"
exit 0
fi
if [[ -n "${COMMON_CORE_PARSE_ERROR:-}" ]]; then
echo "ERROR: ${COMMON_CORE_PARSE_ERROR}" >&2
common_core_usage "$0"
exit 2
fi
ACTION="$COMMON_CORE_ACTION"
NAMESPACE="$(common_core_resolve_namespace "${SERVICE_NAMESPACE:-knoe-system}")"
common_core_apply_namespace "$NAMESPACE"
REDIS_RELEASE="${REDIS_RELEASE:-redis}"
REDIS_REPO_NAME="bitnami"
REDIS_REPO_URL="https://charts.bitnami.com/bitnami"
REDIS_CHART="bitnami/redis"
REDIS_CHART_VERSION="${REDIS_CHART_VERSION:-}"
REDIS_PORT="${REDIS_PORT:-6379}"
REDIS_PVC_SIZE="${REDIS_PVC_SIZE:-1Gi}"
# No dynamic provisioner is available in the service cluster; persistence disabled by default
# (Redis is used as a pub/sub broker — durable storage is not required)
REDIS_STORAGE_CLASS="${REDIS_STORAGE_CLASS:-${STORAGE_CLASS:-}}"
REDIS_PERSISTENCE_ENABLED="${REDIS_PERSISTENCE_ENABLED:-false}"
# Image registry override — set to "registry.bitnami.com" if docker.io is unreachable
# Bitnami OCI registry works as an alternative when Docker Hub times out on constrained networks.
REDIS_IMAGE_REGISTRY="${REDIS_IMAGE_REGISTRY:-}"
# Helm timeout — increase for slow image pulls on constrained network links (e.g. Pi cluster)
REDIS_HELM_TIMEOUT="${REDIS_HELM_TIMEOUT:-8m}"
log() { echo "[INFO] $*"; }
warn() { echo "[WARN] $*" >&2; }
die() { echo "[ERROR] $*" >&2; exit 1; }
command -v helm >/dev/null 2>&1 || die "helm not found"
command -v kubectl >/dev/null 2>&1 || die "kubectl not found"
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
redis_service_host() {
printf '%s-master.%s.svc.cluster.local' "$REDIS_RELEASE" "$NAMESPACE"
}
redis_is_running() {
kubectl -n "$NAMESPACE" get deployment "${REDIS_RELEASE}-master" >/dev/null 2>&1 || \
kubectl -n "$NAMESPACE" get statefulset "${REDIS_RELEASE}-master" >/dev/null 2>&1
}
# ---------------------------------------------------------------------------
# Deploy
# ---------------------------------------------------------------------------
deploy_redis() {
# If Redis is already running and REDIS_FORCE_UPGRADE is not set, skip the
# helm upgrade to avoid Docker Hub / OCI registry timeouts on constrained
# networks (e.g. Pi cluster where registry-1.docker.io may be unreachable).
# Set REDIS_FORCE_UPGRADE=1 to force a chart upgrade regardless.
if [[ "${REDIS_FORCE_UPGRADE:-0}" != "1" ]] && redis_is_running; then
log "Redis already running in '${NAMESPACE}'; skipping upgrade."
log "Set REDIS_FORCE_UPGRADE=1 to force a helm upgrade."
return 0
fi
log "Adding/updating Bitnami Helm repo..."
helm repo add "$REDIS_REPO_NAME" "$REDIS_REPO_URL" 2>&1 || true
helm repo update "$REDIS_REPO_NAME" 2>&1 || warn "helm repo update returned non-zero; continuing..."
kubectl get namespace "$NAMESPACE" >/dev/null 2>&1 || kubectl create namespace "$NAMESPACE" >/dev/null
local helm_args=(
upgrade --install "$REDIS_RELEASE" "$REDIS_CHART"
--namespace "$NAMESPACE"
--create-namespace
--timeout "$REDIS_HELM_TIMEOUT"
--wait
--set architecture=standalone
--set auth.enabled=false
--set master.persistence.enabled="${REDIS_PERSISTENCE_ENABLED}"
--set master.persistence.size="$REDIS_PVC_SIZE"
--set master.resources.requests.memory=128Mi
--set master.resources.requests.cpu=50m
--set master.resources.limits.memory=512Mi
--set master.resources.limits.cpu=500m
)
if [[ -n "$REDIS_CHART_VERSION" ]]; then
helm_args+=(--version "$REDIS_CHART_VERSION")
fi
if [[ -n "$REDIS_STORAGE_CLASS" ]]; then
helm_args+=(--set master.persistence.storageClass="$REDIS_STORAGE_CLASS")
fi
if [[ -n "$REDIS_IMAGE_REGISTRY" ]]; then
log "Using image registry override: ${REDIS_IMAGE_REGISTRY}"
helm_args+=(--set global.imageRegistry="$REDIS_IMAGE_REGISTRY")
fi
log "Deploying Redis (release=${REDIS_RELEASE}, ns=${NAMESPACE})..."
helm "${helm_args[@]}"
log "Redis ready. Endpoint: $(redis_service_host):${REDIS_PORT}"
log "Pub/sub: redis-cli -h $(redis_service_host) -p ${REDIS_PORT} subscribe <channel>"
}
# ---------------------------------------------------------------------------
# Action dispatch
# ---------------------------------------------------------------------------
case "$ACTION" in
start|update|reload|initialize|restart)
deploy_redis
;;
stop)
log "Removing Redis (${REDIS_RELEASE}) from namespace ${NAMESPACE}..."
helm -n "$NAMESPACE" uninstall "$REDIS_RELEASE" 2>/dev/null || warn "Redis release not found."
;;
status)
log "Redis status in namespace ${NAMESPACE}:"
kubectl -n "$NAMESPACE" get pods -l "app.kubernetes.io/name=redis" 2>/dev/null || \
echo " No Redis pods found."
kubectl -n "$NAMESPACE" get svc -l "app.kubernetes.io/name=redis" 2>/dev/null || true
;;
*)
die "Unknown action: $ACTION"
;;
esac