fix: use HARBOR_USERNAME secret in CI, add idempotent Harbor API setup to deploy script

- GitHub Actions: login with secrets.HARBOR_USERNAME + HARBOR_PASSWORD
- deploy.sh step 7: creates stonks-oracle project, robot account, tag retention
- All API calls are idempotent (safe to re-run)
This commit is contained in:
Celes Renata
2026-04-19 07:45:58 +00:00
parent 5be3ce2db9
commit 911e42996b
2 changed files with 194 additions and 3 deletions
+3 -3
View File
@@ -87,7 +87,7 @@ jobs:
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: admin
username: ${{ secrets.HARBOR_USERNAME }}
password: ${{ secrets.HARBOR_PASSWORD }}
- name: Set up Docker Buildx
@@ -121,7 +121,7 @@ jobs:
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: admin
username: ${{ secrets.HARBOR_USERNAME }}
password: ${{ secrets.HARBOR_PASSWORD }}
- name: Set up Docker Buildx
@@ -153,7 +153,7 @@ jobs:
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: admin
username: ${{ secrets.HARBOR_USERNAME }}
password: ${{ secrets.HARBOR_PASSWORD }}
- name: Set up Docker Buildx
+191
View File
@@ -0,0 +1,191 @@
#!/usr/bin/env bash
set -euo pipefail
# deploy.sh — Deploy Harbor container registry to Kubernetes
# Run from gremlin-1: bash ~/sources/kube/harbor/deploy.sh
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo "=== Harbor Container Registry Deploy ==="
echo ""
# -------------------------------------------------------
# 1. Create namespace
# -------------------------------------------------------
echo "--- Step 1: Creating namespace ---"
kubectl create namespace harbor-service --dry-run=client -o yaml | kubectl apply -f -
echo " ✓ harbor-service namespace ready"
echo ""
# -------------------------------------------------------
# 2. Proxy CA cert (for Squid SSL bump)
# -------------------------------------------------------
echo "--- Step 2: Proxy CA cert ---"
CA_CERT_PATH="/tmp/harbor-home.crt"
if curl -sf http://192.168.42.1/home.crt -o "$CA_CERT_PATH" 2>/dev/null; then
if ! kubectl get configmap proxy-ca-cert -n harbor-service > /dev/null 2>&1; then
kubectl create configmap proxy-ca-cert --from-file=ca.crt="$CA_CERT_PATH" -n harbor-service
echo " ✓ proxy-ca-cert created"
else
echo " ✓ proxy-ca-cert already exists"
fi
else
echo " ⚠ Could not fetch CA cert (non-fatal)"
fi
echo ""
# -------------------------------------------------------
# 3. Create NFS directories (requires root for mount)
# -------------------------------------------------------
echo "--- Step 3: Ensuring NFS directories ---"
if [ "$(id -u)" -eq 0 ]; then
mkdir -p /tmp/harbor-nfs-init
mount -t nfs 192.168.42.8:/volume1/Kubernetes/harbor /tmp/harbor-nfs-init 2>/dev/null || true
mkdir -p /tmp/harbor-nfs-init/data/registry
mkdir -p /tmp/harbor-nfs-init/data/redis
mkdir -p /tmp/harbor-nfs-init/data/jobservice
mkdir -p /tmp/harbor-nfs-init/data/trivy
umount /tmp/harbor-nfs-init 2>/dev/null || true
rmdir /tmp/harbor-nfs-init 2>/dev/null || true
echo " ✓ NFS directories ready"
else
echo " ⚠ Not root — skipping NFS dir creation (dirs may already exist)"
fi
echo ""
# -------------------------------------------------------
# 4. Apply PVs and PVCs
# -------------------------------------------------------
echo "--- Step 4: Applying PVs and PVCs ---"
kubectl apply -f "$SCRIPT_DIR/../pvs/harbor-pv.yaml"
kubectl apply -f "$SCRIPT_DIR/pvcs.yaml"
echo " ✓ PVs and PVCs applied"
echo ""
# -------------------------------------------------------
# 5. Remove old plain Docker Registry ingress
# -------------------------------------------------------
echo "--- Step 5: Checking old registry ingress ---"
if kubectl get ingress registry-ingress -n git-server > /dev/null 2>&1; then
echo " Removing old registry ingress from git-server namespace..."
kubectl delete ingress registry-ingress -n git-server
echo " ✓ Old registry ingress removed"
else
echo " ✓ No old registry ingress found"
fi
echo ""
# -------------------------------------------------------
# 6. Install/upgrade Harbor via Helm
# -------------------------------------------------------
echo "--- Step 6: Installing Harbor ---"
helm repo add harbor https://helm.goharbor.io 2>/dev/null || true
helm repo update harbor 2>/dev/null || true
HARBOR_EXISTS=$(helm list -n harbor-service -q 2>/dev/null | grep -c harbor || true)
if [ "${HARBOR_EXISTS:-0}" -gt 0 ]; then
echo " Harbor already installed — upgrading..."
else
echo " Fresh Harbor install..."
fi
helm upgrade --install harbor harbor/harbor \
--namespace harbor-service \
--values "$SCRIPT_DIR/values.yaml" \
--timeout 10m \
--wait
echo ""
echo " Waiting for Harbor core to be ready..."
kubectl wait --for=condition=ready pod -l app=harbor,component=core -n harbor-service --timeout=180s || true
echo ""
# -------------------------------------------------------
# 7. Configure Harbor via API (idempotent)
# -------------------------------------------------------
echo "--- Step 7: Configuring Harbor project and robot account ---"
HARBOR_API="https://registry.celestium.life/api/v2.0"
HARBOR_AUTH="admin:St0nks0racl3!"
# Create stonks-oracle project if it doesn't exist
if curl -sf -u "$HARBOR_AUTH" "$HARBOR_API/projects?name=stonks-oracle" | python3 -c "import sys,json; sys.exit(0 if json.load(sys.stdin) else 1)" 2>/dev/null; then
echo " ✓ Project stonks-oracle already exists"
else
curl -sf -X POST -u "$HARBOR_AUTH" \
-H "Content-Type: application/json" \
"$HARBOR_API/projects" \
-d '{"project_name":"stonks-oracle","public":true,"metadata":{"auto_scan":"true","severity":"high"},"storage_limit":-1}'
echo " ✓ Project stonks-oracle created (public, auto-scan enabled)"
fi
# Create CI robot account if it doesn't exist
EXISTING_ROBOT=$(curl -sf -u "$HARBOR_AUTH" "$HARBOR_API/robots" 2>/dev/null | python3 -c "
import sys, json
robots = json.load(sys.stdin)
for r in robots:
if 'ci-push' in r.get('name', ''):
print(r['name'])
break
" 2>/dev/null || true)
if [ -n "$EXISTING_ROBOT" ]; then
echo " ✓ Robot account already exists: $EXISTING_ROBOT"
else
ROBOT_RESP=$(curl -sf -X POST -u "$HARBOR_AUTH" \
-H "Content-Type: application/json" \
"$HARBOR_API/robots" \
-d '{
"name":"ci-push",
"description":"CI/CD pipeline push account",
"duration":-1,
"level":"project",
"permissions":[{
"namespace":"stonks-oracle",
"kind":"project",
"access":[
{"resource":"repository","action":"push"},
{"resource":"repository","action":"pull"},
{"resource":"tag","action":"create"},
{"resource":"tag","action":"list"},
{"resource":"artifact","action":"read"}
]
}]
}')
ROBOT_NAME=$(echo "$ROBOT_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['name'])")
ROBOT_SECRET=$(echo "$ROBOT_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['secret'])")
echo " ✓ Robot account created"
echo " Username: $ROBOT_NAME"
echo " Secret: $ROBOT_SECRET"
echo " ⚠ Save these — add as HARBOR_USERNAME and HARBOR_PASSWORD in your CI secrets"
fi
# Set tag retention policy (idempotent — check if one exists first)
PROJECT_ID=$(curl -sf -u "$HARBOR_AUTH" "$HARBOR_API/projects?name=stonks-oracle" | python3 -c "import sys,json; print(json.load(sys.stdin)[0]['project_id'])" 2>/dev/null || true)
if [ -n "$PROJECT_ID" ]; then
EXISTING_RETENTION=$(curl -sf -u "$HARBOR_AUTH" "$HARBOR_API/retentions" 2>/dev/null || true)
if echo "$EXISTING_RETENTION" | python3 -c "import sys,json; d=json.load(sys.stdin); sys.exit(0 if isinstance(d,list) and len(d)>0 else 1)" 2>/dev/null; then
echo " ✓ Tag retention policy already exists"
else
curl -sf -X POST -u "$HARBOR_AUTH" \
-H "Content-Type: application/json" \
"$HARBOR_API/retentions" \
-d "{
\"algorithm\":\"or\",
\"scope\":{\"level\":\"project\",\"ref\":$PROJECT_ID},
\"trigger\":{\"kind\":\"Schedule\",\"settings\":{\"cron\":\"0 0 0 * * *\"}},
\"rules\":[
{\"disabled\":false,\"action\":\"retain\",\"scope_selectors\":{\"repository\":[{\"kind\":\"doublestar\",\"decoration\":\"repoMatches\",\"pattern\":\"**\"}]},\"tag_selectors\":[{\"kind\":\"doublestar\",\"decoration\":\"matches\",\"pattern\":\"latest\"}],\"params\":{}},
{\"disabled\":false,\"action\":\"retain\",\"scope_selectors\":{\"repository\":[{\"kind\":\"doublestar\",\"decoration\":\"repoMatches\",\"pattern\":\"**\"}]},\"tag_selectors\":[{\"kind\":\"doublestar\",\"decoration\":\"matches\",\"pattern\":\"**\"}],\"params\":{\"latestPushedK\":10}}
]
}" 2>/dev/null && echo " ✓ Tag retention policy created (keep latest + last 10 tags, daily)" || echo " ⚠ Could not create retention policy (non-fatal)"
fi
fi
echo ""
echo "=== Harbor Deploy Complete ==="
echo ""
echo " URL: https://registry.celestium.life"
echo " Login: admin / St0nks0racl3!"
echo ""
echo " Pods:"
kubectl get pods -n harbor-service