Skip to content

Commit b10fc10

Browse files
committed
ci: nested SDS setup only (prepare+cleanup); remove E2E tests and report; restore jump-host; stabilize SDS bring-up (MPO + explicit ModuleConfigs + CRD‑compatible LVG + safe default SC patch)
Signed-off-by: Anton Yachmenev <[email protected]>
1 parent 744dba8 commit b10fc10

36 files changed

+3047
-75
lines changed

.github/workflows/e2e-matrix.yml

Lines changed: 206 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,6 @@ on:
2727
- cron: "30 2 * * *"
2828
workflow_dispatch:
2929
inputs:
30-
profiles:
31-
description: "Storage profiles (comma-separated): sds, cephrbd"
32-
required: false
33-
default: "sds,cephrbd"
3430
timeout:
3531
description: "Ginkgo timeout (e.g. 2h, 4h)"
3632
required: false
@@ -43,45 +39,71 @@ env:
4339
E2E_K8S_URL: https://api.e2e.virtlab.flant.com
4440

4541
jobs:
46-
setup:
47-
name: Setup Profiles
42+
# ============================================
43+
# 1. SETUP - Environment preparation
44+
# ============================================
45+
setup-nested-envs:
46+
name: Setup Nested Envs
4847
runs-on: ubuntu-latest
48+
concurrency:
49+
group: setup-nested-envs-${{ github.ref }}
50+
cancel-in-progress: true
51+
env:
52+
PROFILE: sds-replicated-volume
4953
outputs:
50-
profiles: ${{ steps.profiles.outputs.profiles }}
54+
run_id: ${{ steps.prep.outputs.run_id }}
5155
steps:
5256
- uses: actions/checkout@v4
5357

54-
- name: Load storage profiles
55-
id: profiles
58+
- name: Load storage profile
59+
id: load
5660
run: |
57-
# Single profile: sds with storage class sds-replicated-volume
58-
echo 'profiles=["sds"]' >> "$GITHUB_OUTPUT"
61+
cd ci/dvp-e2e
62+
# Map sds-replicated-volume to sds profile from profiles.json
63+
PROFILE=$(jq -r '.[0].name' profiles.json)
64+
echo "profile=$PROFILE" >> "$GITHUB_OUTPUT"
65+
echo "Will test profile: $PROFILE (mapped from sds-replicated-volume)"
5966
60-
- name: Print matrix
67+
- name: Prepare run context
68+
id: prep
6169
run: |
62-
echo "Will test profiles: ${{ steps.profiles.outputs.profiles }}"
70+
RUN_ID="nightly-nested-e2e-sds-$(date +%H%M%S)"
71+
echo "run_id=$RUN_ID" >> "$GITHUB_OUTPUT"
72+
mkdir -p ./tmp/run-context
73+
echo "profile: ${PROFILE}" > ./tmp/run-context/config.yaml
74+
echo "run_id: ${RUN_ID}" >> ./tmp/run-context/config.yaml
75+
echo "timestamp: $(date -Iseconds)" >> ./tmp/run-context/config.yaml
6376
77+
- name: Upload run context
78+
uses: actions/upload-artifact@v4
79+
with:
80+
name: run-context-${{ steps.prep.outputs.run_id }}
81+
path: ./tmp/run-context
82+
83+
# ============================================
84+
# 2. PREPARE - Cluster preparation
85+
# ============================================
6486
prepare:
65-
name: Matrix Setup (${{ matrix.profile }})
66-
needs: [setup]
87+
name: Prepare Cluster
88+
needs: [setup-nested-envs]
6789
runs-on: ubuntu-latest
6890
timeout-minutes: 300
6991
concurrency:
70-
group: prepare-${{ github.ref }}-${{ matrix.profile }}
92+
group: prepare-${{ github.ref }}-sds-replicated-volume
7193
cancel-in-progress: true
72-
strategy:
73-
fail-fast: false
74-
matrix:
75-
profile: ${{ fromJson(needs.setup.outputs.profiles) }}
76-
7794
env:
95+
PROFILE: sds-replicated-volume
7896
GO_VERSION: "1.24.6"
7997
TMP_ROOT: ${{ github.workspace }}/ci/dvp-e2e/tmp
80-
STORAGE_CLASS: sds-replicated-volume
98+
LOOP_WEBHOOK: ${{ secrets.LOOP_WEBHOOK_URL || secrets.LOOP_WEBHOOK }}
99+
LOOP_CHANNEL: ${{ secrets.LOOP_CHANNEL || 'test-virtualization-loop-alerts' }} # TODO: replace with channel secret after successful run
81100

82101
outputs:
83102
run_id: ${{ steps.prep.outputs.run_id }}
84-
storage_class: ${{ env.STORAGE_CLASS }}
103+
storage_class: ${{ steps.profile-config.outputs.storage_class }}
104+
image_storage_class: ${{ steps.profile-config.outputs.image_storage_class }}
105+
snapshot_storage_class: ${{ steps.profile-config.outputs.snapshot_storage_class }}
106+
attach_disk_size: ${{ steps.profile-config.outputs.attach_disk_size }}
85107

86108
steps:
87109
- uses: actions/checkout@v4
@@ -102,7 +124,7 @@ jobs:
102124
- name: Install kubectl
103125
uses: azure/setup-kubectl@v4
104126
with:
105-
version: 'latest'
127+
version: "latest"
106128

107129
- name: Install Deckhouse CLI
108130
env:
@@ -123,13 +145,20 @@ jobs:
123145
curl -L -o /usr/local/bin/yq https://github.com/mikefarah/yq/releases/download/v4.44.1/yq_linux_amd64
124146
chmod +x /usr/local/bin/yq
125147
148+
- name: Restore run context
149+
uses: actions/download-artifact@v4
150+
with:
151+
name: run-context-${{ needs.setup-nested-envs.outputs.run_id }}
152+
path: .
153+
126154
- name: Prepare environment
127155
id: prep
128156
run: |
129-
RUN_ID="nightly-nested-e2e-${{ matrix.profile }}-$(date +%H%M)"
157+
RUN_ID="${{ needs.setup-nested-envs.outputs.run_id }}"
130158
echo "run_id=$RUN_ID" >> "$GITHUB_OUTPUT"
131159
echo "RUN_ID=$RUN_ID" >> "$GITHUB_ENV"
132-
echo "PROFILE=${{ matrix.profile }}" >> "$GITHUB_ENV"
160+
# Map sds-replicated-volume to sds for profile config
161+
echo "PROFILE=sds" >> "$GITHUB_ENV"
133162
echo "TMP_ROOT=${{ env.TMP_ROOT }}" >> "$GITHUB_ENV"
134163
mkdir -p "${{ env.TMP_ROOT }}/shared" "${{ env.TMP_ROOT }}/matrix-logs"
135164
@@ -169,12 +198,154 @@ jobs:
169198
RUN_DIR="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}"
170199
echo "VALUES_TEMPLATE_FILE=${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/values.yaml" >> $GITHUB_ENV
171200
201+
- name: Configure registry auth (REGISTRY_DOCKER_CFG)
202+
run: |
203+
prod_user="${{ secrets.PROD_READ_REGISTRY_USER }}"
204+
prod_pass="${{ secrets.PROD_READ_REGISTRY_PASSWORD }}"
205+
dev_user="${{ secrets.BOOTSTRAP_DEV_REGISTRY_LOGIN }}"
206+
dev_pass="${{ secrets.BOOTSTRAP_DEV_REGISTRY_PASSWORD }}"
207+
echo "::add-mask::$prod_user"
208+
echo "::add-mask::$prod_pass"
209+
echo "::add-mask::$dev_user"
210+
echo "::add-mask::$dev_pass"
211+
prod_auth_b64=$(printf '%s:%s' "$prod_user" "$prod_pass" | base64 | tr -d '\n')
212+
dev_auth_b64=$(printf '%s:%s' "$dev_user" "$dev_pass" | base64 | tr -d '\n')
213+
docker_cfg=$(printf '{"auths":{"registry.deckhouse.io":{"auth":"%s"},"dev-registry.deckhouse.io":{"auth":"%s"}}}' "$prod_auth_b64" "$dev_auth_b64")
214+
docker_cfg_b64=$(printf '%s' "$docker_cfg" | base64 | tr -d '\n')
215+
echo "::add-mask::$docker_cfg_b64"
216+
{
217+
echo "REGISTRY_DOCKER_CFG=$docker_cfg_b64"
218+
echo "DECKHOUSE_REGISTRY_USER=$prod_user"
219+
echo "DECKHOUSE_REGISTRY_PASSWORD=$prod_pass"
220+
} >> "$GITHUB_ENV"
221+
222+
- name: Inject REGISTRY_DOCKER_CFG into values.yaml
223+
working-directory: ci/dvp-e2e
224+
run: |
225+
yq eval --inplace '.deckhouse.registryDockerCfg = strenv(REGISTRY_DOCKER_CFG)' "${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/values.yaml"
226+
227+
- name: Docker login to Deckhouse registry
228+
uses: docker/login-action@v3
229+
with:
230+
registry: registry.deckhouse.io
231+
username: ${{ env.DECKHOUSE_REGISTRY_USER }}
232+
password: ${{ env.DECKHOUSE_REGISTRY_PASSWORD }}
233+
234+
- name: Docker login to dev-registry
235+
uses: docker/login-action@v3
236+
with:
237+
registry: ${{ vars.DEV_REGISTRY }}
238+
username: ${{ secrets.BOOTSTRAP_DEV_REGISTRY_LOGIN }}
239+
password: ${{ secrets.BOOTSTRAP_DEV_REGISTRY_PASSWORD }}
240+
172241
- name: Configure storage profile
173242
working-directory: ci/dvp-e2e
243+
id: profile-config
244+
env:
245+
PROFILE: sds
174246
run: |
175-
# Set storage profile to sds with storage class sds-replicated-volume
247+
# Get storage class configuration from profiles.json
248+
PROFILE_CONFIG=$(./scripts/get_profile_config.sh "${PROFILE}")
249+
250+
# Parse the output more carefully
251+
STORAGE_CLASS=$(echo "$PROFILE_CONFIG" | grep "^STORAGE_CLASS=" | cut -d'=' -f2)
252+
IMAGE_STORAGE_CLASS=$(echo "$PROFILE_CONFIG" | grep "^IMAGE_STORAGE_CLASS=" | cut -d'=' -f2)
253+
SNAPSHOT_STORAGE_CLASS=$(echo "$PROFILE_CONFIG" | grep "^SNAPSHOT_STORAGE_CLASS=" | cut -d'=' -f2)
254+
ATTACH_DISK_SIZE=$(echo "$PROFILE_CONFIG" | grep "^ATTACH_DISK_SIZE=" | cut -d'=' -f2)
255+
256+
echo "Profile: ${PROFILE}"
257+
echo "Storage Class: ${STORAGE_CLASS}"
258+
echo "Image Storage Class: ${IMAGE_STORAGE_CLASS}"
259+
echo "Snapshot Storage Class: ${SNAPSHOT_STORAGE_CLASS}"
260+
echo "Attach Disk Size: ${ATTACH_DISK_SIZE}"
261+
262+
# Export variables safely
263+
echo "STORAGE_CLASS=${STORAGE_CLASS}" >> $GITHUB_ENV
264+
echo "IMAGE_STORAGE_CLASS=${IMAGE_STORAGE_CLASS}" >> $GITHUB_ENV
265+
echo "SNAPSHOT_STORAGE_CLASS=${SNAPSHOT_STORAGE_CLASS}" >> $GITHUB_ENV
266+
echo "ATTACH_DISK_SIZE=${ATTACH_DISK_SIZE}" >> $GITHUB_ENV
267+
echo "storage_class=$STORAGE_CLASS" >> $GITHUB_OUTPUT
268+
echo "image_storage_class=$IMAGE_STORAGE_CLASS" >> $GITHUB_OUTPUT
269+
echo "snapshot_storage_class=$SNAPSHOT_STORAGE_CLASS" >> $GITHUB_OUTPUT
270+
echo "attach_disk_size=$ATTACH_DISK_SIZE" >> $GITHUB_OUTPUT
271+
# Pass storage profile into run values for Helm templates
176272
PROFILE='sds' yq eval --inplace '.storageProfile = strenv(PROFILE)' "${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/values.yaml"
177-
echo "Configured storage profile: sds with storage class: ${STORAGE_CLASS}"
273+
# Effective disk SC used for worker data disks (prefer image SC when set)
274+
EFF_DISK_SC=${IMAGE_STORAGE_CLASS:-$STORAGE_CLASS}
275+
echo "EFFECTIVE_DISK_SC=${EFF_DISK_SC}" >> $GITHUB_ENV
276+
277+
- name: Install infra (namespace/RBAC/ingress)
278+
working-directory: ci/dvp-e2e
279+
run: |
280+
USE_GH_SSH_KEYS=true SSH_FILE_NAME=id_ed task render-infra \
281+
TMP_DIR="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}" \
282+
VALUES_FILE="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/values.yaml" \
283+
PARENT_KUBECONFIG="${KUBECONFIG}" \
284+
SSH_FILE_NAME="id_ed"
285+
USE_GH_SSH_KEYS=true SSH_FILE_NAME=id_ed task infra-deploy \
286+
TMP_DIR="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}" \
287+
VALUES_FILE="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/values.yaml" \
288+
PARENT_KUBECONFIG="${KUBECONFIG}" \
289+
SSH_FILE_NAME="id_ed"
290+
291+
- name: Bootstrap nested cluster (via jump-host)
292+
working-directory: ci/dvp-e2e
293+
run: |
294+
echo "🚀 dhctl bootstrap (profile: sds-replicated-volume -> sds)"
295+
task dhctl-bootstrap \
296+
TMP_DIR="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}" \
297+
VALUES_FILE="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/values.yaml" \
298+
PARENT_KUBECONFIG="${KUBECONFIG}" \
299+
SSH_FILE_NAME="id_ed" \
300+
TARGET_STORAGE_CLASS="ceph-pool-r2-csi-rbd-immediate"
301+
302+
- name: Attach data disks to worker VMs using hotplug
303+
working-directory: ci/dvp-e2e
304+
run: |
305+
task infra:attach-storage-disks-hotplug \
306+
TMP_DIR="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}" \
307+
VALUES_FILE="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/values.yaml" \
308+
PARENT_KUBECONFIG="${KUBECONFIG}" \
309+
DISK_SIZE="${ATTACH_DISK_SIZE:-10Gi}" \
310+
STORAGE_CLASS="ceph-pool-r2-csi-rbd-immediate" \
311+
DISK_COUNT="2"
312+
313+
- name: Build nested kubeconfig
314+
working-directory: ci/dvp-e2e
315+
run: |
316+
task nested:kubeconfig \
317+
TMP_DIR="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}" \
318+
VALUES_FILE="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/values.yaml" \
319+
NAMESPACE="${{ env.RUN_ID }}" \
320+
SSH_DIR="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/ssh" \
321+
SSH_FILE_NAME="id_ed" \
322+
NESTED_DIR="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/nested" \
323+
NESTED_KUBECONFIG="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/nested/kubeconfig" \
324+
PARENT_KUBECONFIG="${KUBECONFIG}"
325+
326+
- name: Configure storage classes
327+
working-directory: ci/dvp-e2e
328+
run: |
329+
echo "💾 Configuring storage classes for profile: sds-replicated-volume -> sds"
330+
task nested:storage:configure \
331+
STORAGE_PROFILE="sds" \
332+
TARGET_STORAGE_CLASS="${{ steps.profile-config.outputs.storage_class }}" \
333+
TMP_DIR="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}" \
334+
VALUES_FILE="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/values.yaml" \
335+
GENERATED_VALUES_FILE="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/generated-values.yaml" \
336+
SSH_DIR="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/ssh" \
337+
SSH_FILE_NAME="id_ed" \
338+
PASSWORD_FILE="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/password.txt" \
339+
PASSWORD_HASH_FILE="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/password-hash.txt" \
340+
NAMESPACE="${{ env.RUN_ID }}" \
341+
DOMAIN="" \
342+
DEFAULT_USER="ubuntu" \
343+
NESTED_DIR="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/nested" \
344+
NESTED_KUBECONFIG="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/nested/kubeconfig"
345+
346+
# Ingress smoke disabled: not required for storage config
347+
348+
# Ceph CSI smoke check removed per request
178349

179350
- name: Upload run context
180351
if: always()
@@ -185,35 +356,11 @@ jobs:
185356
ci/dvp-e2e/tmp/runs/${{ env.RUN_ID }}
186357
ci/dvp-e2e/tmp/shared
187358
if-no-files-found: warn
188-
189-
run-e2e:
190-
name: E2E (${{ matrix.profile }}) [skeleton]
191-
needs: [setup, prepare]
192-
runs-on: ubuntu-latest
193-
concurrency:
194-
group: e2e-${{ github.ref }}-${{ matrix.profile }}
195-
cancel-in-progress: true
196-
strategy:
197-
fail-fast: false
198-
matrix:
199-
profile: ${{ fromJson(needs.setup.outputs.profiles) }}
200-
steps:
201-
- name: Echo run
202-
run: |
203-
echo "E2E stage for profile=${{ matrix.profile }} (skeleton - placeholder)"
204-
report:
205-
name: Report [skeleton]
206-
needs: [setup, run-e2e]
207-
if: always()
208-
runs-on: ubuntu-latest
209-
steps:
210-
- name: Echo report
211-
run: |
212-
echo "Report stage (skeleton). Collecting results from matrix..."
359+
overwrite: true
213360

214361
cleanup:
215-
name: Cleanup Resources
216-
needs: report
362+
name: Cleanup [skeleton]
363+
needs: [setup-nested-envs, prepare]
217364
if: always()
218365
runs-on: ubuntu-latest
219366
steps:
@@ -225,7 +372,7 @@ jobs:
225372
- name: Install kubectl
226373
uses: azure/setup-kubectl@v4
227374
with:
228-
version: 'latest'
375+
version: "latest"
229376

230377
- name: Build parent kubeconfig from secret (cleanup)
231378
shell: bash
@@ -257,25 +404,9 @@ jobs:
257404
- name: Cleanup test namespaces
258405
run: |
259406
set -euo pipefail
260-
PREFIX="nightly-nested-e2e-"
261-
echo "🧹 Cleaning up namespaces matching prefix '${PREFIX}'"
262-
mapfile -t CANDIDATES < <(kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' | grep "^${PREFIX}" || true)
263-
OURS=()
264-
for ns in "${CANDIDATES[@]:-}"; do
265-
[ -z "$ns" ] && continue
266-
if kubectl -n "$ns" get deploy jump-host >/dev/null 2>&1; then
267-
OURS+=("$ns")
268-
fi
269-
done
270-
if [ "${#OURS[@]}" -eq 0 ]; then
271-
echo "[INFO] No namespaces to delete."
272-
else
273-
echo "[INFO] Deleting namespaces:"
274-
printf ' - %s\n' "${OURS[@]}"
275-
for ns in "${OURS[@]}"; do
276-
kubectl delete ns "$ns" --wait=false || true
277-
done
278-
fi
407+
echo "🧹 Cleaning up namespaces matching 'nightly-nested-e2e-*'"
408+
kubectl get ns -o name | grep "namespace/nightly-nested-e2e-" | cut -d/ -f2 | \
409+
xargs -r kubectl delete ns --wait=false || echo "[INFO] No namespaces to delete"
279410
280411
- name: Report cleanup results
281412
if: always()

0 commit comments

Comments
 (0)