Files
my-rook-config/.github/workflows/multus.yaml
T
Joshua Hoblitt d59abb1956 ci: convert integration and canary CI from minikube to kind
The integration and canary suites ran on a single-node minikube
`driver: none` cluster, where the kubelet ran directly on the GitHub
runner, so the host docker daemon doubled as the cluster runtime and
host block devices and host paths were directly visible to pods. Replace
that with a kind cluster.

Every suite creates its cluster through the shared
integration-test-setup-cluster-resources composite action, so the
conversion is centralized there and converts the smoke, object, helm,
keystone, multi-cluster, upgrade, on-release, nightly, encryption-KMS and
all canary jobs at once.

- Replace the setup-minikube step with helm/kind-action, selecting the
  kubernetes version via the kindest/node image tag and creating a
  single-node cluster from a new kind config (kind pinned to v0.32.0 for
  reproducibility).
- Drop the cri-dockerd install; kind nodes use their built-in containerd.
- Add a kind config that bind-mounts the host /dev, /var/lib/rook and
  /run/udev into the node so the existing host-based disk-prep helpers
  (use_local_disk*, create_partitions_for_osds, blockDevicePV.sh,
  localPathPV.sh, ...) keep working unchanged: devices and partitions
  created on the host appear in the node and in the OSD pods that
  hostPath-mount the node /dev, and ceph-volume can read the host udev
  database it needs to inventory disks.
- Prepare the kind node for the host-level operations rook runs against the
  underlying host: remount /sys read-write so CSI's kernel RBD mapping
  (`rbd map --device-type krbd`, which writes /sys/bus/rbd) works, and install
  lvm2 and cryptsetup, which rook runs in the node's mount namespace to
  provision LVM- and encryption-backed OSDs. kindest/node images provide none
  of this; the minikube driver:none runner host did.
- Route the Service and pod CIDRs from the runner to the kind node so
  host-side tests (the `go test` process runs on the runner) can reach
  in-cluster ClusterIPs, e.g. an S3 request to the RGW service. With minikube
  driver:none the runner already shared the cluster network.
- Load locally built images into the cluster. Under minikube `driver: none`
  the built image was already in the cluster runtime; under kind it must be
  imported, so build_rook and create_helm_tag now import their images into
  each node's containerd through a new load_image_into_cluster helper (via the
  node's ctr, which avoids the kind/kindest-node containerd-config version
  skew that breaks `kind load docker-image`).
- Point Vault's kubernetes-auth at the in-cluster API endpoint
  (kubernetes.default.svc) instead of the kubeconfig server URL: kind exposes
  that as https://127.0.0.1:<port>, unreachable from the in-cluster Vault pod,
  so OSD encryption-key retrieval via k8s-auth failed.
- Replace the remaining direct minikube references in the canary workflow: a
  `minikube kubectl` call and the external-cluster topology values.
- Adapt host-name assumptions that only held under driver:none: resolve the
  disk-cleanup job by the k8s node name rather than the runner hostname, and
  let kind-action ignore post-job cluster-teardown failures (the runner is
  ephemeral; nvme/multus devices can wedge `docker rm` of the node).
- Update stale comments that described the CI environment as minikube.
- Move the multus integration test's kind config under tests/config too, so
  both kind cluster configs live in one place.

create-dev-cluster.sh and other local-dev tooling are intentionally left on
minikube.

Signed-off-by: Joshua Hoblitt <josh@hoblitt.com>
2026-07-06 08:42:39 -07:00

128 lines
4.8 KiB
YAML

name: Multus integration tests
on:
push:
tags:
- v*
branches:
- master
- release-*
pull_request:
paths:
- cmd/rook/userfacing/**
- pkg/daemon/multus/**
- .github/workflows/multus.yaml
- tests/scripts/multus/**
defaults:
run:
# reference: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#using-a-specific-shell
shell: bash --noprofile --norc -eo pipefail -x {0}
# cancel the in-progress workflow when PR is refreshed.
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }}
cancel-in-progress: true
permissions:
contents: read
jobs:
test-validation-tool:
runs-on: ubuntu-latest
strategy:
fail-fast: true
if: "!contains(github.event.pull_request.labels.*.name, 'skip-ci')"
steps:
- name: checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
- name: Set up Go version
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with:
go-version: "1.26"
- name: Create KinD Cluster
uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc # v1.14.0
with:
config: tests/config/multus/kind-config.yaml
cluster_name: kind
- name: consider (pre-job) debugging
uses: ./.github/workflows/tmate_debug
with:
use-tmate: ${{ secrets.USE_TMATE }}
debug-ci: ${{ contains(github.event.pull_request.labels.*.name, 'debug-ci') }}
- name: Setup multus
run: ./tests/scripts/multus/setup-multus.sh
- name: Set up multus prerequisite host routing
run: |
kubectl create -f tests/scripts/multus/host-cfg-ds.yaml
kubectl rollout status daemonset/host-net-config --timeout=120s
- name: Install public and cluster NADs in default namespace
run: kubectl create -f tests/scripts/multus/default-public-cluster-nads.yaml
- name: Quickly build Rook binary
id: build
run: go build -tags=ceph_preview -o rook cmd/rook/*.go
- name: Run CLI validation test
run: ./tests/scripts/multus/test-110-cli.sh
- name: Label kind nodes for stretch cluster tests
id: label
# tests that require labels are independent from previous tests
if: steps.build.outcome == 'success' && !cancelled()
run: ./tests/scripts/multus/test-200-stretch-label-nodes.sh
# nodes are purposefully not tainted yet for overlap test
- name: Run stretch cluster overlap test
id: overlap
# independent from other tests as long as nodes are labeled
if: steps.label.outcome == 'success' && !cancelled()
run: ./tests/scripts/multus/test-210-stretch-overlap.sh
- name: Run cleanup test
# cleanup relies on overlap test to be successful
if: steps.overlap.outcome == 'success' && !cancelled()
run: ./tests/scripts/multus/test-211-stretch-cleanup.sh
- name: Taint kind nodes for remaining stretch cluster tests
id: taint
# tests that require taints+labels are independent from previous tests
if: steps.label.outcome == 'success' && !cancelled()
run: ./tests/scripts/multus/test-200-stretch-taint-nodes.sh
- name: Run stretch cluster test with public and cluster networks
# independent from other tests as long as nodes are tainted and labeled
if: steps.taint.outcome == 'success' && !cancelled()
run: ./tests/scripts/multus/test-220-stretch-pub-and-cluster.sh
- name: Run stretch cluster test with public network only
# independent from other tests as long as nodes are tainted and labeled
if: steps.taint.outcome == 'success' && !cancelled()
run: ./tests/scripts/multus/test-230-stretch-pub-only.sh
- name: Run stretch cluster test with cluster network only
# independent from other tests as long as nodes are tainted and labeled
if: steps.taint.outcome == 'success' && !cancelled()
run: ./tests/scripts/multus/test-240-stretch-cluster-only.sh
- name: dump cluster state on failure
if: failure()
run: |
kubectl get nodes -o wide || true
kubectl get pods -A -o wide || true
kubectl -n kube-system describe daemonset kube-multus-ds install-cni-plugins whereabouts || true
kubectl get events -A --sort-by=.lastTimestamp | tail -60 || true
kubectl -n kube-system logs -l name=multus --all-containers --tail=30 || true
- name: consider (post-job) debugging
uses: ./.github/workflows/upterm_debug
with:
debug-ci: ${{ contains(github.event.pull_request.labels.*.name, 'debug-ci') }}