2626 schedule :
2727 - cron : " 30 2 * * *"
2828 workflow_dispatch :
29- inputs :
30- timeout :
31- description : " Ginkgo timeout (e.g. 2h, 4h)"
32- required : false
33- default : " 4h"
3429
3530permissions :
3631 contents : read
5247 concurrency :
5348 group : setup-nested-envs-${{ github.head_ref || github.ref_name }}
5449 cancel-in-progress : true
55- env :
56- PROFILE : sds-replicated-volume
5750 outputs :
5851 run_id : ${{ steps.prep.outputs.run_id }}
52+ profile : ${{ steps.load.outputs.profile }}
5953 steps :
6054 - uses : actions/checkout@v4
6155
@@ -72,17 +66,14 @@ jobs:
7266 id : prep
7367 run : |
7468 RUN_ID="nightly-nested-e2e-sds-$(date +%H%M%S)"
69+ PROFILE="${{ steps.load.outputs.profile }}"
7570 echo "run_id=$RUN_ID" >> "$GITHUB_OUTPUT"
7671 mkdir -p ./tmp/run-context
77- echo "profile: ${PROFILE}" > ./tmp/run-context/config.yaml
78- echo "run_id: ${RUN_ID}" >> ./tmp/run-context/config.yaml
79- echo "timestamp: $(date -Iseconds)" >> ./tmp/run-context/config.yaml
80-
81- - name : Upload run context
82- uses : actions/upload-artifact@v4
83- with :
84- name : run-context-${{ steps.prep.outputs.run_id }}
85- path : ./tmp/run-context
72+ {
73+ echo "profile: ${PROFILE}"
74+ echo "run_id: ${RUN_ID}"
75+ echo "timestamp: $(date -Iseconds)"
76+ } > ./tmp/run-context/config.yaml
8677
8778 # ============================================
8879 # 2. PREPARE - Cluster preparation
@@ -93,24 +84,15 @@ jobs:
9384 runs-on : ubuntu-latest
9485 timeout-minutes : 300
9586 concurrency :
96- group : prepare-${{ github.head_ref || github.ref_name }}-sds-replicated-volume
87+ group : prepare-${{ github.head_ref || github.ref_name }}-${{ needs.setup-nested-envs.outputs.profile }}
9788 cancel-in-progress : true
9889 env :
99- PROFILE : sds-replicated-volume
100- GO_VERSION : " 1.24.6"
90+ PROFILE : ${{ needs.setup-nested-envs.outputs.profile }}
10191 TMP_ROOT : ${{ github.workspace }}/ci/dvp-e2e/tmp
102-
103- outputs :
104- run_id : ${{ steps.prep.outputs.run_id }}
105- storage_class : ${{ steps.profile-config.outputs.storage_class }}
106- image_storage_class : ${{ steps.profile-config.outputs.image_storage_class }}
107- snapshot_storage_class : ${{ steps.profile-config.outputs.snapshot_storage_class }}
108- attach_disk_size : ${{ steps.profile-config.outputs.attach_disk_size }}
92+ REGISTRY_DOCKER_CFG : ${{ secrets.DEV_REGISTRY_DOCKER_CFG }}
10993
11094 steps :
11195 - uses : actions/checkout@v4
112- with :
113- fetch-depth : 0
11496
11597 - name : Install Task
11698 uses : arduino/setup-task@v2
@@ -128,38 +110,27 @@ jobs:
128110 with :
129111 version : " latest"
130112
131- - name : Install Deckhouse CLI
132- env :
133- D8_VERSION : v0.13.2
134- run : |
135- set -euo pipefail
136- echo "Installing d8 ${D8_VERSION}..."
137- curl -fsSL -o d8.tgz "https://deckhouse.io/downloads/deckhouse-cli/${D8_VERSION}/d8-${D8_VERSION}-linux-amd64.tar.gz"
138- tar -xzf d8.tgz linux-amd64/bin/d8
139- mv linux-amd64/bin/d8 /usr/local/bin/d8
140- chmod +x /usr/local/bin/d8
141- rm -rf d8.tgz linux-amd64
142- d8 --version
113+ - name : Setup d8
114+ uses :
werf/trdl/actions/[email protected] 115+ with :
116+ repo : d8
117+ url : https://deckhouse.ru/downloads/deckhouse-cli-trdl/
118+ root-version : 1
119+ root-sha512 : 343bd5f0d8811254e5f0b6fe292372a7b7eda08d276ff255229200f84e58a8151ab2729df3515cb11372dc3899c70df172a4e54c8a596a73d67ae790466a0491
120+ group : 0
121+ channel : stable
143122
144123 - name : Install yq
145124 run : |
146125 echo "Installing yq..."
147126 curl -L -o /usr/local/bin/yq https://github.com/mikefarah/yq/releases/download/v4.44.1/yq_linux_amd64
148127 chmod +x /usr/local/bin/yq
149128
150- - name : Restore run context
151- uses : actions/download-artifact@v4
152- with :
153- name : run-context-${{ needs.setup-nested-envs.outputs.run_id }}
154- path : .
155-
156129 - name : Prepare environment
157130 id : prep
158131 run : |
159132 RUN_ID="${{ needs.setup-nested-envs.outputs.run_id }}"
160- echo "run_id=$RUN_ID" >> "$GITHUB_OUTPUT"
161133 echo "RUN_ID=$RUN_ID" >> "$GITHUB_ENV"
162- echo "PROFILE=sds-replicated-volume" >> "$GITHUB_ENV"
163134 echo "TMP_ROOT=${{ env.TMP_ROOT }}" >> "$GITHUB_ENV"
164135 mkdir -p "${{ env.TMP_ROOT }}/shared" "${{ env.TMP_ROOT }}/matrix-logs"
165136
@@ -177,56 +148,29 @@ jobs:
177148 RUN_ID="${{ env.RUN_ID }}" \
178149 RUN_NAMESPACE="${{ env.RUN_ID }}" \
179150 RUN_DIR="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}"
180- echo "VALUES_TEMPLATE_FILE=${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/values.yaml" >> $GITHUB_ENV
181151
182- - name : Configure registry auth (DEV_REGISTRY_DOCKER_CFG)
183- run : |
184- dev_cfg_b64='${{ secrets.DEV_REGISTRY_DOCKER_CFG }}'
185- if [ -n "$dev_cfg_b64" ]; then
186- echo "::add-mask::$dev_cfg_b64"
187- echo "REGISTRY_DOCKER_CFG=$dev_cfg_b64" >> "$GITHUB_ENV"
188- else
189- echo "[WARN] DEV_REGISTRY_DOCKER_CFG is empty; proceeding without registry cfg"
190- fi
191-
192- - name : Inject REGISTRY_DOCKER_CFG into values.yaml
193- if : ${{ env.REGISTRY_DOCKER_CFG != '' }}
194- working-directory : ci/dvp-e2e
152+ - name : Configure registry auth for installer pull
195153 run : |
196- VALS="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/values.yaml"
197- task values:inject-registry VALUES_FILE="$VALS" REGISTRY_DOCKER_CFG="${REGISTRY_DOCKER_CFG}"
198-
199- - name : Docker login from DEV_REGISTRY_DOCKER_CFG (optional)
200- if : ${{ env.REGISTRY_DOCKER_CFG != '' }}
201- run : |
202- set -euo pipefail
203- cfg=$(printf '%s' "$REGISTRY_DOCKER_CFG" | base64 -d)
204- reg_list=$(printf '%s' "$cfg" | jq -r '.auths | keys[]')
205- for reg in $reg_list; do
206- auth=$(printf '%s' "$cfg" | jq -r --arg r "$reg" '.auths[$r].auth // ""')
207- [ -z "$auth" ] && continue
208- creds=$(printf '%s' "$auth" | base64 -d)
209- user=${creds%%:*}
210- pass=${creds#*:}
211- echo "Logging into $reg"
212- echo "$pass" | docker login "$reg" -u "$user" --password-stdin
213- done
154+ mkdir -p ~/.docker
155+ printf '%s' "$REGISTRY_DOCKER_CFG" | base64 -d > ~/.docker/config.json
214156
215157 - name : Configure storage profile
216158 working-directory : ci/dvp-e2e
217159 id : profile-config
218- env :
219- PROFILE : sds-replicated-volume
220160 run : |
221- # Get storage class configuration from profiles.json
222- PROFILE_CONFIG=$(./scripts/get_profile_config.sh "${PROFILE}")
161+ PROFILE_JSON=$(jq -c --arg profile "$PROFILE" '.[] | select(.name == $profile)' profiles.json)
162+ if [ -z "$PROFILE_JSON" ]; then
163+ echo "Profile '$PROFILE' not found in profiles.json" >&2
164+ echo "Available profiles:" >&2
165+ jq -r '.[] | " - \(.name)"' profiles.json >&2
166+ exit 1
167+ fi
223168
224- # Parse the output more carefully
225- STORAGE_CLASS=$(echo "$PROFILE_CONFIG" | grep "^STORAGE_CLASS=" | cut -d'=' -f2)
226- IMAGE_STORAGE_CLASS=$(echo "$PROFILE_CONFIG" | grep "^IMAGE_STORAGE_CLASS=" | cut -d'=' -f2)
227- SNAPSHOT_STORAGE_CLASS=$(echo "$PROFILE_CONFIG" | grep "^SNAPSHOT_STORAGE_CLASS=" | cut -d'=' -f2)
228- PARENT_STORAGE_CLASS=$(echo "$PROFILE_CONFIG" | grep "^PARENT_STORAGE_CLASS=" | cut -d'=' -f2)
229- ATTACH_DISK_SIZE=$(echo "$PROFILE_CONFIG" | grep "^ATTACH_DISK_SIZE=" | cut -d'=' -f2)
169+ STORAGE_CLASS=$(jq -r '.storage_class // ""' <<<"$PROFILE_JSON")
170+ IMAGE_STORAGE_CLASS=$(jq -r '.image_storage_class // ""' <<<"$PROFILE_JSON")
171+ SNAPSHOT_STORAGE_CLASS=$(jq -r '.snapshot_storage_class // ""' <<<"$PROFILE_JSON")
172+ PARENT_STORAGE_CLASS=$(jq -r '.parent_storage_class // ""' <<<"$PROFILE_JSON")
173+ ATTACH_DISK_SIZE=$(jq -r '.worker_data_disk_size // "10Gi"' <<<"$PROFILE_JSON")
230174
231175 echo "Profile: ${PROFILE}"
232176 echo "Storage Class: ${STORAGE_CLASS}"
@@ -235,124 +179,57 @@ jobs:
235179 echo "Parent Storage Class: ${PARENT_STORAGE_CLASS}"
236180 echo "Attach Disk Size: ${ATTACH_DISK_SIZE}"
237181
238- # Export variables to GitHub Actions environment and outputs
182+ # Export variables to GitHub Actions environment
239183 echo "STORAGE_CLASS=${STORAGE_CLASS}" >> $GITHUB_ENV
240- echo "IMAGE_STORAGE_CLASS=${IMAGE_STORAGE_CLASS}" >> $GITHUB_ENV
241- echo "SNAPSHOT_STORAGE_CLASS=${SNAPSHOT_STORAGE_CLASS}" >> $GITHUB_ENV
242184 echo "PARENT_STORAGE_CLASS=${PARENT_STORAGE_CLASS}" >> $GITHUB_ENV
243185 echo "ATTACH_DISK_SIZE=${ATTACH_DISK_SIZE}" >> $GITHUB_ENV
244- echo "storage_class=$STORAGE_CLASS" >> $GITHUB_OUTPUT
245- echo "image_storage_class=$IMAGE_STORAGE_CLASS" >> $GITHUB_OUTPUT
246- echo "snapshot_storage_class=$SNAPSHOT_STORAGE_CLASS" >> $GITHUB_OUTPUT
247- echo "attach_disk_size=$ATTACH_DISK_SIZE" >> $GITHUB_OUTPUT
248186 # Pass storage profile into run values for Helm templates
249187 yq eval --inplace ".storageProfile = \"${PROFILE}\"" "${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/values.yaml"
250188 # Effective disk SC used for worker data disks (prefer image SC when set)
251189 EFF_DISK_SC=${IMAGE_STORAGE_CLASS:-$STORAGE_CLASS}
252190 echo "EFFECTIVE_DISK_SC=${EFF_DISK_SC}" >> $GITHUB_ENV
253191
254- - name : Install infra (namespace/RBAC/ingress)
192+ - name : Install nested environment
255193 working-directory : ci/dvp-e2e
256194 run : |
257- USE_GH_SSH_KEYS=true SSH_FILE_NAME=id_ed task render-infra \
258- TMP_DIR="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}" \
259- VALUES_FILE="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/values.yaml" \
260- PARENT_KUBECONFIG="${KUBECONFIG}" \
261- SSH_FILE_NAME="id_ed"
262- USE_GH_SSH_KEYS=true SSH_FILE_NAME=id_ed task infra-deploy \
195+ task install:nested:env \
263196 TMP_DIR="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}" \
264197 VALUES_FILE="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/values.yaml" \
265198 PARENT_KUBECONFIG="${KUBECONFIG}" \
266- SSH_FILE_NAME="id_ed"
267-
268- - name : Bootstrap nested cluster (via jump-host)
269- working-directory : ci/dvp-e2e
270- run : |
271- echo "🚀 dhctl bootstrap (profile: sds-replicated-volume)"
272- task dhctl-bootstrap \
273- TMP_DIR="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}" \
274- VALUES_FILE="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/values.yaml" \
275- PARENT_KUBECONFIG="${KUBECONFIG}" \
276- SSH_FILE_NAME="id_ed" \
277- TARGET_STORAGE_CLASS="${{ env.PARENT_STORAGE_CLASS }}"
278-
279- - name : Attach data disks to worker VMs using hotplug
280- working-directory : ci/dvp-e2e
281- run : |
282- task infra:attach-storage-disks-hotplug \
283- TMP_DIR="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}" \
284- VALUES_FILE="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/values.yaml" \
285- PARENT_KUBECONFIG="${KUBECONFIG}" \
286- DISK_SIZE="${ATTACH_DISK_SIZE:-10Gi}" \
287- STORAGE_CLASS="ceph-pool-r2-csi-rbd-immediate" \
288- DISK_COUNT="2"
289-
290- - name : Build nested kubeconfig
291- working-directory : ci/dvp-e2e
292- run : |
293- task nested:kubeconfig \
294- TMP_DIR="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}" \
295- VALUES_FILE="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/values.yaml" \
199+ TARGET_STORAGE_CLASS="${{ env.PARENT_STORAGE_CLASS }}" \
200+ ATTACH_DISK_SIZE="${{ env.ATTACH_DISK_SIZE }}" \
201+ EFFECTIVE_DISK_SC="${{ env.EFFECTIVE_DISK_SC }}" \
296202 NAMESPACE="${{ env.RUN_ID }}" \
297- SSH_DIR="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/ssh" \
298- SSH_FILE_NAME="id_ed" \
299- NESTED_DIR="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/nested" \
300203 NESTED_KUBECONFIG="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/nested/kubeconfig" \
301- PARENT_KUBECONFIG="${KUBECONFIG}"
302-
303- - name : Configure SDS in nested cluster
304- working-directory : ci/dvp-e2e
305- run : |
306- echo "💾 Configuring SDS storage (sds-node-configurator + sds-replicated-volume)"
307- task nested:storage:sds \
308- TMP_DIR="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}" \
309- NESTED_KUBECONFIG="${{ env.TMP_ROOT }}/runs/${{ env.RUN_ID }}/nested/kubeconfig" \
310- SDS_SC_NAME="${{ steps.profile-config.outputs.storage_class }}"
311-
312- - name : Upload run context
313- if : always()
314- uses : actions/upload-artifact@v4
315- with :
316- name : run-context-${{ env.RUN_ID }}
317- path : |
318- ci/dvp-e2e/tmp/runs/${{ env.RUN_ID }}
319- ci/dvp-e2e/tmp/shared
320- if-no-files-found : warn
321- overwrite : true
204+ SDS_SC_NAME="${{ env.STORAGE_CLASS }}"
322205
323206 cleanup :
324207 name : Cleanup [skeleton]
325208 needs : [setup-nested-envs, prepare]
326209 if : always()
327210 runs-on : ubuntu-latest
211+ env :
212+ CLEANUP_PREFIX : ${{ vars.CLEANUP_PREFIX || 'nightly-nested-e2e-' }}
328213 steps :
329214 - uses : actions/checkout@v4
330215
331- - name : Install Task
332- uses : arduino/setup-task@v2
333- with :
334- version : 3.x
335- repo-token : ${{ secrets.GITHUB_TOKEN }}
336-
337216 - name : Install kubectl
338217 uses : azure/setup-kubectl@v4
339218 with :
340219 version : " latest"
341220
342- - name : Build parent kubeconfig from secret (cleanup)
221+ - name : Install Task
222+ uses : arduino/setup-task@v2
223+
224+ - name : Build parent kubeconfig from secret
343225 working-directory : ci/dvp-e2e
344226 run : |
345227 KCFG="$HOME/.kube/config"
346228 task parent:kubeconfig OUTPUT="$KCFG" API_URL="${E2E_K8S_URL}" SA_TOKEN="${{ secrets.E2E_NESTED_SA_SECRET }}"
347229 echo "KUBECONFIG=$KCFG" >> "$GITHUB_ENV"
348230
349- - name : Install Task
350- uses : arduino/setup-task@v2
351-
352231 - name : Cleanup test namespaces
353232 working-directory : ci/dvp-e2e
354- env :
355- CLEANUP_PREFIX : ${{ vars.CLEANUP_PREFIX || 'nightly-nested-e2e-' }}
356233 run : |
357234 task cleanup:namespaces PREFIX="${CLEANUP_PREFIX}" PARENT_KUBECONFIG="${KUBECONFIG}"
358235
0 commit comments