Skip to content

Commit 6e9ab03

Browse files
committed
fix: fixes for issues found during local ut test for happy path for inplace
1 parent 20f6846 commit 6e9ab03

File tree

3 files changed

+116
-39
lines changed

3 files changed

+116
-39
lines changed

hack/lib-premiumv2-migration-common.sh

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ MIGRATION_FORCE_INPROGRESS_AFTER_MINUTES="${MIGRATION_FORCE_INPROGRESS_AFTER_MIN
2626
# Maximum PVC size (in GiB) eligible for migration (default 2TiB = 2048GiB). PVCs >= this are skipped.
2727
MAX_PVC_CAPACITY_GIB="${MAX_PVC_CAPACITY_GIB:-2048}"
2828
declare -a AUDIT_LINES=()
29+
MIGRATION_LABEL_KEY="${MIGRATION_LABEL%%=*}"
30+
MIGRATION_LABEL_VALUE="${MIGRATION_LABEL#*=}"
31+
BACKUP_ORIGINAL_PVC="${BACKUP_ORIGINAL_PVC:-true}"
32+
PVC_BACKUP_DIR="${PVC_BACKUP_DIR:-pvc-backups}"
2933

3034
# ---------- Timeouts ----------
3135
BIND_TIMEOUT_SECONDS="${BIND_TIMEOUT_SECONDS:-60}"
@@ -43,6 +47,8 @@ CREATED_BY_LABEL_KEY="${CREATED_BY_LABEL_KEY:-disk.csi.azure.com/created-by}"
4347
MIGRATION_TOOL_ID="${MIGRATION_TOOL_ID:-azuredisk-pv1-to-pv2-migrator}"
4448
MIGRATION_DONE_LABEL_KEY="${MIGRATION_DONE_LABEL_KEY:-disk.csi.azure.com/migration-done}"
4549
MIGRATION_DONE_LABEL_VALUE="${MIGRATION_DONE_LABEL_VALUE:-true}"
50+
MIGRATION_INPROGRESS_LABEL_KEY="${MIGRATION_INPROGRESS_LABEL_KEY:-disk.csi.azure.com/migration-inprogress}"
51+
MIGRATION_INPROGRESS_LABEL_VALUE="${MIGRATION_INPROGRESS_LABEL_VALUE:-true}"
4652

4753
audit_add() {
4854
[[ "$AUDIT_ENABLE" != "true" ]] && return 0
@@ -288,6 +294,7 @@ metadata:
288294
name: $csi_pv
289295
labels:
290296
${CREATED_BY_LABEL_KEY}: ${MIGRATION_TOOL_ID}
297+
${MIGRATION_LABEL_KEY}: "${MIGRATION_LABEL_VALUE}"
291298
annotations:
292299
pv.kubernetes.io/provisioned-by: disk.csi.azure.com
293300
spec:
@@ -561,11 +568,15 @@ extract_event_reason() {
561568
local ns="$1" pvc_name="$2"
562569
kcmd get events -n "$ns" -o json 2>/dev/null \
563570
| jq -r --arg name "$pvc_name" '
564-
.items
565-
| map(select(.involvedObject.name==$name
566-
and (.reason|test("SKUMigration(Completed|Progress|Started)"))))
567-
| sort_by(.lastTimestamp)
568-
| last?.reason // empty' 2>/dev/null || true
571+
[ .items[]
572+
| select(.involvedObject.name==$name
573+
and (.reason|test("^SKUMigration(Completed|Progress|Started)$")))
574+
| {reason, ts:(.lastTimestamp // .eventTime // .deprecatedLastTimestamp // .metadata.creationTimestamp // "")}
575+
] as $arr
576+
| if ($arr|length)>0
577+
then ($arr|sort_by(.ts)|last|.reason)
578+
else ""
579+
end'
569580
}
570581

571582
populate_pvcs() {
@@ -797,7 +808,7 @@ print_migration_cleanup_report() {
797808
local failed_header_printed=false
798809
local any=false
799810

800-
if [[ "${#MIG_PVCS[@]:-0}" -eq 0 ]]; then
811+
if ! (( ${#MIG_PVCS[@]} == 0 )); then
801812
warn "print_migration_cleanup_report: MIG_PVCS empty (nothing to report)."
802813
return 0
803814
fi

hack/premium-to-premiumv2-migrator-dualpvc.sh

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ IFS=$'\n\t'
44

55
SCRIPT_START_TS="$(date +'%Y-%m-%dT%H:%M:%S')"
66
SCRIPT_START_EPOCH="$(date +%s)"
7+
MODE=dual
78

89
# Declarations
910
declare -a MIG_PVCS
@@ -13,6 +14,20 @@ declare -A SC_SET
1314
declare -a PV2_CREATE_FAILURES
1415
declare -a PV2_BIND_TIMEOUTS
1516

17+
MIG_PVCS=()
18+
PREREQ_ISSUES=()
19+
CONFLICT_ISSUES=()
20+
PV2_CREATE_FAILURES=()
21+
PV2_BIND_TIMEOUTS=()
22+
23+
# (after array zeroing, before ensure_no_foreign_conflicts)
24+
safe_array_len() {
25+
local name="$1"
26+
# If array not declared (future refactor), return 0 instead of tripping set -u
27+
declare -p "$name" &>/dev/null || { echo 0; return; }
28+
eval "echo \${#$name[@]}"
29+
}
30+
1631
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
1732
. "${SCRIPT_DIR}/lib-premiumv2-migration-common.sh"
1833

@@ -33,48 +48,52 @@ populate_pvcs
3348
ensure_no_foreign_conflicts() {
3449
info "Checking for pre-existing conflicting objects not created by this tool..."
3550
if kcmd get volumesnapshotclass "$SNAPSHOT_CLASS" >/dev/null 2>&1; then
36-
if ! kcmd get volumesnapshotclass "$SNAPSHOT_CLASS" -o json \
37-
| jq -e --arg k "$CREATED_BY_LABEL_KEY" --arg v "$MIGRATION_TOOL_ID" '.metadata.labels[$k]==$v' >/dev/null; then
51+
if ! kcmd get volumesnapshotclass "$SNAPSHOT_CLASS" -o json | jq -e \
52+
--arg k "$CREATED_BY_LABEL_KEY" --arg v "$MIGRATION_TOOL_ID" \
53+
'.metadata.labels[$k]==$v' >/dev/null; then
3854
CONFLICT_ISSUES+=("VolumeSnapshotClass/$SNAPSHOT_CLASS (missing label)")
3955
fi
4056
fi
41-
for ENTRY in "${MIG_PVCS[@]:-}"; do
57+
for ENTRY in "${MIG_PVCS[@]}"; do
4258
local ns="${ENTRY%%|*}" pvc="${ENTRY##*|}"
43-
local pv2_pvc
59+
local pv2_pvc pv diskuri int_pvc int_pv snap
4460
pv2_pvc="$(name_pv2_pvc "$pvc")"
4561
if kcmd get pvc "$pv2_pvc" -n "$ns" >/dev/null 2>&1; then
46-
if ! kcmd get pvc "$pv2_pvc" -n "$ns" -o json \
47-
| jq -e --arg k "$CREATED_BY_LABEL_KEY" --arg v "$MIGRATION_TOOL_ID" '.metadata.labels[$k]==$v' >/dev/null; then
62+
if ! kcmd get pvc "$pv2_pvc" -n "$ns" -o json | jq -e \
63+
--arg k "$CREATED_BY_LABEL_KEY" --arg v "$MIGRATION_TOOL_ID" \
64+
'.metadata.labels[$k]==$v' >/dev/null; then
4865
CONFLICT_ISSUES+=("PVC/$ns/$pv2_pvc (pv2) missing label")
4966
fi
5067
fi
51-
local pv
5268
pv=$(kcmd get pvc "$pvc" -n "$ns" -o jsonpath='{.spec.volumeName}' 2>/dev/null || true)
5369
[[ -z "$pv" ]] && continue
54-
local diskuri
5570
diskuri=$(kcmd get pv "$pv" -o jsonpath='{.spec.azureDisk.diskURI}' 2>/dev/null || true)
5671
if [[ -n "$diskuri" ]]; then
57-
local int_pvc int_pv
5872
int_pvc="$(name_csi_pvc "$pvc")"
5973
int_pv="$(name_csi_pv "$pv")"
6074
if kcmd get pvc "$int_pvc" -n "$ns" >/dev/null 2>&1; then
61-
kcmd get pvc "$int_pvc" -n "$ns" -o json | jq -e --arg k "$CREATED_BY_LABEL_KEY" --arg v "$MIGRATION_TOOL_ID" '.metadata.labels[$k]==$v' >/dev/null || \
62-
CONFLICT_ISSUES+=("PVC/$ns/$int_pvc (intermediate) missing label")
75+
kcmd get pvc "$int_pvc" -n "$ns" -o json | jq -e \
76+
--arg k "$CREATED_BY_LABEL_KEY" --arg v "$MIGRATION_TOOL_ID" \
77+
'.metadata.labels[$k]==$v' >/dev/null || \
78+
CONFLICT_ISSUES+=("PVC/$ns/$int_pvc (intermediate) missing label")
6379
fi
6480
if kcmd get pv "$int_pv" >/dev/null 2>&1; then
65-
kcmd get pv "$int_pv" -o json | jq -e --arg k "$CREATED_BY_LABEL_KEY" --arg v "$MIGRATION_TOOL_ID" '.metadata.labels[$k]==$v' >/dev/null || \
66-
CONFLICT_ISSUES+=("PV/$int_pv (intermediate) missing label")
81+
kcmd get pv "$int_pv" -o json | jq -e \
82+
--arg k "$CREATED_BY_LABEL_KEY" --arg v "$MIGRATION_TOOL_ID" \
83+
'.metadata.labels[$k]==$v' >/dev/null || \
84+
CONFLICT_ISSUES+=("PV/$int_pv (intermediate) missing label")
6785
fi
6886
fi
69-
local snap
7087
snap="$(name_snapshot "$pv")"
7188
if kcmd get volumesnapshot "$snap" -n "$ns" >/dev/null 2>&1; then
72-
kcmd get volumesnapshot "$snap" -n "$ns" -o json | jq -e --arg k "$CREATED_BY_LABEL_KEY" --arg v "$MIGRATION_TOOL_ID" '.metadata.labels[$k]==$v' >/dev/null || \
73-
CONFLICT_ISSUES+=("VolumeSnapshot/$ns/$snap missing label")
89+
kcmd get volumesnapshot "$snap" -n "$ns" -o json | jq -e \
90+
--arg k "$CREATED_BY_LABEL_KEY" --arg v "$MIGRATION_TOOL_ID" \
91+
'.metadata.labels[$k]==$v' >/dev/null || \
92+
CONFLICT_ISSUES+=("VolumeSnapshot/$ns/$snap missing label")
7493
fi
7594
done
76-
if (( ${#CONFLICT_ISSUES[@]} > 0 )); then
77-
err "Conflict check failed (${#CONFLICT_ISSUES[@]} items)."
95+
if (( $(safe_array_len CONFLICT_ISSUES) > 0 )); then
96+
err "Conflict check failed ($(safe_array_len CONFLICT_ISSUES) items)."
7897
printf ' - %s\n' "${CONFLICT_ISSUES[@]}"
7998
exit 1
8099
fi
@@ -99,6 +118,7 @@ metadata:
99118
namespace: $ns
100119
labels:
101120
${CREATED_BY_LABEL_KEY}: ${MIGRATION_TOOL_ID}
121+
${MIGRATION_LABEL_KEY}: "${MIGRATION_LABEL_VALUE}"
102122
spec:
103123
accessModes:
104124
- ReadWriteOnce
@@ -130,14 +150,15 @@ EOF
130150
return 2
131151
}
132152

133-
extract_event_reason() { extract_event_reason "$@"; } # use common lib version
134-
135153
# ---------------- Discover Tagged PVCs ----------------
136154
populate_pvcs
137155

138156
# ------------- Pre-Req & Conflicts -------------
139157
print_combined_validation_report_and_exit_if_needed() {
140-
local prereq_count=${#PREREQ_ISSUES[@]} conflict_count=${#CONFLICT_ISSUES[@]}
158+
local prereq_count
159+
prereq_count=$(safe_array_len PREREQ_ISSUES)
160+
local conflict_count
161+
conflict_count=$(safe_array_len CONFLICT_ISSUES)
141162
if (( prereq_count==0 && conflict_count==0 )); then
142163
ok "Pre-req & conflict checks passed."
143164
return

hack/premium-to-premiumv2-migrator-inplace.sh

100644100755
Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ IFS=$'\n\t'
44

55
SCRIPT_START_TS="$(date +'%Y-%m-%dT%H:%M:%S')"
66
SCRIPT_START_EPOCH="$(date +%s)"
7+
MODE=inplace
78

89
# In-place rollback keys
910
ROLLBACK_PVC_YAML_ANN="${ROLLBACK_PVC_YAML_ANN:-disk.csi.azure.com/rollback-pvc-yaml}"
@@ -16,6 +17,21 @@ declare -a CONFLICT_ISSUES
1617
declare -A SC_SET
1718
declare -a ROLLBACK_FAILURES
1819

20+
# Explicit zeroing (defensive; avoids 'unbound variable' under set -u even if declarations are edited later)
21+
MIG_PVCS=()
22+
PREREQ_ISSUES=()
23+
CONFLICT_ISSUES=()
24+
ROLLBACK_FAILURES=()
25+
26+
# Helper: safe length (avoids accidental nounset trip if future refactor removes a declare)
27+
safe_array_len() {
28+
# usage: safe_array_len arrayName
29+
local name="$1"
30+
declare -p "$name" &>/dev/null || { echo 0; return; }
31+
# indirect expansion
32+
eval "echo \${#$name[@]}"
33+
}
34+
1935
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
2036
. "${SCRIPT_DIR}/lib-premiumv2-migration-common.sh"
2137

@@ -33,39 +49,40 @@ ensure_snapshot_class # from common lib
3349
ensure_no_foreign_conflicts() {
3450
info "Checking for pre-existing conflicting objects not created by this tool..."
3551
if kcmd get volumesnapshotclass "$SNAPSHOT_CLASS" >/dev/null 2>&1; then
36-
if ! kcmd get volumesnapshotclass "$SNAPSHOT_CLASS" -o json \
37-
| jq -e --arg k "$CREATED_BY_LABEL_KEY" --arg v "$MIGRATION_TOOL_ID" '.metadata.labels[$k]==$v' >/dev/null; then
52+
if ! kcmd get volumesnapshotclass "$SNAPSHOT_CLASS" -o json | jq -e \
53+
--arg k "$CREATED_BY_LABEL_KEY" --arg v "$MIGRATION_TOOL_ID" \
54+
'.metadata.labels[$k]==$v' >/dev/null; then
3855
CONFLICT_ISSUES+=("VolumeSnapshotClass/$SNAPSHOT_CLASS (missing label)")
3956
fi
4057
fi
41-
for ENTRY in "${MIG_PVCS[@]:-}"; do
58+
for ENTRY in "${MIG_PVCS[@]}"; do
4259
local ns="${ENTRY%%|*}" pvc="${ENTRY##*|}"
43-
local pv
60+
local pv snap
4461
pv=$(kcmd get pvc "$pvc" -n "$ns" -o jsonpath='{.spec.volumeName}' 2>/dev/null || true)
4562
[[ -z "$pv" ]] && continue
46-
local snap
4763
snap="$(name_snapshot "$pv")"
4864
if kcmd get volumesnapshot "$snap" -n "$ns" >/dev/null 2>&1; then
49-
kcmd get volumesnapshot "$snap" -n "$ns" -o json | jq -e --arg k "$CREATED_BY_LABEL_KEY" --arg v "$MIGRATION_TOOL_ID" '.metadata.labels[$k]==$v' >/dev/null || \
50-
CONFLICT_ISSUES+=("VolumeSnapshot/$ns/$snap missing label")
65+
kcmd get volumesnapshot "$snap" -n "$ns" -o json | jq -e \
66+
--arg k "$CREATED_BY_LABEL_KEY" --arg v "$MIGRATION_TOOL_ID" \
67+
'.metadata.labels[$k]==$v' >/dev/null || \
68+
CONFLICT_ISSUES+=("VolumeSnapshot/$ns/$snap missing label")
5169
fi
5270
done
53-
if (( ${#CONFLICT_ISSUES[@]} > 0 )); then
54-
err "Conflict check failed (${#CONFLICT_ISSUES[@]} items)."
71+
if (( $(safe_array_len CONFLICT_ISSUES) > 0 )); then
72+
err "Conflict check failed ($(safe_array_len CONFLICT_ISSUES) items)."
5573
printf ' - %s\n' "${CONFLICT_ISSUES[@]}"
5674
exit 1
5775
fi
5876
ok "No conflicting pre-existing objects detected."
5977
}
6078

61-
extract_event_reason() { extract_event_reason "$@"; } # use common lib version
62-
6379
# ---------------- Discover Tagged PVCs ----------------
6480
populate_pvcs
6581

6682
# ---------------- Pre-Requisite Validation (mirrors dual script) ----------------
6783
print_combined_validation_report_and_exit_if_needed() {
68-
local prereq_count=${#PREREQ_ISSUES[@]} conflict_count=${#CONFLICT_ISSUES[@]}
84+
local prereq_count=$(safe_array_len PREREQ_ISSUES)
85+
local conflict_count=$(safe_array_len CONFLICT_ISSUES)
6986
if (( prereq_count==0 && conflict_count==0 )); then
7087
ok "Pre-req & conflict checks passed."
7188
return
@@ -138,6 +155,33 @@ create_pv2_inplace() {
138155

139156
ensure_reclaim_policy_retain "$pv_before"
140157

158+
# -------- Raw PVC backup (full YAML) prior to deletion --------
159+
if [[ "$BACKUP_ORIGINAL_PVC" == "true" ]]; then
160+
local ts backup_ns_dir backup_file tmp_file
161+
ts="$(date +%Y%m%d-%H%M%S)"
162+
backup_ns_dir="${PVC_BACKUP_DIR}/${ns}"
163+
mkdir -p "$backup_ns_dir"
164+
tmp_file="${backup_ns_dir}/${pvc}-${ts}.yaml.tmp"
165+
backup_file="${backup_ns_dir}/${pvc}-${ts}.yaml"
166+
info "Backing up original PVC $ns/$pvc to $backup_file"
167+
if ! kcmd get pvc "$pvc" -n "$ns" -o yaml >"$tmp_file" 2>/dev/null; then
168+
err "Failed to fetch PVC $ns/$pvc for backup; skipping migration of this PVC."
169+
audit_add "PersistentVolumeClaim" "$pvc" "$ns" "backup-failed" "kubectl get pvc $pvc -n $ns -o yaml" "dest=$backup_file reason=kubectlError"
170+
return 1
171+
fi
172+
if [[ ! -s "$tmp_file" ]] || ! grep -q '^kind: *PersistentVolumeClaim' "$tmp_file"; then
173+
err "Backup validation failed for $ns/$pvc (empty or malformed); skipping migration."
174+
rm -f "$tmp_file"
175+
audit_add "PersistentVolumeClaim" "$pvc" "$ns" "backup-invalid" "kubectl get pvc $pvc -n $ns -o yaml" "dest=$backup_file reason=validation"
176+
return 1
177+
fi
178+
mv "$tmp_file" "$backup_file"
179+
audit_add "PersistentVolumeClaim" "$pvc" "$ns" "backup" "rm -f $backup_file" "dest=$backup_file size=$(wc -c <"$backup_file")B"
180+
else
181+
info "BACKUP_ORIGINAL_PVC=false -> skipping raw PVC backup for $ns/$pvc"
182+
fi
183+
# ---------------------------------------------------------------
184+
141185
info "Deleting original PVC $ns/$pvc (PV retained for rollback)"
142186
kcmd delete pvc "$pvc" -n "$ns" --wait=true
143187
audit_add "PersistentVolumeClaim" "$pvc" "$ns" "delete" "N/A" "stage=replace retainedPV=${pv_before}"
@@ -158,6 +202,7 @@ metadata:
158202
namespace: ${ns}
159203
labels:
160204
${CREATED_BY_LABEL_KEY}: ${MIGRATION_TOOL_ID}
205+
${MIGRATION_LABEL_KEY}: "${MIGRATION_LABEL_VALUE}"
161206
annotations:
162207
${ROLLBACK_PVC_YAML_ANN}: "${encoded_spec}"
163208
${ROLLBACK_ORIG_PV_ANN}: "${pv_before}"

0 commit comments

Comments
 (0)