summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-01-15 21:31:45 +0200
committerPaul Buetow <paul@buetow.org>2026-01-15 21:31:45 +0200
commit7abd6361ddd487ded8baee5f3812af0135964abf (patch)
tree71856dc85bf1c856c99db3dee0ed20947654aec9
parente5e6a3baa70cab02360779079ed431607ea42f89 (diff)
feat: add automated demo scripts for Argo Rollouts
-rw-r--r--f3s/tracing-demo/Justfile18
-rwxr-xr-xf3s/tracing-demo/demo-abort-rollout.sh106
-rwxr-xr-xf3s/tracing-demo/demo-canary-rollout.sh171
-rwxr-xr-xf3s/tracing-demo/demo-menu.sh95
-rwxr-xr-xf3s/tracing-demo/demo-reset.sh63
5 files changed, 453 insertions, 0 deletions
diff --git a/f3s/tracing-demo/Justfile b/f3s/tracing-demo/Justfile
index b3b1eae..2d5620e 100644
--- a/f3s/tracing-demo/Justfile
+++ b/f3s/tracing-demo/Justfile
@@ -136,6 +136,24 @@ rollout-abort:
rollout-history:
kubectl argo rollouts history tracing-demo-frontend -n {{NAMESPACE}}
+# === Automated Demo Scripts ===
+
+# Run full automated canary rollout demo
+demo-canary:
+ @./demo-canary-rollout.sh
+
+# Run abort/rollback demo
+demo-abort:
+ @./demo-abort-rollout.sh
+
+# Reset rollout to clean state
+demo-reset:
+ @./demo-reset.sh
+
+# Interactive demo menu
+demo-menu:
+ @./demo-menu.sh
+
# Start demo (requires manual rollout trigger in another terminal)
rollout-demo:
@echo "Starting Argo Rollouts demo..."
diff --git a/f3s/tracing-demo/demo-abort-rollout.sh b/f3s/tracing-demo/demo-abort-rollout.sh
new file mode 100755
index 0000000..55c0c7f
--- /dev/null
+++ b/f3s/tracing-demo/demo-abort-rollout.sh
@@ -0,0 +1,106 @@
+#!/bin/bash
+# Argo Rollouts Abort Demo - Test rollback behavior
+
+NAMESPACE="services"
+ROLLOUT="tracing-demo-frontend"
+
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+BOLD='\033[1m'
+NC='\033[0m'
+
+info() { echo -e "${BLUE}ℹ${NC} $1"; }
+success() { echo -e "${GREEN}✓${NC} $1"; }
+step() { echo -e "\n${BOLD}=== $1 ===${NC}"; }
+
+step "Rollout Abort Demo"
+echo ""
+echo "This will:"
+echo " 1. Trigger a new canary rollout"
+echo " 2. Wait 20 seconds for canary to become ready"
+echo " 3. Abort the rollout mid-canary"
+echo " 4. Show that old version continues running"
+echo ""
+
+read -p "Start? (y/n) " -n 1 -r
+echo
+if [[ ! $REPLY =~ ^[Yy]$ ]]; then
+ exit 0
+fi
+
+# Trigger rollout
+step "Step 1: Triggering canary rollout..."
+TRIGGER_VALUE="$(date +%s)"
+kubectl patch rollout "$ROLLOUT" -n "$NAMESPACE" \
+ --type='json' \
+ -p='[{"op":"add","path":"/spec/template/spec/containers/0/env/-","value":{"name":"ROLLOUT_ABORT_TEST","value":"'$TRIGGER_VALUE'"}}]' \
+ > /dev/null
+
+success "Rollout triggered"
+echo ""
+
+# Wait for canary to start
+step "Step 2: Waiting for canary pod to become ready..."
+echo "Monitoring..."
+
+WAITED=0
+MAX_WAIT=30
+while [ $WAITED -lt $MAX_WAIT ]; do
+ READY=$(kubectl get rollout "$ROLLOUT" -n "$NAMESPACE" -o jsonpath='{.status.readyReplicas}')
+ UPDATED=$(kubectl get rollout "$ROLLOUT" -n "$NAMESPACE" -o jsonpath='{.status.updatedReplicas}')
+ STEP=$(kubectl get rollout "$ROLLOUT" -n "$NAMESPACE" -o jsonpath='{.status.currentStep}')
+
+ printf "\r[%02ds] Ready: %s, Updated: %s, Step: %s " $WAITED "$READY" "$UPDATED" "$STEP"
+
+ # Check if canary is ready (4 total ready = 3 stable + 1 canary)
+ if [ "$READY" = "4" ]; then
+ echo ""
+ success "Canary pod ready!"
+ break
+ fi
+
+ sleep 1
+ WAITED=$((WAITED + 1))
+done
+echo ""
+
+# Abort the rollout
+step "Step 3: Aborting rollout..."
+kubectl argo rollouts abort "$ROLLOUT" -n "$NAMESPACE" > /dev/null
+success "Rollout aborted"
+echo ""
+
+# Show status
+step "Step 4: Checking status after abort"
+sleep 2
+kubectl argo rollouts status "$ROLLOUT" -n "$NAMESPACE"
+echo ""
+
+# Show pods
+step "Pod Status After Abort"
+echo "Notice: Canary pod is gone, 3 stable pods still running"
+echo ""
+kubectl get pods -n "$NAMESPACE" -l app="$ROLLOUT" -o wide --no-headers | awk '{print $1, $3, $4}'
+echo ""
+
+step "Summary"
+cat << 'EOF'
+What happened:
+ ✓ Canary started (4 pods: 3 stable + 1 canary)
+ ✓ Abort command issued while in canary phase
+ ✓ Canary pods immediately terminated
+ ✓ Old 3 stable pods continue serving traffic
+ ✓ Status: Degraded (RolloutAborted)
+
+Benefits of abort:
+ • Zero downtime - old version never interrupted
+ • Safe to stop at any point
+ • No manual cleanup needed
+ • Can retry with different version
+
+To retry:
+ ./demo-canary-rollout.sh
+EOF
+echo ""
diff --git a/f3s/tracing-demo/demo-canary-rollout.sh b/f3s/tracing-demo/demo-canary-rollout.sh
new file mode 100755
index 0000000..ce570db
--- /dev/null
+++ b/f3s/tracing-demo/demo-canary-rollout.sh
@@ -0,0 +1,171 @@
+#!/bin/bash
+# Argo Rollouts Canary Demo - Fully Automated
+# Simulates a complete canary rollout with monitoring
+
+set -e
+
+NAMESPACE="services"
+ROLLOUT="tracing-demo-frontend"
+KUBE_CTX="$(kubectl config current-context)"
+
+# Colors
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+BOLD='\033[1m'
+NC='\033[0m'
+
+info() { echo -e "${BLUE}ℹ${NC} $1"; }
+success() { echo -e "${GREEN}✓${NC} $1"; }
+error() { echo -e "${RED}✗${NC} $1"; exit 1; }
+step() { echo -e "\n${BOLD}=== $1 ===${NC}"; }
+
+# Check prerequisites
+step "Checking Prerequisites"
+
+info "Cluster: $KUBE_CTX"
+
+if ! kubectl get pods -n cicd -l app.kubernetes.io/name=argo-rollouts &>/dev/null; then
+ error "Argo Rollouts controller not found. Install: cd argo-rollouts && just install"
+fi
+success "Argo Rollouts controller running"
+
+if ! kubectl get rollout "$ROLLOUT" -n "$NAMESPACE" &>/dev/null; then
+ error "Rollout $ROLLOUT not found in $NAMESPACE"
+fi
+success "Rollout $ROLLOUT found"
+
+if ! kubectl argo rollouts version &>/dev/null; then
+ error "kubectl argo rollouts plugin not installed"
+fi
+success "kubectl argo rollouts plugin available"
+
+# Current state
+step "Current Rollout State"
+kubectl argo rollouts status "$ROLLOUT" -n "$NAMESPACE"
+echo ""
+
+# Demo plan
+step "Demo Plan"
+cat << 'EOF'
+Timeline:
+ 0-15s: Canary pod starting (Step 0/3, SetWeight 33%)
+ 15-60s: Canary observing (Step 1/3, paused)
+ 60-90s: Auto-promoting (Step 2/3, SetWeight 100%)
+~90s: Complete (Status Healthy)
+
+What will be shown:
+ • Real-time rollout progress
+ • Pod replica counts
+ • Canary vs Stable pods
+ • Step progression
+EOF
+echo ""
+
+read -p "Start demo? (y/n) " -n 1 -r
+echo
+if [[ ! $REPLY =~ ^[Yy]$ ]]; then
+ info "Cancelled"
+ exit 0
+fi
+
+# Show initial pod state
+step "Initial Pod State"
+kubectl get pods -n "$NAMESPACE" -l app="$ROLLOUT" -o wide --no-headers | awk '{print $1, $3, $4}'
+echo ""
+
+# Trigger rollout
+step "Triggering Canary Rollout"
+info "Triggering rollout by adding env var..."
+
+TRIGGER_VALUE="$(date +%s)"
+kubectl patch rollout "$ROLLOUT" -n "$NAMESPACE" \
+ --type='json' \
+ -p='[{"op":"add","path":"/spec/template/spec/containers/0/env/-","value":{"name":"ROLLOUT_DEMO_V","value":"'$TRIGGER_VALUE'"}}]' \
+ > /dev/null
+
+success "Rollout triggered (v=$TRIGGER_VALUE)"
+echo ""
+
+# Monitor rollout
+step "Monitoring Rollout Progress"
+echo "Watching rollout for ~100 seconds..."
+echo ""
+
+START_TIME=$(date +%s)
+MAX_WAIT=120
+COMPLETE=0
+
+while true; do
+ ELAPSED=$(($(date +%s) - START_TIME))
+
+ # Get status
+ STATUS=$(kubectl argo rollouts status "$ROLLOUT" -n "$NAMESPACE" 2>/dev/null || echo "Error")
+ ROLLOUT_INFO=$(kubectl get rollout "$ROLLOUT" -n "$NAMESPACE" -o jsonpath='{.status.phase},{.status.currentStep},{.spec.strategy.canary.steps | length},{.status.canary.weights.canary.weight // 0},{.status.replicas},{.status.updatedReplicas},{.status.readyReplicas}' 2>/dev/null || echo "Unknown,0,3,0,0,0,0")
+
+ IFS=',' read -r PHASE STEP TOTAL_STEPS WEIGHT CURRENT UPDATED READY <<< "$ROLLOUT_INFO"
+
+ # Print progress line
+ printf "\r[%02d:%02ds] %s | Step %s/%s | Weight %s%% | Replicas: %s (updated:%s ready:%s) " \
+ $((ELAPSED / 60)) $((ELAPSED % 60)) "$PHASE" "$STEP" "$TOTAL_STEPS" "$WEIGHT" "$CURRENT" "$UPDATED" "$READY"
+
+ # Check if complete
+ if [ "$PHASE" = "Healthy" ] && [ "$STEP" = "$TOTAL_STEPS" ]; then
+ echo ""
+ COMPLETE=1
+ break
+ fi
+
+ # Check if exceeded max wait
+ if [ $ELAPSED -ge $MAX_WAIT ]; then
+ echo ""
+ error "Timeout waiting for rollout to complete"
+ fi
+
+ sleep 2
+done
+
+echo ""
+
+if [ $COMPLETE -eq 1 ]; then
+ success "Rollout completed successfully!"
+ echo ""
+fi
+
+# Show final state
+step "Final Rollout State"
+kubectl argo rollouts get rollout "$ROLLOUT" -n "$NAMESPACE"
+echo ""
+
+# Show final pods
+step "Final Pod State"
+kubectl get pods -n "$NAMESPACE" -l app="$ROLLOUT" -o wide --no-headers | awk '{print $1, $3, $4}'
+echo ""
+
+# Summary
+step "Demo Summary"
+echo "Total time: ${ELAPSED}s"
+echo ""
+cat << 'EOF'
+What happened:
+ 1. ✓ Canary pod created with new revision
+ 2. ✓ 1 canary pod + 3 stable pods = 33% traffic to new version
+ 3. ✓ Paused for 1 minute to observe metrics
+ 4. ✓ Auto-promoted to 100% (all 3 pods = new version)
+ 5. ✓ Old pods terminated
+
+This is progressive delivery:
+ • Zero downtime
+ • Validated before full rollout
+ • Automatic promotion if healthy
+ • Easy rollback if issues
+
+To test more:
+ • Run again: ./demo-canary-rollout.sh
+ • Abort: kubectl argo rollouts abort tracing-demo-frontend -n services
+ • Check logs: kubectl logs -n services -l app=tracing-demo-frontend -f
+ • View history: kubectl argo rollouts history tracing-demo-frontend -n services
+EOF
+echo ""
+success "Demo complete!"
diff --git a/f3s/tracing-demo/demo-menu.sh b/f3s/tracing-demo/demo-menu.sh
new file mode 100755
index 0000000..73a7f05
--- /dev/null
+++ b/f3s/tracing-demo/demo-menu.sh
@@ -0,0 +1,95 @@
+#!/bin/bash
+# Argo Rollouts Demo Menu - Choose demo scenario
+
+BOLD='\033[1m'
+BLUE='\033[0;34m'
+GREEN='\033[0;32m'
+NC='\033[0m'
+
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+
+show_menu() {
+ clear
+ echo -e "${BOLD}Argo Rollouts Demo Menu${NC}"
+ echo ""
+ echo "Choose a demo:"
+ echo ""
+ echo " 1) Run full canary rollout demo"
+ echo " • Triggers rollout"
+ echo " • Monitors 0-15s (canary), 15-60s (observe), 60-90s (promote)"
+ echo " • Shows final state"
+ echo ""
+ echo " 2) Abort rollout demo"
+ echo " • Triggers rollout"
+ echo " • Waits 20s for canary to be ready"
+ echo " • Aborts mid-canary"
+ echo " • Shows rollback behavior"
+ echo ""
+ echo " 3) Reset rollout"
+ echo " • Aborts any in-progress rollout"
+ echo " • Removes demo env vars"
+ echo " • Returns to clean state"
+ echo ""
+ echo " 4) Check rollout status"
+ echo " • Shows current state"
+ echo " • Shows pod replicas"
+ echo " • Shows recent history"
+ echo ""
+ echo " 5) Watch rollout (real-time)"
+ echo " • Opens live rollout viewer"
+ echo ""
+ echo " 0) Exit"
+ echo ""
+}
+
+check_status() {
+ echo ""
+ echo -e "${BOLD}Rollout Status:${NC}"
+ kubectl argo rollouts status tracing-demo-frontend -n services
+ echo ""
+ echo -e "${BOLD}Pod Replicas:${NC}"
+ kubectl get pods -n services -l app=tracing-demo-frontend -o wide --no-headers | awk '{print $1, $3, $4}'
+ echo ""
+ echo -e "${BOLD}Recent Revisions:${NC}"
+ kubectl argo rollouts history tracing-demo-frontend -n services | head -5
+ echo ""
+ read -p "Press enter to continue..."
+}
+
+watch_live() {
+ echo ""
+ echo -e "${BOLD}Live Rollout Viewer (Ctrl+C to exit)${NC}"
+ echo ""
+ kubectl argo rollouts get rollout tracing-demo-frontend -n services --watch
+}
+
+while true; do
+ show_menu
+ read -p "Select option: " choice
+
+ case $choice in
+ 1)
+ bash "$SCRIPT_DIR/demo-canary-rollout.sh"
+ ;;
+ 2)
+ bash "$SCRIPT_DIR/demo-abort-rollout.sh"
+ ;;
+ 3)
+ bash "$SCRIPT_DIR/demo-reset.sh"
+ ;;
+ 4)
+ check_status
+ ;;
+ 5)
+ watch_live
+ ;;
+ 0)
+ echo "Goodbye!"
+ exit 0
+ ;;
+ *)
+ echo "Invalid option"
+ sleep 1
+ ;;
+ esac
+done
diff --git a/f3s/tracing-demo/demo-reset.sh b/f3s/tracing-demo/demo-reset.sh
new file mode 100755
index 0000000..fbfa0bd
--- /dev/null
+++ b/f3s/tracing-demo/demo-reset.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+# Reset rollout to clean state
+
+NAMESPACE="services"
+ROLLOUT="tracing-demo-frontend"
+
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+BLUE='\033[0;34m'
+BOLD='\033[1m'
+NC='\033[0m'
+
+step() { echo -e "\n${BOLD}=== $1 ===${NC}"; }
+success() { echo -e "${GREEN}✓${NC} $1"; }
+
+step "Resetting Rollout"
+echo ""
+echo "This will:"
+echo " 1. Abort any in-progress rollout"
+echo " 2. Remove env vars added by demo scripts"
+echo " 3. Return rollout to clean state"
+echo ""
+
+read -p "Reset? (y/n) " -n 1 -r
+echo
+if [[ ! $REPLY =~ ^[Yy]$ ]]; then
+ exit 0
+fi
+
+step "Step 1: Aborting current rollout"
+kubectl argo rollouts abort "$ROLLOUT" -n "$NAMESPACE" 2>/dev/null || true
+sleep 2
+success "Aborted"
+
+step "Step 2: Removing demo env vars"
+# Get the current env vars and reconstruct without demo ones
+kubectl get rollout "$ROLLOUT" -n "$NAMESPACE" -o json | \
+ jq '.spec.template.spec.containers[0].env |= map(select(.name | test("ROLLOUT_") | not))' | \
+ kubectl apply -f - > /dev/null
+
+sleep 2
+success "Demo env vars removed"
+
+step "Step 3: Verifying clean state"
+echo "Waiting for rollout to stabilize..."
+sleep 5
+
+STATUS=$(kubectl argo rollouts status "$ROLLOUT" -n "$NAMESPACE")
+echo "$STATUS"
+echo ""
+
+step "Reset Complete"
+cat << 'EOF'
+Rollout is now reset to:
+ • Status: Healthy
+ • No pending rollouts
+ • No demo env vars
+ • Ready for next demo
+
+To run demo again:
+ ./demo-canary-rollout.sh
+EOF
+echo ""