Skip to content

Commit aeaedca

Browse files
ci: consolidated platform & e2e stabilization batch (#2948)
## What Consolidated landing branch for a set of interdependent platform/CI stabilization fixes. It began as the source PRs in the table below (in dependency order) and has since grown with review-driven fixes and a few production-behavior changes — the full current inventory is under **Scope** below. Landing them as one unit lets CI run against the real combined state instead of a fragile bottom-up merge train. ## Source PRs (dependency order) | # | Commit | Source PR | Addresses | |---|--------|-----------|-----------| | 1 | fix(capi): startupProbe on capi-controller-manager | #2946 | capi crashloop during cert provisioning | | 2 | test(e2e): bucket.bats port-forward + S3 client reliability | #2944 | flaky bucket test | | 3 | fix(seaweedfs): restore -lock BucketClass, s3 svc name, drop volumeSizeLimitMB | #2943 | missing bucket/access classes | | 4 | test(e2e): in-cluster Cilium endpoint-leak healer (install + apps) | #2874 | cilium "IP already in use" leak | | 5 | refactor(build): mode=max registry cache + main-only warmer | #2938 | build cache | | 6 | ci(build): isolate each PR build on its own ephemeral runner VM | #2939 | shared-buildkit contention | | 7 | fix(e2e): LINSTOR post-install waits on a single 15m deadline | #2928 | LINSTOR provisioning timeouts | | 8 | test(metallb): assert digest-pinned image form, not version literal | #2873 | brittle metallb assertion | ## Why consolidated These form a dependency DAG (verified from CI logs): e.g. 2943 needs 2946, 2938 needs 2874, 2928 needs 2938/2939, 2873 needs 2928. Tested bottom-up, each lower PR runs with none of the fixes above it and can't go green alone. This branch carries all of them, so CI runs against the real combined state. ## Verification status CI is green on the latest head (`5653c30`): full-suite E2E passes end-to-end and is reproducible (2 of 3 runs on this SHA green). The one red run was a LINSTOR tie-breaker / DRBD-metadata infra flake on the sandbox, unrelated to the diff — a different environmental subsystem failed each run (details in the comments below). The earlier 3-hour crust-gather snapshot hang is fixed in `5653c30`. ## Scope beyond the original 8 The branch has grown past the 8 source PRs above with review-driven fixes and a few production-behavior changes. For reviewer transparency, the full set: **Review fixes (@lexfrei review):** - **B1 (blocker)** — `8f41910` converts the SeaweedFS `-lock`/`-readonly` BucketClasses and the s3 service-name override into `patches/`, wired into `make update`, so a re-vendor no longer drops them. - **FU1** — `cc99230` grants the cilium leak-healer `delete` on pods (both delete remedies were RBAC-forbidden). - **FU3** — `014de3f` adds a unit test for the HelmRelease update conflict-retry path. - **FU4** — `6deddc6` makes the leak-healer refuse a disconnect for any non-terminal owner phase, not just `Running`. - **FU7** — `f3914d2` sets `persist-credentials: false` on the build-cache checkout (SHA-pinning is handled repo-wide in #2849). **Production-behavior changes (not in the table above):** - VPA `updateMode: Auto → Initial` for etcd (`6e9ff90`) and monitoring (`0997105`), plus `vmselect`/`vmstorage` `minAllowed` floors — stops install-time eviction churn. - cozystack-api: `retry.RetryOnConflict` on the Application→HelmRelease update path (`728f676`). **E2E robustness follow-ups:** per-test crust-gather snapshots (`50e5f94`), EtcdBackupSchedule wait (`763b85e`), tenant-node single-deadline wait (`9e43d45`), harbor BucketClaim 10m budget (`d7f244f`), tenant API via LoadBalancer (`9beda4e`), crust-gather pin (`95f42aa`). **Not addressed (by decision):** FU2 — the s3 Service keeps `seaweedfs.name`-based naming via patch (rendered output unchanged; cozystack renders `fullname == seaweedfs`, so it matches the `componentName`/`fullname` siblings in practice). FU6 — fork PR build push is handled by the existing mirror-to-same-repo-branch workflow. ## Relates to #2946 #2944 #2943 #2874 #2938 #2939 #2928 #2873 — if this lands, those can be closed; otherwise they remain the granular per-PR review path. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added CI build cache warming for main branch builds. * Added a best-effort in-cluster Cilium endpoint self-heal watchdog for e2e installs. * Extended SeaweedFS COSI with object-lock support plus separate readonly access. * **Improvements** * Reduced e2e install flakiness with a shared readiness deadline, safer waits, and improved cleanup/diagnostics capture. * Prevented install-time churn by switching VPA update mode to **Initial**. * Added container startup probes and updated SeaweedFS volume sizing. * **Tests** * Improved e2e robustness (etcd backup schedule waiting, digest-pinned image checks, and corrected S3 port-forwarding). <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2 parents e8e750c + 5653c30 commit aeaedca

60 files changed

Lines changed: 1012 additions & 161 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/build-main.yaml‎

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
name: Build cache (main)
2+
3+
# Warms the shared mode=max build cache so PR builds start hot.
4+
#
5+
# PR builds (pull-requests.yaml) read the cache but never write it
6+
# (WRITE_CACHE unset -> 0). Only this serialized main build writes
7+
# CACHE_REGISTRY/<img>:buildcache, so concurrent PR builds never race on the
8+
# cache manifest -- the 409 collisions PR #2711 fixed for image tags would
9+
# otherwise reappear on the cache ref. Cache is mode=max so all multistage
10+
# `builder` stages are cached, not just the final stage as with inline.
11+
#
12+
# This job builds on a docker-container buildx builder, NOT the host's default
13+
# embedded `docker` driver: `--cache-to type=registry,mode=max` is unsupported
14+
# on the docker driver unless the daemon runs the containerd image store, so on
15+
# a classic store the warmer would otherwise fail to export any cache. The
16+
# container driver also gives this build its own buildkit (separate bbolt), so
17+
# the warmer never contends with PR builds on the shared embedded buildkit.
18+
19+
env:
20+
# Same per-CI registry as pull-requests.yaml; the cache is co-located here.
21+
REGISTRY: iad.ocir.io/idyksih5sir9/cozystack
22+
23+
on:
24+
push:
25+
branches: [main]
26+
paths-ignore:
27+
- 'docs/**'
28+
29+
# Only the newest main commit's cache matters; cancel older in-flight warmers.
30+
concurrency:
31+
group: build-main-cache
32+
cancel-in-progress: true
33+
34+
jobs:
35+
warm-cache:
36+
name: Warm build cache
37+
runs-on: [self-hosted]
38+
timeout-minutes: 90
39+
permissions:
40+
contents: read
41+
packages: write
42+
43+
steps:
44+
- name: Checkout code
45+
uses: actions/checkout@v4
46+
with:
47+
fetch-depth: 0
48+
fetch-tags: true
49+
# This privileged workflow has packages:write and an OCIR push token;
50+
# it never pushes git, so don't leave the checkout's GITHUB_TOKEN in
51+
# .git/config where a later build step could read it.
52+
persist-credentials: false
53+
54+
- name: Set up Docker config
55+
run: |
56+
if [ -d ~/.docker ]; then
57+
cp -r ~/.docker "${{ runner.temp }}/.docker"
58+
fi
59+
60+
- name: Login to OCIR
61+
uses: docker/login-action@v3
62+
with:
63+
username: ${{ secrets.OCIR_USER }}
64+
password: ${{ secrets.OCIR_TOKEN }}
65+
registry: iad.ocir.io
66+
env:
67+
DOCKER_CONFIG: ${{ runner.temp }}/.docker
68+
69+
# docker-container driver: required for `--cache-to type=registry,mode=max`
70+
# (unsupported on the host's default docker driver) and gives this build an
71+
# isolated buildkit so it never contends with PR builds on the shared one.
72+
- name: Set up Buildx (docker-container driver)
73+
id: buildx
74+
uses: docker/setup-buildx-action@v3
75+
with:
76+
driver: docker-container
77+
78+
- name: Build all images and write mode=max cache
79+
run: make build
80+
env:
81+
DOCKER_CONFIG: ${{ runner.temp }}/.docker
82+
# Build on the docker-container builder created above (BUILDX_ARGS adds
83+
# --builder=$(BUILDER)); buildx forwards the OCIR auth from DOCKER_CONFIG
84+
# to the container builder for cache reads/writes and image pushes.
85+
BUILDER: ${{ steps.buildx.outputs.name }}
86+
# WRITE_CACHE=1 turns on --cache-to (mode=max) for every image.
87+
WRITE_CACHE: '1'
88+
# Publish a floating :main handle; do not move :latest (releases do).
89+
IMAGE_TAG: main
90+
PUBLISH_VERSIONED: '0'
91+
PUBLISH_FLOATING: '0'

‎.github/workflows/pull-requests.yaml‎

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,17 @@ jobs:
2828
2929
build:
3030
name: Build
31-
runs-on: [self-hosted]
31+
# Run each Build on its own ephemeral VM instead of the shared self-hosted
32+
# runner. The shared host runs 4 runner agents against one dockerd-embedded
33+
# buildkit; concurrent build jobs serialize on buildkit's single-writer bbolt
34+
# cache lock + exporter mutex and stall to the 30-min timeout (proven via a
35+
# live SIGUSR1 goroutine dump). One VM per job => one buildkit per job => that
36+
# contention is severed by construction. `make build` is serial (one image at
37+
# a time), so a small shape suffices -- 4cpu/16gb, not the 24cpu the e2e job
38+
# uses -- and it leans on the warm mode=max cache (#2938) to stay under the
39+
# 30-min wall. The `debug` label still routes to self-hosted for the
40+
# breakpoint path. Phase 0.5 of #2937.
41+
runs-on: ${{ contains(github.event.pull_request.labels.*.name, 'debug') && 'self-hosted' || 'oracle-vm-4cpu-16gb-x86-64' }}
3242
timeout-minutes: 30
3343
permissions:
3444
contents: read
@@ -47,6 +57,19 @@ jobs:
4757
fetch-depth: 0
4858
fetch-tags: true
4959

60+
# Ephemeral runners don't carry two tools the persistent self-hosted
61+
# runner accreted: the helm-unittest plugin (make unit-tests) and the
62+
# flux CLI (the installer's `flux push artifact` publishes the
63+
# cozystack-packages OCI artifact the operator pulls). Install if absent
64+
# (idempotent; the debug/self-hosted path already has them). Durable fix:
65+
# bake both into the oracle-vm runner image, then drop this step.
66+
- name: Set up build toolchain
67+
run: |
68+
helm plugin list 2>/dev/null | grep -q unittest \
69+
|| helm plugin install https://github.com/helm-unittest/helm-unittest
70+
command -v flux >/dev/null \
71+
|| curl -s https://fluxcd.io/install.sh | sudo bash
72+
5073
- name: Run unit tests
5174
run: make unit-tests
5275

‎hack/common-envs.mk‎

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,12 @@ endif
77

88
REGISTRY ?= ghcr.io/cozystack/cozystack
99

10-
# CACHE_REGISTRY: registry that `--cache-from` reads build cache from. It must
11-
# point at a registry where a `:latest` tag is actually published. PR builds
12-
# set REGISTRY to a per-CI registry and push only unique `pr-<N>-<sha>` tags
13-
# (PUBLISH_FLOATING=0), so they never refresh `:latest` there — reading cache
14-
# from $(REGISTRY):latest would always 404. Release builds publish `:latest`
15-
# to ghcr.io, so default cache reads there and stays warm across PR builds.
16-
CACHE_REGISTRY ?= ghcr.io/cozystack/cozystack
10+
# CACHE_REGISTRY: registry holding the `:buildcache` mode=max cache images that
11+
# `--cache-from`/`--cache-to` read and write (see the cache-args macro below).
12+
# Defaults to $(REGISTRY) so the cache is co-located with the build registry —
13+
# in CI that is the per-CI registry the runners are closest to, keeping cache
14+
# transfers fast and egress-free.
15+
CACHE_REGISTRY ?= $(REGISTRY)
1716

1817
# IMAGE_TAG: build-unique tag pushed for every image. Set by CI to a value
1918
# that does not collide between concurrent builds:
@@ -29,6 +28,12 @@ IMAGE_TAG ?= dev
2928
PUBLISH_VERSIONED ?= 0
3029
PUBLISH_FLOATING ?= 0
3130

31+
# WRITE_CACHE=1 enables `--cache-to` (mode=max) to CACHE_REGISTRY/<img>:buildcache.
32+
# Default off: only the serialized main/release cache-warming build writes the
33+
# shared cache ref. PR builds keep it 0 and read-only, so concurrent PR builds
34+
# never race on the cache manifest (the 409 collisions PR #2711 fixed for tags).
35+
WRITE_CACHE ?= 0
36+
3237
PUSH := 1
3338
LOAD := 0
3439
BUILDER ?=
@@ -55,6 +60,20 @@ define image-tags
5560
--tag $(REGISTRY)/$(1):$(IMAGE_TAG)$(if $(filter 1,$(PUBLISH_VERSIONED)),$(if $(filter-out $(IMAGE_TAG),$(strip $(2))), --tag $(REGISTRY)/$(1):$(strip $(2))))$(if $(filter 1,$(PUBLISH_FLOATING)), --tag $(REGISTRY)/$(1):latest)
5661
endef
5762

63+
# cache-args <image-name> [<cache-tag>]
64+
# Expands to buildx cache flags for one image:
65+
# --cache-from is always emitted (a missing cache 404s harmlessly -> cold build)
66+
# --cache-to is emitted only when WRITE_CACHE=1 (main/release), writing mode=max
67+
# so ALL stages are cached -- including the multistage `builder` layers that
68+
# `--cache-to type=inline` could never export. oci-mediatypes + image-manifest
69+
# keep the cache manifest portable across registries (OCIR/ghcr/ECR).
70+
# <cache-tag> defaults to `buildcache`; pass an explicit tag for images that build
71+
# a distinct artifact per loop iteration (e.g. ubuntu-container-disk per k8s ver).
72+
# $(comma) escapes the literal commas in the --cache-to value so make does not
73+
# mis-parse them as $(if ...) argument separators.
74+
comma := ,
75+
cache-args = --cache-from type=registry,ref=$(CACHE_REGISTRY)/$(1):$(if $(2),$(2),buildcache)$(if $(filter 1,$(WRITE_CACHE)), --cache-to type=registry$(comma)ref=$(CACHE_REGISTRY)/$(1):$(if $(2),$(2),buildcache)$(comma)mode=max$(comma)oci-mediatypes=true$(comma)image-manifest=true)
76+
5877
ifeq ($(COZYSTACK_VERSION),)
5978
$(shell git remote add upstream https://github.com/cozystack/cozystack.git || true)
6079
$(shell git fetch upstream --tags)

‎hack/cozyreport.sh‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,12 @@ fi
294294
echo "Generating summary..."
295295
"$SCRIPT_DIR/cozyreport-summary.sh" > "$REPORT_DIR/summary.txt" 2>&1 || true
296296

297+
# Fold in the per-test crust-gather snapshots cozytest.sh captured on failure
298+
# (host + each nested tenant cluster) so the uploaded artifact carries an
299+
# inspectable, `crust-gather serve`-able state for every failed test.
300+
SNAP_DIR="${COZY_REPORT_DIR:-_out/cozyreport}/snapshots"
301+
[ -d "$SNAP_DIR" ] && cp -a "$SNAP_DIR" "$REPORT_DIR/snapshots" 2>/dev/null || true
302+
297303
echo "Creating archive..."
298304
tar -czf $REPORT_NAME.tgz -C $REPORT_PDIR .
299305
echo "Report created: $REPORT_NAME.tgz"

‎hack/cozytest.sh‎

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,44 @@ run_one() {
7676
# convert .bats -> shell-functions #
7777
###############################################################################
7878
TMP_SH=$(mktemp) || { echo "Failed to create temp file" >&2; exit 1; }
79-
trap 'rm -f "$TMP_SH"' EXIT
79+
80+
# Per-file lifecycle hook. cozytest.sh runs each .bats as a single invocation
81+
# and exit()s on the first failing @test, so this EXIT trap is the one place to:
82+
# 1. on failure, snapshot the HOST cluster with crust-gather BEFORE any cleanup,
83+
# so each failed test keeps its own inspectable state instead of one
84+
# end-of-suite dump;
85+
# 2. ALWAYS run the file's cozy_cleanup() if it defines one, so a test never
86+
# leaks resources into the shared tenant-test namespace (left-behind PVCs
87+
# otherwise exhaust the tenant quota and cascade-fail every later app).
88+
# cozy_cleanup is a plain shell function a .bats file may define — there are no
89+
# bats setup/teardown directives here, this runner only knows @test + bash.
90+
# NOTE: nested tenant clusters are NOT captured here. This trap runs in the
91+
# parent shell after the failing test subshell has exited and reaped its
92+
# port-forward, and crust-gather can only reach a tenant via that localhost
93+
# forward — so a test that creates tenant clusters (run-kubernetes.sh) captures
94+
# them from its OWN in-subshell EXIT trap, while the forward is still alive.
95+
COZY_REPORT_DIR="${COZY_REPORT_DIR:-_out/cozyreport}"
96+
_cozy_on_exit() {
97+
_rc=$?
98+
if [ "$_rc" -ne 0 ] && command -v crust-gather >/dev/null 2>&1; then
99+
_snap="$COZY_REPORT_DIR/snapshots/$(basename "$TEST_FILE" .bats)"
100+
mkdir -p "$_snap" 2>/dev/null || true
101+
echo "» capturing crust-gather snapshot of failed $(basename "$TEST_FILE") -> $_snap"
102+
# Bound with a timeout: crust-gather collect has hung indefinitely on a
103+
# contended/degraded cluster (e.g. streaming logs from a crashlooping pod),
104+
# wedging the whole test step for hours until the job-level cancel. 5 min is
105+
# ample for a host snapshot; a partial capture (timeout exits 124, swallowed
106+
# by `|| true`) still beats a multi-hour hang. -k 30 hard-kills if a blocked
107+
# collect ignores the SIGTERM.
108+
timeout -k 30 300 crust-gather collect --exclude-kind Secret -f "$_snap/host" >/dev/null 2>&1 || true
109+
fi
110+
if command -v cozy_cleanup >/dev/null 2>&1; then
111+
echo "» cozy_cleanup $(basename "$TEST_FILE" .bats)"
112+
cozy_cleanup || true
113+
fi
114+
rm -f "$TMP_SH"
115+
}
116+
trap '_cozy_on_exit' EXIT
80117
awk '
81118
/^@test[[:space:]]+"/ {
82119
line = substr($0, index($0, "\"") + 1)

‎hack/e2e-apps/bucket.bats‎

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,20 @@ EOF
3838
VIEWER_ACCESS_KEY=$(jq -r '.spec.secretS3.accessKeyID' bucket-viewer-credentials.json)
3939
VIEWER_SECRET_KEY=$(jq -r '.spec.secretS3.accessSecretKey' bucket-viewer-credentials.json)
4040

41-
# Start port-forwarding
42-
bash -c 'timeout 100s kubectl port-forward service/seaweedfs-s3 -n tenant-root 8333:8333 > /dev/null 2>&1 &'
41+
# Start port-forwarding in this shell (not via `bash -c '... &'` — the
42+
# wrapper subshell exits immediately, the backgrounded kubectl becomes an
43+
# orphan and gets reaped before the first mc S3 request, so `mc cp` sees
44+
# `dial tcp 127.0.0.1:8333: connect: connection refused` even though the
45+
# earlier `nc -z` probe succeeded). The forked port-forward inherits the
46+
# test process group; cozytest.sh kills the whole group when the test
47+
# function returns, so no explicit cleanup is needed.
48+
kubectl port-forward service/seaweedfs-s3 -n tenant-root 8333:8333 >/dev/null 2>&1 &
4349

4450
# Wait for port-forward to be ready
45-
timeout 30 sh -ec 'until nc -z localhost 8333; do sleep 1; done'
51+
timeout 30 sh -ec 'until nc -z 127.0.0.1 8333; do sleep 1; done'
4652

4753
# --- Test readwrite user (admin) ---
48-
mc alias set rw-user https://localhost:8333 $ADMIN_ACCESS_KEY $ADMIN_SECRET_KEY --insecure
54+
mc alias set rw-user https://127.0.0.1:8333 $ADMIN_ACCESS_KEY $ADMIN_SECRET_KEY --insecure
4955

5056
# Admin can upload
5157
echo "readwrite test" > /tmp/rw-test.txt
@@ -58,7 +64,7 @@ EOF
5864
mc cp --insecure rw-user/$BUCKET_NAME/rw-test.txt /tmp/rw-test-download.txt
5965

6066
# --- Test readonly user (viewer) ---
61-
mc alias set ro-user https://localhost:8333 $VIEWER_ACCESS_KEY $VIEWER_SECRET_KEY --insecure
67+
mc alias set ro-user https://127.0.0.1:8333 $VIEWER_ACCESS_KEY $VIEWER_SECRET_KEY --insecure
6268

6369
# Viewer can list
6470
mc ls --insecure ro-user/$BUCKET_NAME/rw-test.txt

‎hack/e2e-apps/etcd.bats‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,11 @@ spec:
103103
EOF
104104
wait_etcd_hr_ready || { dump_diagnostics; false; }
105105
kubectl -n tenant-test wait etcdcluster.etcd.aenix.io etcd --timeout=180s --for=jsonpath='{.status.conditions[?(@.type=="Ready")].status}'=True || { dump_diagnostics; false; }
106-
kubectl -n tenant-test get etcdbackupschedule.etcd.aenix.io etcd || { dump_diagnostics; false; }
106+
# Reconfiguring the Etcd CR triggers a HelmRelease upgrade that renders the
107+
# EtcdBackupSchedule; hr/etcdcluster readiness can report ready on the prior
108+
# revision before that resource materializes, so poll for it instead of a
109+
# bare get (same pattern this test already uses for the CronJob below).
110+
timeout 120 sh -ec "until kubectl -n tenant-test get etcdbackupschedule.etcd.aenix.io etcd >/dev/null 2>&1; do sleep 2; done" || { dump_diagnostics; false; }
107111
# Verify the region field propagated to the EtcdBackupSchedule.
108112
REGION=$(kubectl -n tenant-test get etcdbackupschedule.etcd.aenix.io etcd -o jsonpath='{.spec.destination.s3.region}')
109113
[ "$REGION" = "us-east-1" ]

‎hack/e2e-apps/harbor.bats‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,13 @@ EOF
4343
timeout 60 sh -ec "until kubectl -n tenant-test get hr $release >/dev/null 2>&1; do sleep 2; done"
4444
kubectl -n tenant-test wait hr $release --timeout=5m --for=condition=ready
4545

46-
# Wait for COSI to provision bucket
46+
# Wait for COSI to provision bucket. The driver creates the Bucket and grants
47+
# access quickly, but the central COSI controller's propagation of the Bucket's
48+
# readiness back onto the namespaced BucketClaim can lag several minutes on a
49+
# loaded runner, so allow the same 10m budget the dependent HelmRelease gets.
4750
timeout 60 sh -ec "until kubectl -n tenant-test get bucketclaims.objectstorage.k8s.io $release-registry >/dev/null 2>&1; do sleep 2; done"
4851
kubectl -n tenant-test wait bucketclaims.objectstorage.k8s.io $release-registry \
49-
--timeout=300s --for=jsonpath='{.status.bucketReady}'=true
52+
--timeout=600s --for=jsonpath='{.status.bucketReady}'=true
5053
timeout 60 sh -ec "until kubectl -n tenant-test get bucketaccesses.objectstorage.k8s.io $release-registry >/dev/null 2>&1; do sleep 2; done"
5154
kubectl -n tenant-test wait bucketaccesses.objectstorage.k8s.io $release-registry \
5255
--timeout=60s --for=jsonpath='{.status.accessGranted}'=true

‎hack/e2e-apps/kubernetes-latest.bats‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
#!/usr/bin/env bats
22

3+
# Sourced at file scope (not inside the @test) so cozytest.sh sources it into
4+
# the parent shell: both run_kubernetes_test and the cozy_cleanup() hook the
5+
# EXIT trap calls must live there (the @test itself runs in a subshell).
6+
. hack/e2e-apps/run-kubernetes.sh
7+
38
@test "Create a tenant Kubernetes control plane with latest version" {
4-
. hack/e2e-apps/run-kubernetes.sh
59
# 4th arg = enable_ouroboros: folds the standalone ouroboros.bats's
610
# hairpin-NAT reconciliation assertions onto this cluster instead of
711
# spinning up a second ~25m Kamaji bringup.
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#!/usr/bin/env bats
22

3+
# Sourced at file scope (see kubernetes-latest.bats) so cozytest.sh's parent
4+
# shell gets run_kubernetes_test + the cozy_cleanup() hook for the EXIT trap.
5+
. hack/e2e-apps/run-kubernetes.sh
6+
37
@test "Create a tenant Kubernetes control plane with previous version" {
4-
. hack/e2e-apps/run-kubernetes.sh
58
run_kubernetes_test 'keys | sort_by(.) | .[-2]' 'test-previous-version' '59992'
69
}

0 commit comments

Comments
 (0)