Skip to content
Back to skills

Operations

ASecurity

Guide the operator through Method 1 switchover: disable auto-import, stop Thanos, verify sync, and activate managed clusters via passive restore. > **Reference**: [docs/ACM_SWITCHOVER_RUNBOOK.md — Steps 2-5](../../../docs/ACM_SWITCHOVER_RUNBOOK.md#method-1-continuous-passive-restore-activation-path) ---

  • 3 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 3, 2026
devopsgobashkubernetesapi

Works with

  • api

Security analysis

A100/100

Pro scans all 9 files and shows the line behind each finding

Scanned September 3, 2026

npx -y skills add tomazb/rh-acm-switchover --skill operations --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Operations?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Operations
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tomazb-operations-rh-acm-switchover/badge)](https://www.skillsdirectory.com/skills/tomazb-operations-rh-acm-switchover)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# Activate Passive Restore (Method 1)

Guide the operator through Method 1 switchover: disable auto-import, stop Thanos, verify sync, and activate managed clusters via passive restore.

> **Reference**: [docs/ACM_SWITCHOVER_RUNBOOK.md — Steps 2-5](../../../docs/ACM_SWITCHOVER_RUNBOOK.md#method-1-continuous-passive-restore-activation-path)

---

## Prerequisites Check

Before starting, confirm:
- [ ] Backups are paused on primary hub (see [pause-backups.skill.md](pause-backups.skill.md))
- [ ] Passive restore is running on secondary hub
- [ ] Both kubeconfig contexts are available

---

## Step 2: Disable Auto-Import on Primary Hub

> This prevents the old hub from trying to recover clusters after switchover

### Apply disable-auto-import annotation

**Batch command (all clusters except local-cluster):**

```bash
for cluster in $(oc get managedcluster.cluster.open-cluster-management.io -o name --context <primary> | grep -v '/local-cluster$'); do
  echo "Annotating $cluster"
  oc annotate $cluster import.open-cluster-management.io/disable-auto-import='' --context <primary>
done
```

### Verify annotations applied

```bash
oc get managedcluster.cluster.open-cluster-management.io --context <primary> \
  -o custom-columns=NAME:.metadata.name,DISABLE-IMPORT:.metadata.annotations.import\\.open-cluster-management\\.io/disable-auto-import
```

**Decision Tree:**
- ✅ All clusters (except local-cluster) show annotation → Proceed
- ❌ Some missing → Re-run annotation command for missing clusters

---

## Step 3: Stop Thanos Compactor on Primary Hub

> Prevents write conflicts on shared object storage during switchover

```bash
oc scale statefulset observability-thanos-compact \
  -n open-cluster-management-observability --context <primary> --replicas=0
```

### Verify compactor stopped

```bash
oc get pods -n open-cluster-management-observability --context <primary> \
  -l app.kubernetes.io/name=thanos-compact --field-selector=status.phase=Running --no-headers | wc -l
# Should return: 0
```

### Optional: Stop Observatorium API too

> Recommended to avoid any write contention during switchover window

```bash
oc scale deployment observability-observatorium-api \
  -n open-cluster-management-observability --context <primary> --replicas=0
```

> **⚠️ Scaling is temporary:** The MCO operator will re-scale Thanos and Observatorium back to defaults within minutes. If the old hub will remain as a long-lived secondary, you must delete the MCO object — see [verify-switchover.skill.md](verify-switchover.skill.md) "Optional: Disable Observability on Old Hub".

---

## Step 4: Verify Passive Restore on Secondary Hub

### Check passive sync status

```bash
oc get restore.cluster.open-cluster-management.io restore-acm-passive-sync \
  -n open-cluster-management-backup --context <secondary>
```

**Expected output:**
```
NAME                       PHASE     MESSAGE
restore-acm-passive-sync   Enabled   Velero restores have run to completion, restore will continue to sync with new backups
```

### Check last restored backup timestamps

```bash
# Get restored backup names
oc get restore.cluster.open-cluster-management.io restore-acm-passive-sync \
  -n open-cluster-management-backup --context <secondary> \
  -o jsonpath='{.status.veleroCredentialsRestoreName}'

oc get restore.cluster.open-cluster-management.io restore-acm-passive-sync \
  -n open-cluster-management-backup --context <secondary> \
  -o jsonpath='{.status.veleroResourcesRestoreName}'
```

### Compare with latest backups from primary

```bash
for s in $(oc get backup.velero.io -n open-cluster-management-backup --context <primary> -o json \
  | jq -r '.items[].metadata.labels["velero.io/schedule-name"]' | sort -u); do
  echo -n "$s: "
  oc get backup.velero.io -n open-cluster-management-backup --context <primary> \
    -l velero.io/schedule-name="$s" \
    --sort-by=.metadata.creationTimestamp --no-headers | tail -n1 | awk '{print $1 " (" $2 ")"}'
done
```

**Decision Tree:**
- ✅ Passive sync shows latest backups → Proceed to activation
- ⚠️ Sync is behind → Wait 5-10 minutes, recheck
- ❌ Passive sync not running → Consider [activate-full-restore.skill.md](activate-full-restore.skill.md)

---

## Step 4a (ACM 2.14+ with ImportOnly): Apply immediate-import annotations

> If the destination hub is using the default `ImportOnly` strategy, apply immediate-import to ensure clusters re-import.

```bash
oc get managedcluster.cluster.open-cluster-management.io -o name --context <secondary> | \
  grep -v '/local-cluster$' | \
  xargs -I{} oc annotate {} import.open-cluster-management.io/immediate-import='' --overwrite --context <secondary>
```

---

## Step 4b (ACM 2.14+ with existing clusters): Set ImportAndSync (optional)

> Only needed if secondary hub has non-local-cluster ManagedClusters AND you plan to switch back later

Ask: **"Does your secondary hub have existing managed clusters (besides local-cluster)?"**

```bash
oc get managedcluster.cluster.open-cluster-management.io --context <secondary> --no-headers | awk '$1 != "local-cluster" {print}'
```

**Decision Tree:**
- No clusters found → Skip this step
- Clusters exist → Apply ConfigMap:

```bash
oc apply --context <secondary> -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: import-controller-config
  namespace: multicluster-engine
data:
  autoImportStrategy: ImportAndSync
EOF
```

> **Note**: This will be removed in post-activation Step 7. Use only for planned switchback scenarios.

---

## Step 5: Activate Managed Clusters

> ⚠️ **CRITICAL**: This is the point of no return for activation

### Option A: Patch Existing Restore (Recommended)

```bash
oc patch restore.cluster.open-cluster-management.io restore-acm-passive-sync \
  -n open-cluster-management-backup --context <secondary> \
  --type='merge' \
  -p '{"spec":{"veleroManagedClustersBackupName":"latest"}}'
```

### Monitor activation progress

```bash
# Watch for transition to Finished state (Ctrl+C to exit)
oc get restore.cluster.open-cluster-management.io restore-acm-passive-sync \
  -n open-cluster-management-backup --context <secondary> -w
```

**Expected final state:**
```
NAME                       PHASE      MESSAGE
restore-acm-passive-sync   Finished   All Velero restores have run successfully
```

### Alternative Option B: Delete and Create New Restore

If patching fails or you prefer a clean activation:

```bash
# Delete existing
oc delete restore.cluster.open-cluster-management.io restore-acm-passive-sync \
  -n open-cluster-management-backup --context <secondary>

# Wait for deletion to complete
until ! oc get restore.cluster.open-cluster-management.io restore-acm-passive-sync \
  -n open-cluster-management-backup --context <secondary> &>/dev/null; do
  echo "Waiting for restore deletion..."
  sleep 2
done

# Create activation restore
oc apply --context <secondary> -f - <<EOF
apiVersion: cluster.open-cluster-management.io/v1beta1
kind: Restore
metadata:
  name: restore-acm-activate
  namespace: open-cluster-management-backup
spec:
  cleanupBeforeRestore: CleanupRestored
  veleroManagedClustersBackupName: latest
  veleroCredentialsBackupName: skip
  veleroResourcesBackupName: skip
EOF

# Monitor
oc get restore.cluster.open-cluster-management.io restore-acm-activate \
  -n open-cluster-management-backup --context <secondary> -w

# If Phase=FinishedWithErrors, the controller may still see the deleted restore as active.
# Confirm the passive restore is fully gone, then delete/recreate restore-acm-activate.
```

---

## What If...

### "Restore is stuck in Running state"

See [troubleshooting/restore-stuck.skill.md](../troubleshooting/restore-stuck.skill.md)

### "Patch command returns error"

Check restore exists:
```bash
oc get restore.cluster.open-cluster-management.io -n open-cluster-management-backup --context <secondary>
```

If name differs, adjust command accordingly.

### "I used the wrong restore name"

Find correct name:
```bash
oc get restore.cluster.open-cluster-management.io -n open-cluster-management-backup --context <secondary>
```

Look for one with `syncRestoreWithNewBackups: true` in spec.

---

## Confirmation

Before proceeding, confirm:
- [ ] Restore shows `Phase=Finished`
- [ ] No errors in restore events

---

## Next Step

Proceed to: [verify-switchover.skill.md](verify-switchover.skill.md) (Post-Activation Verification)

Files in this skill

  • activate-full-restore.skill.md5.8 KB
  • activate-passive-restore.skill.md8.2 KB
  • decommission.skill.md6.8 KB
  • enable-backups.skill.md6.4 KB
  • pause-backups.skill.md4.6 KB
  • preflight-validation.skill.md7.8 KB
  • rollback.skill.md7.8 KB
  • verify-switchover.skill.md6.1 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.