# Methods library for woodpecker — sourced by install-woodpecker.sh (and the # orchestrator's generated run-*.sh). SCRIPT_DIR, CATALOG_LIB and WOODPECKER_* env # must be set before sourcing. Mirrors the forgejo-lib.sh structure. _kubectl() { if command -v kubectl >/dev/null 2>&1; then command kubectl "$@" elif command -v k0s >/dev/null 2>&1; then k0s kubectl "$@" else echo "ERROR: no kubectl or k0s binary found" >&2; exit 127 fi } _require_env() { local var="$1" if [ -z "${!var:-}" ]; then echo "ERROR: required variable $var is not set" >&2 exit 1 fi } _namespace_exists() { _kubectl get namespace "$WOODPECKER_NAMESPACE" >/dev/null 2>&1 } _ensure_database() { local pg_pod pg_pod=$(_kubectl get pod --namespace "$WOODPECKER_DB_NAMESPACE" \ --selector "app.kubernetes.io/name=postgresql" \ -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || true) if [ -z "$pg_pod" ]; then echo "ERROR: no postgresql pod found in namespace $WOODPECKER_DB_NAMESPACE" >&2 exit 1 fi local exists exists=$(_kubectl exec --namespace "$WOODPECKER_DB_NAMESPACE" "$pg_pod" -- \ psql -U postgres -tAc \ "SELECT 1 FROM pg_database WHERE datname = '${WOODPECKER_DATABASE}'" 2>/dev/null || true) if [ "${exists}" != "1" ]; then _kubectl exec --namespace "$WOODPECKER_DB_NAMESPACE" "$pg_pod" -- \ psql -U postgres -c \ "CREATE DATABASE \"${WOODPECKER_DATABASE}\" WITH OWNER postgres ENCODING 'UTF8' LC_COLLATE 'C' LC_CTYPE 'C' TEMPLATE template0" echo " [ok] database '${WOODPECKER_DATABASE}' created" else echo " [skip] database '${WOODPECKER_DATABASE}' already exists" fi _kubectl exec --namespace "$WOODPECKER_DB_NAMESPACE" "$pg_pod" -- \ psql -U postgres -d "${WOODPECKER_DATABASE}" -c \ "GRANT ALL ON SCHEMA public TO postgres" echo " [ok] schema public grants ensured" } _wait_for_deployment() { local name="$1" local timeout="${2:-180}" _kubectl rollout status deployment/"$name" \ --namespace "$WOODPECKER_NAMESPACE" \ --timeout="${timeout}s" } # shellcheck source=../../../lib/gateway-tls.sh source "${CATALOG_LIB}/gateway-tls.sh" _do_install() { [ -f "${SCRIPT_DIR}/_credentials.env" ] && set -a && source "${SCRIPT_DIR}/_credentials.env" && set +a _require_env WOODPECKER_AGENT_SECRET _require_env WOODPECKER_FORGEJO_SECRET _require_env WOODPECKER_FORGEJO_CLIENT _require_env WOODPECKER_HOSTNAME _require_env POSTGRES_PASSWORD echo "Ensuring database '${WOODPECKER_DATABASE}' exists..." _ensure_database if ! _namespace_exists; then _kubectl create namespace "$WOODPECKER_NAMESPACE" fi local _forgejo_host _forgejo_gw_ip _host_aliases_yaml="" _forgejo_host=$(echo "${WOODPECKER_FORGEJO_URL}" | sed 's|https\?://||' | cut -d: -f1 | cut -d/ -f1) if [ -n "${_forgejo_host:-}" ]; then _forgejo_gw_ip="${WOODPECKER_FORGEJO_GATEWAY_IP:-$(\ _kubectl get svc -n "${WOODPECKER_GATEWAY_NS}" \ -l "gateway.networking.k8s.io/gateway-name=${WOODPECKER_GATEWAY_NAME}" \ -o jsonpath='{.items[0].spec.clusterIP}' 2>/dev/null || true)}" if [ -n "${_forgejo_gw_ip:-}" ]; then _host_aliases_yaml=" hostAliases: - ip: \"${_forgejo_gw_ip}\" hostnames: - \"${_forgejo_host}\"" fi fi _kubectl apply --namespace "$WOODPECKER_NAMESPACE" -f - </dev/null || true) if [ -z "$pod" ]; then echo "UNHEALTHY: no woodpecker-server pod found in namespace $WOODPECKER_NAMESPACE" >&2 exit 1 fi local status status=$(_kubectl exec --namespace "$WOODPECKER_NAMESPACE" "$pod" -- \ wget -qO- --server-response "http://localhost:${WOODPECKER_HTTP_PORT}/healthz" 2>&1 \ | grep "HTTP/" | tail -1 | awk '{print $2}' || echo "") if [ "$status" = "200" ]; then echo "HEALTHY: woodpecker /healthz returned HTTP 200" else echo "UNHEALTHY: woodpecker /healthz returned HTTP $status" >&2 exit 1 fi }