diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index 72f821fe5..20f4980fd 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -8,7 +8,7 @@ The canonical file lives at `.claude/CLAUDE.md`. The root-level `AGENTS.md` is a Skyhook (being renamed to NodeWright) is a Kubernetes-aware package manager for safely modifying host infrastructure at scale. It coordinates the node lifecycle (cordon → drain → apply package → interrupt/reboot → uncordon) as controlled rollouts gated by interruption budgets and deployment policies. -Rename status: the project is transitioning from Skyhook → NodeWright. The namespace (`skyhook`) still uses `skyhook` pending its migration. Components already moved to `nodewright`: the Go module (`github.com/NVIDIA/nodewright/operator`), the Helm chart (`name: nodewright`, distributed at `oci://ghcr.io/nvidia/nodewright/charts/nodewright`), the operator image (`ghcr.io/nvidia/nodewright/operator`), the agent image (`ghcr.io/nvidia/nodewright/agent`, since `agent/v6.4.2`), the primary CRD group (`nodewright.nvidia.com/v1alpha1 NodeWright`; the legacy `skyhook.nvidia.com` group is kept read-only for a migration window), and the CLI plugin (`kubectl nodewright`, binary `kubectl-nodewright`). Don't "fix" `nodewright` references back to `skyhook`, and don't preemptively rename what hasn't moved yet. +Rename status: the project is transitioning from Skyhook → NodeWright. Components already moved to `nodewright`: the install namespace (`nodewright` for new installs; existing installs stay in `skyhook` forever, since namespaces cannot be renamed in place), the Go module (`github.com/NVIDIA/nodewright/operator`), the Helm chart (`name: nodewright`, distributed at `oci://ghcr.io/nvidia/nodewright/charts/nodewright`), the operator image (`ghcr.io/nvidia/nodewright/operator`), the agent image (`ghcr.io/nvidia/nodewright/agent`, since `agent/v6.4.2`), the primary CRD group (`nodewright.nvidia.com/v1alpha1 NodeWright`; the legacy `skyhook.nvidia.com` group is kept read-only for a migration window), and the CLI plugin (`kubectl nodewright`, binary `kubectl-nodewright`). Don't "fix" `nodewright` references back to `skyhook`, and don't preemptively rename what hasn't moved yet. ## Required reading: `docs/` (load every session) @@ -100,7 +100,7 @@ E2E tests use [chainsaw](https://kyverno.github.io/chainsaw/) against a real clu ### CRDs (see `operator/api/v1alpha1/`) -- **Skyhook** (namespaced) — desired state: a DAG of `packages` (container image + version + configMap + optional `dependsOn`), node selector, interruption budget, additional tolerations, runtime-required flag, priority/sequencing, optional `DeploymentPolicy` reference. +- **Skyhook** / **NodeWright** (cluster-scoped) — desired state: a DAG of `packages` (container image + version + configMap + optional `dependsOn`), node selector, interruption budget, additional tolerations, runtime-required flag, priority/sequencing, optional `DeploymentPolicy` reference. Both CRDs are cluster-scoped, so the install namespace only ever determines where the operator and its package pods live, never which CRs a client sees. - **DeploymentPolicy** (cluster-scoped) — rollout shape: batch sizing, pause/resume windows, cross-Skyhook ordering. CRD types are kubebuilder-annotated (`//+kubebuilder:…`). Any change to these files **must** be followed by `make manifests generate` — the generated `zz_generated.deepcopy.go`, CRD YAML under `config/crd/bases/`, and webhook config are all consumed at build time. diff --git a/README.md b/README.md index 567b41c94..24093f716 100644 --- a/README.md +++ b/README.md @@ -76,13 +76,15 @@ Install NodeWright quickly using Helm without downloading the repository: # Helm 3.8+ supports OCI natively — no `helm repo add` needed. helm install nodewright oci://ghcr.io/nvidia/nodewright/charts/nodewright \ --version v0.17.1 \ - --namespace skyhook \ + --namespace nodewright \ --create-namespace ``` > **Where things live:** chart at `oci://ghcr.io/nvidia/nodewright/charts/nodewright`, operator image at `ghcr.io/nvidia/nodewright/operator`, agent image at `ghcr.io/nvidia/nodewright/agent`. NGC / `nvcr.io` distribution is paused — see [docs/release-process.md#distribution-ghcrio-only-for-now](docs/release-process.md#distribution-ghcrio-only-for-now). > > **Migrating from `helm repo add skyhook https://helm.ngc.nvidia.com/...`?** Run `helm repo remove skyhook` and use the OCI install above. If you also want to keep the existing in-cluster release name (e.g. `skyhook`), substitute it for `nodewright` in the `helm install` command — the chart works either way. +> +> **Already installed in the `skyhook` namespace?** Stay there. The documented namespace for **new** installs moved from `skyhook` to `nodewright`, but Kubernetes namespaces cannot be renamed in place and Helm cannot move a release between namespaces, so there is nothing to migrate and no deadline. `kubectl nodewright` finds the operator in either namespace automatically. See [docs/nodewright-migration.md#install-namespace](docs/nodewright-migration.md#install-namespace-skyhook---nodewright). ### Configure Image Pull Secrets (if needed) @@ -92,7 +94,7 @@ If you're using private container registries, create the necessary secrets: kubectl create secret generic node-init-secret \ --from-file=.dockerconfigjson=${HOME}/.docker/config.json \ --type=kubernetes.io/dockerconfigjson \ - --namespace skyhook + --namespace nodewright ``` **Note:** NodeWright currently uses a single shared image pull secret for all packages, and agent/operator containers. If you need access to multiple registries, combine the credentials into one `dockerconfigjson` secret with multiple registry auths. @@ -101,16 +103,16 @@ kubectl create secret generic node-init-secret \ ```bash # Check that the operator is running -kubectl get pods -n skyhook +kubectl get pods -n nodewright # or Wait for the deployment to be available first -kubectl wait --for=condition=Available deployment -l control-plane=controller-manager -n skyhook --timeout=300s +kubectl wait --for=condition=Available deployment -l control-plane=controller-manager -n nodewright --timeout=300s # Then wait for the operator pod to be ready -kubectl wait --for=condition=Ready pod -l control-plane=controller-manager -n skyhook --timeout=300s +kubectl wait --for=condition=Ready pod -l control-plane=controller-manager -n nodewright --timeout=300s # Verify the Ready condition -kubectl get pods -l control-plane=controller-manager -n skyhook -o jsonpath='{.items[0].status.conditions[?(@.type=="Ready")].status}' +kubectl get pods -l control-plane=controller-manager -n nodewright -o jsonpath='{.items[0].status.conditions[?(@.type=="Ready")].status}' # Verify the CRDs are installed kubectl get crd | grep nodewright @@ -154,7 +156,7 @@ kubectl describe nodewright nodewright-sample ```bash # Uninstall the chart (cleanup happens automatically) -helm uninstall nodewright --namespace skyhook +helm uninstall nodewright --namespace nodewright ``` The pre-delete hook will: @@ -170,13 +172,13 @@ The pre-delete hook will: To disable automatic cleanup and manage resources manually: ```bash -helm install nodewright ./chart --namespace skyhook --set cleanup.enabled=false +helm install nodewright ./chart --namespace nodewright --set cleanup.enabled=false ``` To adjust the job timeout: ```bash -helm install nodewright ./chart --namespace skyhook \ +helm install nodewright ./chart --namespace nodewright \ --set cleanup.jobTimeoutSeconds=180 ``` @@ -193,7 +195,7 @@ kubectl delete deploymentpolicies.nodewright.nvidia.com --all kubectl delete deploymentpolicies --all # Then uninstall the chart -helm uninstall nodewright --namespace skyhook +helm uninstall nodewright --namespace nodewright ``` **Why cleanup matters:** If you uninstall while NodeWright CRs with finalizers still exist, it can leave resources in a broken state that may cause reinstall issues. @@ -203,7 +205,7 @@ helm uninstall nodewright --namespace skyhook ### Watch NodeWright apply packages ``` -kubectl get pods -w -n skyhook +kubectl get pods -w -n nodewright ``` There will be a pod for each lifecycle stage (apply, config, etc.) per package per node matching the selector. diff --git a/chart/README.md b/chart/README.md index 3b212a76e..8f5c0ec12 100644 --- a/chart/README.md +++ b/chart/README.md @@ -95,7 +95,7 @@ By default, the Helm chart includes a pre-delete hook that automatically cleans ```bash # Uninstall with automatic cleanup (default) -helm uninstall nodewright --namespace skyhook +helm uninstall nodewright --namespace nodewright ``` The pre-delete hook will: @@ -121,7 +121,7 @@ When disabled, you must manually delete resources before uninstalling to avoid i # Manual cleanup when automatic cleanup is disabled kubectl delete skyhooks --all kubectl delete deploymentpolicies --all -helm uninstall nodewright --namespace skyhook +helm uninstall nodewright --namespace nodewright ``` ### Configuring Timeout Values diff --git a/chart/RELEASE_NOTES.md b/chart/RELEASE_NOTES.md index 15cf77ae1..c9570e25a 100644 --- a/chart/RELEASE_NOTES.md +++ b/chart/RELEASE_NOTES.md @@ -5,6 +5,15 @@ For the full commit-level log see CHANGELOG.md. ## Unreleased +### Other Changes + +- **The documented install namespace for new installs is now `nodewright`.** This is a + documentation and example change only: the chart has always sourced the namespace from + `.Release.Namespace` and installs cleanly into any namespace. **An existing release in + the `skyhook` namespace needs no action** — a namespace cannot be renamed in place and + Helm cannot move a release between namespaces, so `helm upgrade` there keeps working + unchanged and is supported indefinitely. + ### Bug Fixes - **Helm upgrade no longer fails on the immutable Deployment selector after the diff --git a/docs/cli.md b/docs/cli.md index 8cfdf1546..818503b85 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -23,6 +23,42 @@ If the cluster serves only the legacy `skyhook.nvidia.com` group and not naming both groups and telling you to upgrade to a NodeWright-capable operator, rather than a confusing `NotFound`. +### Namespace resolution + +The install namespace for new deployments moved from `skyhook` to `nodewright` with +the rename. Namespaces cannot be renamed in place, and Helm cannot move a release +between namespaces, so an install that predates the rename legitimately stays in +`skyhook` indefinitely. The CLI therefore does **not** simply default to +`nodewright`. + +When `--namespace` is **not** passed, the CLI resolves the operator's namespace in +this order and caches the answer for the invocation: + +1. `nodewright` — if a NodeWright operator Deployment is there, use it. +2. `skyhook` — if the operator is there instead, use it and print a one-line note + to stderr saying the legacy namespace was used and that new installs default to + `nodewright`. Pass `--namespace skyhook` to silence the note. +3. A cluster-wide Deployment sweep, for installs in some other namespace. This + needs cluster-scoped list permission; if you don't have it, the step is skipped + silently rather than failing. +4. If nothing is found, `nodewright` is used so the command's own lookup produces + the specific error (for example, "no operator deployment found in namespace + \"nodewright\""). + +When `--namespace` **is** passed, it is used verbatim with no discovery and no +note. Nothing else about the CLI is version-gated on this: the namespace is only +used to locate the operator Deployment and the package pods. + +The `NodeWright` and `DeploymentPolicy` CRDs are cluster-scoped, so `--namespace` +never affects which CRs a command sees. + +| Situation | `--namespace` omitted | `--namespace` passed | +|-----------|----------------------|----------------------| +| Operator in `nodewright` | ✅ Discovered | ✅ Used as given | +| Operator in `skyhook` (pre-rename install) | ✅ Discovered, with a deprecation note | ✅ Used as given | +| Operator in some other namespace | ✅ Discovered when the user can list Deployments cluster-wide, otherwise falls back to `nodewright` and the command reports the miss | ✅ Used as given | +| No operator installed | ⚠️ Falls back to `nodewright`; the command reports the miss | ⚠️ Command reports the miss | + ### Minimum Operator Version The CLI requires **operator version v0.8.0 or later** for full functionality of all commands. @@ -105,7 +141,7 @@ kubectl nodewright [global-flags] [subcommand] [flags] [arguments] - `-h, --help` - Show help for any command - `--version` - Show version information -- `-n, --namespace` - Kubernetes namespace (default: "skyhook") +- `-n, --namespace` - Kubernetes namespace the operator is installed in. When omitted, the CLI discovers it (see [Namespace resolution](#namespace-resolution)); the fallback default is `nodewright`. - `-o, --output` - Output format: table|json|yaml|wide - `-v, --verbose` - Enable verbose output - `--dry-run` - Preview changes without applying them diff --git a/docs/designs/webhook-bootstrap-lease.md b/docs/designs/webhook-bootstrap-lease.md index 09e493b0e..105301d64 100644 --- a/docs/designs/webhook-bootstrap-lease.md +++ b/docs/designs/webhook-bootstrap-lease.md @@ -102,17 +102,21 @@ specifically, because v0.7.x has no knowledge of the new lease. Operators on v0.7.x still need the manual workaround: ```bash -# In the operator's namespace: -kubectl -n skyhook get pods # identify old-version pods -kubectl -n skyhook delete pod # free the lease +# The operator's namespace. A v0.7.x install predates the skyhook -> nodewright +# namespace default, so it is almost certainly still `skyhook`; `nodewright` is +# the default only for installs created after that change. +NS=skyhook + +kubectl -n "$NS" get pods # identify old-version pods +kubectl -n "$NS" delete pod # free the lease # Or, equivalently: -kubectl -n skyhook delete lease 3c22c1ae.nvidia.com +kubectl -n "$NS" delete lease 3c22c1ae.nvidia.com # Verify recovery: -kubectl -n skyhook get secret webhook-cert -w +kubectl -n "$NS" get secret webhook-cert -w kubectl get mutatingwebhookconfiguration skyhook-operator-mutating-webhook \ -o jsonpath='{.webhooks[0].clientConfig.caBundle}' | wc -c # must be > 0 -kubectl -n skyhook rollout status deploy/skyhook-operator-controller-manager +kubectl -n "$NS" rollout status deploy/skyhook-operator-controller-manager ``` The runbook above should be added to release notes for any future major diff --git a/docs/metrics/README.md b/docs/metrics/README.md index 4f46ee11d..3acc84a45 100644 --- a/docs/metrics/README.md +++ b/docs/metrics/README.md @@ -84,18 +84,18 @@ Note: When a NodeWright is deleted all metrics for that NodeWright are no longer See the script [metrics_test.py](../../k8s-tests/chainsaw/metrics_test.py) that will let you test for the existence or absence of metrics based on name and labels. The metrics endpoint requires a bearer token authorized for the `/metrics` non-resource URL. Create a scraper identity and bind it to the chart's metrics-reader role: ```bash -kubectl -n skyhook create serviceaccount metrics-reader +kubectl -n nodewright create serviceaccount metrics-reader kubectl create clusterrolebinding metrics-reader-access \ --clusterrole=skyhook-operator-metrics-reader \ - --serviceaccount=skyhook:metrics-reader + --serviceaccount=nodewright:metrics-reader ``` Then port-forward the HTTPS Service and scrape it with a short-lived token. TLS verification must be skipped because controller-runtime generates an in-memory self-signed certificate for each operator pod and does not publish a stable CA: ```bash -kubectl -n skyhook port-forward \ +kubectl -n nodewright port-forward \ svc/skyhook-operator-controller-manager-metrics-service 8443:8443 & -METRICS_TOKEN="$(kubectl -n skyhook create token metrics-reader)" +METRICS_TOKEN="$(kubectl -n nodewright create token metrics-reader)" curl --insecure --header "Authorization: Bearer ${METRICS_TOKEN}" \ https://127.0.0.1:8443/metrics ``` @@ -104,7 +104,7 @@ curl --insecure --header "Authorization: Bearer ${METRICS_TOKEN}" \ namespace are provided by flags or environment variables: ```bash -SKYHOOK_NAMESPACE=skyhook \ +SKYHOOK_NAMESPACE=nodewright \ METRICS_TEST_SERVICE_ACCOUNT=metrics-reader \ ./k8s-tests/chainsaw/metrics_test.py \ skyhook_node_target_count 1 -t skyhook_name=my-nodewright @@ -114,7 +114,7 @@ For repeated checks, mint one token and reuse it instead of making a TokenRequest for every invocation: ```bash -METRICS_TOKEN="$(kubectl -n skyhook create token metrics-reader)" +METRICS_TOKEN="$(kubectl -n nodewright create token metrics-reader)" export METRICS_TOKEN ./k8s-tests/chainsaw/metrics_test.py \ skyhook_node_target_count 1 -t skyhook_name=my-nodewright @@ -177,7 +177,7 @@ make create-kind-cluster # Install the operator through the helm chart so that # the /metrics endpoint is setup -helm install skyhook ../chart --namespace skyhook \ +helm install skyhook ../chart --namespace nodewright \ --set metrics.addServiceAccountBinding=true \ --set metrics.serviceAccountName=prometheus \ --set metrics.serviceAccountNamespace=default diff --git a/docs/nodewright-migration.md b/docs/nodewright-migration.md index 6bb312af4..a64f4cf2c 100644 --- a/docs/nodewright-migration.md +++ b/docs/nodewright-migration.md @@ -282,6 +282,44 @@ runtime-required **taint** key is likewise untouched: it did not move in the ren This is transition-only behavior and is removed together with the `skyhook.nvidia.com` group at the removal release. +## Install namespace (`skyhook` -> `nodewright`) + +The documented install namespace for **new** deployments is now `nodewright`. The kustomize +overlay moved from `skyhook-operator-system` to `nodewright-operator-system` to match, and the +operator's own `NAMESPACE` default (used only when nothing sets it, such as a bare binary or +`make run`) moved from `skyhook` to `nodewright`. + +**There is nothing to migrate, and no deadline.** Kubernetes namespaces cannot be renamed in +place, and Helm cannot move a release between namespaces, so moving an existing install would +mean deleting and recreating every namespaced object the operator owns: a real outage in +exchange for a cosmetic name. **Staying in `skyhook` remains fully supported and correct.** The +chart takes the namespace from `.Release.Namespace` throughout and installs cleanly into any +namespace, so `helm upgrade` against an existing `skyhook`-namespace release is unaffected by +this change. + +What this does change: + +- **New installs.** The README and chart docs now use `--namespace nodewright --create-namespace`. + Substitute your own namespace freely; nothing depends on the name. +- **`kubectl nodewright`.** With no `--namespace`, the CLI discovers the operator's namespace + rather than assuming one, so it keeps working against a `skyhook`-namespace install. It checks + `nodewright`, then `skyhook` (printing a one-line note), then sweeps cluster-wide. See + [the CLI reference](cli.md#namespace-resolution). + +If you do want to move an existing install, treat it as an uninstall and reinstall, not a +migration: + +1. Confirm every NodeWright is `complete` with no nodes in progress. +2. `helm uninstall -n skyhook`. The chart's pre-delete hook removes the NodeWright and + DeploymentPolicy CRs; on-node package state (the `nodewright.nvidia.com/*` node annotations) + is **not** removed by this, so it survives. +3. `helm install oci://ghcr.io/nvidia/nodewright/charts/nodewright -n nodewright --create-namespace`. +4. Re-apply your NodeWright CRs. Because the per-node state annotations survived, packages are + not re-run. + +There is no reason to do this on a running cluster unless you have an external requirement on +the namespace name. + ## Downstream consumers (e.g. aicr) Projects that ship or depend on Skyhook CRs need a coordinated update. For example diff --git a/docs/uninstall.md b/docs/uninstall.md index d513d1009..052ecb24b 100644 --- a/docs/uninstall.md +++ b/docs/uninstall.md @@ -2,6 +2,8 @@ NodeWright supports explicit, controlled uninstall of packages from nodes. This document covers the API, workflows, and migration guide. +> `kubectl` examples below use `nodewright`, the default install namespace for new installs. Substitute your own if you installed elsewhere; installs predating the namespace rename are in `skyhook`. + ## API Reference ### `Uninstall` struct @@ -164,8 +166,8 @@ If the operator is rolled back to a version without explicit uninstall support: Check the uninstall pod logs: ```bash -kubectl logs -n skyhook -c -uninstall -kubectl logs -n skyhook -c -uninstallcheck +kubectl logs -n nodewright -c -uninstall +kubectl logs -n nodewright -c -uninstallcheck ``` Check node state: @@ -214,7 +216,7 @@ Any rows returned are nodes the finalizer is waiting on. **Workarounds (pick one; they have different blast radius).** -1. **Fix the underlying install.** Inspect `kubectl logs -n skyhook -c -apply` and correct the script, config, or environment so the install completes. Once the node reaches `stage: config` / `state: complete` (or `post-interrupt/complete` if the package has an interrupt), the finalizer's next reconcile will transition it to `uninstall` and proceed. +1. **Fix the underlying install.** Inspect `kubectl logs -n nodewright -c -apply` and correct the script, config, or environment so the install completes. Once the node reaches `stage: config` / `state: complete` (or `post-interrupt/complete` if the package has an interrupt), the finalizer's next reconcile will transition it to `uninstall` and proceed. 2. **Reset the affected node's NodeWright state.** Use the CLI: @@ -257,7 +259,7 @@ kubectl get nodes -l -o json \ And verify no interrupt pod exists for the package: ```bash -kubectl get pods -n skyhook -l nodewright.nvidia.com/name=,nodewright.nvidia.com/package=-,nodewright.nvidia.com/interrupt=True +kubectl get pods -n nodewright -l nodewright.nvidia.com/name=,nodewright.nvidia.com/package=-,nodewright.nvidia.com/interrupt=True ``` An entry from the first command with no rows from the second confirms the stranded state. diff --git a/docs/versioning.md b/docs/versioning.md index ed696a477..ea825be8d 100644 --- a/docs/versioning.md +++ b/docs/versioning.md @@ -96,10 +96,12 @@ go get github.com/NVIDIA/nodewright/operator@v0.8.0 ## Quick Reference +> These examples use `nodewright`, the default install namespace for new installs. Substitute your own if you installed elsewhere; installs predating the namespace rename are in `skyhook`. + ```bash # Check deployed versions -kubectl get deployment -n skyhook -o jsonpath='{.items[0].spec.template.spec.containers[0].image}' -helm list -n skyhook +kubectl get deployment -n nodewright -o jsonpath='{.items[0].spec.template.spec.containers[0].image}' +helm list -n nodewright # Override operator version helm install skyhook ./chart --set controllerManager.manager.image.tag="0.8.0" diff --git a/k8s-tests/chainsaw/cli/reset-package/chainsaw-test.yaml b/k8s-tests/chainsaw/cli/reset-package/chainsaw-test.yaml index 115a0ada2..3f4335742 100644 --- a/k8s-tests/chainsaw/cli/reset-package/chainsaw-test.yaml +++ b/k8s-tests/chainsaw/cli/reset-package/chainsaw-test.yaml @@ -38,7 +38,7 @@ spec: - get: apiVersion: v1 kind: Pod - namespace: skyhook + namespace: nodewright format: yaml steps: # Step 0: Reset state from previous runs diff --git a/k8s-tests/chainsaw/cli/update-state-reject/chainsaw-test.yaml b/k8s-tests/chainsaw/cli/update-state-reject/chainsaw-test.yaml index f13ab5aee..af1809920 100644 --- a/k8s-tests/chainsaw/cli/update-state-reject/chainsaw-test.yaml +++ b/k8s-tests/chainsaw/cli/update-state-reject/chainsaw-test.yaml @@ -38,7 +38,7 @@ spec: - get: apiVersion: v1 kind: Pod - namespace: skyhook + namespace: nodewright format: yaml steps: # Step 0: Reset state from previous runs diff --git a/k8s-tests/chainsaw/cli/update-state/chainsaw-test.yaml b/k8s-tests/chainsaw/cli/update-state/chainsaw-test.yaml index 3996b6272..226e17047 100644 --- a/k8s-tests/chainsaw/cli/update-state/chainsaw-test.yaml +++ b/k8s-tests/chainsaw/cli/update-state/chainsaw-test.yaml @@ -38,7 +38,7 @@ spec: - get: apiVersion: v1 kind: Pod - namespace: skyhook + namespace: nodewright format: yaml steps: # Step 0: Reset state from previous runs diff --git a/k8s-tests/chainsaw/deployment-policy/readme.md b/k8s-tests/chainsaw/deployment-policy/readme.md index 25a4ec19d..fa98eab2d 100644 --- a/k8s-tests/chainsaw/deployment-policy/readme.md +++ b/k8s-tests/chainsaw/deployment-policy/readme.md @@ -49,7 +49,7 @@ make run make prepare-metrics-test-access cd ../k8s-tests/chainsaw/deployment-policy -SKYHOOK_NAMESPACE=skyhook \ +SKYHOOK_NAMESPACE=nodewright \ METRICS_TEST_SERVICE_ACCOUNT=metrics-reader \ ../../../operator/bin/chainsaw test --test-dir linear-strategy ``` diff --git a/k8s-tests/chainsaw/helm/events-rbac-test/chainsaw-test.yaml b/k8s-tests/chainsaw/helm/events-rbac-test/chainsaw-test.yaml index d1d1d4dc0..9d06f58b0 100644 --- a/k8s-tests/chainsaw/helm/events-rbac-test/chainsaw-test.yaml +++ b/k8s-tests/chainsaw/helm/events-rbac-test/chainsaw-test.yaml @@ -20,7 +20,7 @@ kind: Test metadata: name: helm-events-rbac spec: - # Installs into the shared `skyhook` namespace, so keep it serial with the + # Installs into the shared `nodewright` namespace, so keep it serial with the # other helm tests. concurrent: false timeouts: @@ -45,7 +45,7 @@ spec: # chainsaw runs script content under POSIX /bin/sh (dash in CI), so # keep this POSIX-clean: no `pipefail`, `[[ ]]`, or other bashisms. set -u - NS=skyhook + NS=nodewright # Resolve the operator ServiceAccount from the manager Deployment rather # than hard-coding it, so the test survives a fullnameOverride change. @@ -84,7 +84,7 @@ spec: content: | ## Remove the chart regardless of assertion outcome. Do not swallow the ## exit status: a failed uninstall leaks resources into the shared - ## skyhook namespace and would contaminate later tests. + ## nodewright namespace and would contaminate later tests. if ! ../uninstall-helm-chart.sh events-rbac; then echo "FAIL: could not uninstall Helm release events-rbac" >&2 exit 1 diff --git a/k8s-tests/chainsaw/helm/helm-chart-test/assert-no-schedule.yaml b/k8s-tests/chainsaw/helm/helm-chart-test/assert-no-schedule.yaml index 0b47a11e5..573dcc026 100644 --- a/k8s-tests/chainsaw/helm/helm-chart-test/assert-no-schedule.yaml +++ b/k8s-tests/chainsaw/helm/helm-chart-test/assert-no-schedule.yaml @@ -24,7 +24,7 @@ metadata: app.kubernetes.io/instance: foobar app.kubernetes.io/name: nodewright control-plane: controller-manager - namespace: skyhook + namespace: nodewright ownerReferences: - apiVersion: apps/v1 blockOwnerDeletion: true diff --git a/k8s-tests/chainsaw/helm/helm-chart-test/assert-scheduled.yaml b/k8s-tests/chainsaw/helm/helm-chart-test/assert-scheduled.yaml index 20c3854a5..48bb1beef 100644 --- a/k8s-tests/chainsaw/helm/helm-chart-test/assert-scheduled.yaml +++ b/k8s-tests/chainsaw/helm/helm-chart-test/assert-scheduled.yaml @@ -24,7 +24,7 @@ metadata: app.kubernetes.io/instance: foobar app.kubernetes.io/name: nodewright control-plane: controller-manager - namespace: skyhook + namespace: nodewright ownerReferences: - apiVersion: apps/v1 blockOwnerDeletion: true diff --git a/k8s-tests/chainsaw/helm/helm-node-affinity-test/assert-no-schedule.yaml b/k8s-tests/chainsaw/helm/helm-node-affinity-test/assert-no-schedule.yaml index 93dc0ba2a..d192f6628 100644 --- a/k8s-tests/chainsaw/helm/helm-node-affinity-test/assert-no-schedule.yaml +++ b/k8s-tests/chainsaw/helm/helm-node-affinity-test/assert-no-schedule.yaml @@ -24,7 +24,7 @@ metadata: app.kubernetes.io/instance: node-affinity-test app.kubernetes.io/name: nodewright control-plane: controller-manager - namespace: skyhook + namespace: nodewright ownerReferences: - apiVersion: apps/v1 blockOwnerDeletion: true diff --git a/k8s-tests/chainsaw/helm/helm-node-affinity-test/assert-scheduled.yaml b/k8s-tests/chainsaw/helm/helm-node-affinity-test/assert-scheduled.yaml index 08db29b46..c0999ff16 100644 --- a/k8s-tests/chainsaw/helm/helm-node-affinity-test/assert-scheduled.yaml +++ b/k8s-tests/chainsaw/helm/helm-node-affinity-test/assert-scheduled.yaml @@ -24,7 +24,7 @@ metadata: app.kubernetes.io/instance: node-affinity-test app.kubernetes.io/name: nodewright control-plane: controller-manager - namespace: skyhook + namespace: nodewright ownerReferences: - apiVersion: apps/v1 blockOwnerDeletion: true diff --git a/k8s-tests/chainsaw/helm/helm-scale-test/assert-override-resources.yaml b/k8s-tests/chainsaw/helm/helm-scale-test/assert-override-resources.yaml index 5f55ca0d1..7f1f7ec71 100644 --- a/k8s-tests/chainsaw/helm/helm-scale-test/assert-override-resources.yaml +++ b/k8s-tests/chainsaw/helm/helm-scale-test/assert-override-resources.yaml @@ -24,7 +24,7 @@ metadata: app.kubernetes.io/instance: foobar app.kubernetes.io/name: nodewright control-plane: controller-manager - namespace: skyhook + namespace: nodewright spec: containers: - command: diff --git a/k8s-tests/chainsaw/helm/helm-scale-test/assert-scaled-resources.yaml b/k8s-tests/chainsaw/helm/helm-scale-test/assert-scaled-resources.yaml index ce87a8dd8..e516eb24b 100644 --- a/k8s-tests/chainsaw/helm/helm-scale-test/assert-scaled-resources.yaml +++ b/k8s-tests/chainsaw/helm/helm-scale-test/assert-scaled-resources.yaml @@ -24,7 +24,7 @@ metadata: app.kubernetes.io/instance: foobar app.kubernetes.io/name: nodewright control-plane: controller-manager - namespace: skyhook + namespace: nodewright spec: containers: - command: diff --git a/k8s-tests/chainsaw/helm/helm-template-test/README.md b/k8s-tests/chainsaw/helm/helm-template-test/README.md index 7dc404238..fb64004e0 100644 --- a/k8s-tests/chainsaw/helm/helm-template-test/README.md +++ b/k8s-tests/chainsaw/helm/helm-template-test/README.md @@ -67,7 +67,7 @@ Use when you need to verify specific fields exist at the correct YAML path in a - name: CHAINSAW_BIN value: ($CHAINSAW_BIN) content: | - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ -s templates/cleanup-skyhooks-job.yaml > /tmp/rendered.yaml cat <<'EXPECTED' | ${CHAINSAW_BIN} assert \ --resource /tmp/rendered.yaml --file - --no-color --timeout 5s @@ -102,7 +102,7 @@ Use when you need to verify a gated template produces **no output** when its con - name: CHART value: ($CHART) content: | - helm template test-release ${CHART} -n skyhook --set-json 'limitRange=null' \ + helm template test-release ${CHART} -n nodewright --set-json 'limitRange=null' \ -s templates/limitrange.yaml check: ($error != null): true @@ -120,7 +120,7 @@ Use for simple presence/absence checks where structural assertion would be overk - name: CHART value: ($CHART) content: | - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ --set 'useHostNetwork=true' \ -s templates/deployment.yaml check: diff --git a/k8s-tests/chainsaw/helm/helm-template-test/chainsaw-test.yaml b/k8s-tests/chainsaw/helm/helm-template-test/chainsaw-test.yaml index 496596540..cc15d6540 100644 --- a/k8s-tests/chainsaw/helm/helm-template-test/chainsaw-test.yaml +++ b/k8s-tests/chainsaw/helm/helm-template-test/chainsaw-test.yaml @@ -41,7 +41,7 @@ spec: - name: CHAINSAW_BIN value: ($CHAINSAW_BIN) content: | - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ -s templates/limitrange.yaml > /tmp/rendered.yaml cat <<'EXPECTED' | ${CHAINSAW_BIN} assert \ --resource /tmp/rendered.yaml --file - --no-color --timeout 5s @@ -67,7 +67,7 @@ spec: - name: CHAINSAW_BIN value: ($CHAINSAW_BIN) content: | - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ -s templates/cleanup-skyhooks-job.yaml > /tmp/rendered.yaml cat <<'EXPECTED' | ${CHAINSAW_BIN} assert \ --resource /tmp/rendered.yaml --file - --no-color --timeout 5s @@ -96,7 +96,7 @@ spec: - name: CHAINSAW_BIN value: ($CHAINSAW_BIN) content: | - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ -s templates/cleanup-webhook-job.yaml > /tmp/rendered.yaml cat <<'EXPECTED' | ${CHAINSAW_BIN} assert \ --resource /tmp/rendered.yaml --file - --no-color --timeout 5s @@ -128,7 +128,7 @@ spec: ## The controller-manager Deployment selector must carry the full, ## specific managerSelectorLabels set (not a single vague label), so ## it stays stable and the selector-migration hook can match it. - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ -s templates/deployment.yaml > /tmp/rendered.yaml cat <<'EXPECTED' | ${CHAINSAW_BIN} assert \ --resource /tmp/rendered.yaml --file - --no-color --timeout 5s @@ -158,7 +158,7 @@ spec: ## (name=nodewright), not the overridden name. (Asserted by kind, since ## deployment.yaml also renders the PDB; the preserved Deployment name ## is covered by the Role/hook assertions below.) - helm template skyhook-operator ${CHART} -n skyhook \ + helm template skyhook-operator ${CHART} -n nodewright \ --set fullnameOverride=skyhook-operator \ -s templates/deployment.yaml > /tmp/rendered.yaml cat <<'EXPECTED' | ${CHAINSAW_BIN} assert \ @@ -181,7 +181,7 @@ spec: content: | ## The hook's RBAC must follow the overridden name so it can delete the ## right Deployment. - helm template skyhook-operator ${CHART} -n skyhook \ + helm template skyhook-operator ${CHART} -n nodewright \ --set fullnameOverride=skyhook-operator \ -s templates/selector-migration-role.yaml > /tmp/rendered.yaml cat <<'EXPECTED' | ${CHAINSAW_BIN} assert \ @@ -200,7 +200,7 @@ spec: value: ($CHART) content: | ## The hook command targets the overridden Deployment name. - helm template skyhook-operator ${CHART} -n skyhook \ + helm template skyhook-operator ${CHART} -n nodewright \ --set fullnameOverride=skyhook-operator \ -s templates/selector-migration-job.yaml check: @@ -217,7 +217,7 @@ spec: content: | ## The pre-upgrade hook Job is wired as a pre-upgrade hook, runs under ## its dedicated ServiceAccount, and has a single migration container. - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ -s templates/selector-migration-job.yaml > /tmp/rendered.yaml cat <<'EXPECTED' | ${CHAINSAW_BIN} assert \ --resource /tmp/rendered.yaml --file - --no-color --timeout 5s @@ -250,7 +250,7 @@ spec: ## Also assert the hook compares the FULL managerSelectorLabels set, not ## just control-plane: a regression to a single label would reintroduce ## the upgrade failure for rename/fullnameOverride installs. - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ -s templates/selector-migration-job.yaml check: "(contains($stdout, 'image: alpine/kubectl'))": true @@ -274,7 +274,7 @@ spec: - name: CHAINSAW_BIN value: ($CHAINSAW_BIN) content: | - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ -s templates/selector-migration-serviceaccount.yaml > /tmp/rendered.yaml cat <<'EXPECTED' | ${CHAINSAW_BIN} assert \ --resource /tmp/rendered.yaml --file - --no-color --timeout 5s @@ -297,7 +297,7 @@ spec: value: ($CHAINSAW_BIN) content: | ## Least-privilege: get/delete on the controller-manager deployment only. - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ -s templates/selector-migration-role.yaml > /tmp/rendered.yaml cat <<'EXPECTED' | ${CHAINSAW_BIN} assert \ --resource /tmp/rendered.yaml --file - --no-color --timeout 5s @@ -326,7 +326,7 @@ spec: - name: CHAINSAW_BIN value: ($CHAINSAW_BIN) content: | - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ -s templates/selector-migration-rolebinding.yaml > /tmp/rendered.yaml cat <<'EXPECTED' | ${CHAINSAW_BIN} assert \ --resource /tmp/rendered.yaml --file - --no-color --timeout 5s @@ -353,7 +353,7 @@ spec: ## With the hook disabled, none of the selector-migration templates ## should render (-s exits non-zero when a gated template is empty). for f in serviceaccount role rolebinding job; do - if helm template test-release ${CHART} -n skyhook \ + if helm template test-release ${CHART} -n nodewright \ --set 'selectorMigration.enabled=false' \ -s templates/selector-migration-$f.yaml 2>/dev/null; then echo "ERROR: selector-migration-$f.yaml rendered while disabled" @@ -372,7 +372,7 @@ spec: value: ($CHAINSAW_BIN) content: | ## LimitRange disabled, but cleanup job should still have fallback resources - helm template test-release ${CHART} -n skyhook --set-json 'limitRange=null' \ + helm template test-release ${CHART} -n nodewright --set-json 'limitRange=null' \ -s templates/cleanup-skyhooks-job.yaml > /tmp/rendered.yaml cat <<'EXPECTED' | ${CHAINSAW_BIN} assert \ --resource /tmp/rendered.yaml --file - --no-color --timeout 5s @@ -400,7 +400,7 @@ spec: value: ($CHART) content: | ## -s errors when a gated template produces no output - helm template test-release ${CHART} -n skyhook --set-json 'limitRange=null' \ + helm template test-release ${CHART} -n nodewright --set-json 'limitRange=null' \ -s templates/limitrange.yaml check: ($error != null): true @@ -412,7 +412,7 @@ spec: - name: CHART value: ($CHART) content: | - helm template test-release ${CHART} -n skyhook --set 'limitRange=false' \ + helm template test-release ${CHART} -n nodewright --set 'limitRange=false' \ -s templates/limitrange.yaml check: ($error != null): true @@ -424,7 +424,7 @@ spec: - name: CHART value: ($CHART) content: | - helm template test-release ${CHART} -n skyhook --set 'webhook.enable=false' \ + helm template test-release ${CHART} -n nodewright --set 'webhook.enable=false' \ -s templates/cleanup-webhook-job.yaml check: ($error != null): true @@ -436,7 +436,7 @@ spec: - name: CHART value: ($CHART) content: | - helm template test-release ${CHART} -n skyhook --set 'cleanup.enabled=false' \ + helm template test-release ${CHART} -n nodewright --set 'cleanup.enabled=false' \ -s templates/cleanup-skyhooks-job.yaml check: ($error != null): true @@ -461,7 +461,7 @@ spec: - name: CHART value: ($CHART) content: | - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ --set 'controllerManager.selectors.dedicated=system-workload' \ --set 'controllerManager.nodeAffinity.matchExpressions[0].key=foo' \ --set 'controllerManager.nodeAffinity.matchExpressions[0].operator=Exists' \ @@ -476,7 +476,7 @@ spec: - name: CHART value: ($CHART) content: | - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ --set 'controllerManager.podDisruptionBudget.minAvailable=2' \ --set 'controllerManager.replicas=2' \ 2>&1 || true @@ -492,7 +492,7 @@ spec: - name: CHART value: ($CHART) content: | - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ -s templates/skyhook_viewer_role.yaml check: ($error != null): true @@ -501,7 +501,7 @@ spec: - name: CHART value: ($CHART) content: | - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ -s templates/skyhook_editor_role.yaml check: ($error != null): true @@ -515,7 +515,7 @@ spec: - name: CHAINSAW_BIN value: ($CHAINSAW_BIN) content: | - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ --set 'rbac.createSkyhookViewerRole=true' \ -s templates/skyhook_viewer_role.yaml > /tmp/rendered.yaml cat <<'EXPECTED' | ${CHAINSAW_BIN} assert \ @@ -535,7 +535,7 @@ spec: - name: CHAINSAW_BIN value: ($CHAINSAW_BIN) content: | - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ --set 'rbac.createSkyhookEditorRole=true' \ -s templates/skyhook_editor_role.yaml > /tmp/rendered.yaml cat <<'EXPECTED' | ${CHAINSAW_BIN} assert \ @@ -553,7 +553,7 @@ spec: - name: CHART value: ($CHART) content: | - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ --set 'imagePullSecret=my-registry-secret' \ -s templates/deployment.yaml check: @@ -566,7 +566,7 @@ spec: - name: CHART value: ($CHART) content: | - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ -s templates/deployment.yaml check: "(contains($stdout, 'hostNetwork: true'))": false @@ -578,7 +578,7 @@ spec: - name: CHART value: ($CHART) content: | - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ --set 'useHostNetwork=true' \ -s templates/deployment.yaml check: @@ -591,7 +591,7 @@ spec: - name: CHART value: ($CHART) content: | - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ -s templates/metrics-reader-rbac.yaml check: "(contains($stdout, 'kind: ClusterRoleBinding'))": false @@ -603,7 +603,7 @@ spec: - name: CHART value: ($CHART) content: | - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ --set 'metrics.addServiceAccountBinding=true' \ -s templates/metrics-reader-rbac.yaml check: @@ -627,7 +627,7 @@ spec: - name: CHAINSAW_BIN value: ($CHAINSAW_BIN) content: | - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ --set 'controllerManager.tolerations[0].key=dedicated' \ --set 'controllerManager.tolerations[0].operator=Equal' \ --set 'controllerManager.tolerations[0].value=system-cpu' \ @@ -656,7 +656,7 @@ spec: - name: CHAINSAW_BIN value: ($CHAINSAW_BIN) content: | - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ --set 'controllerManager.tolerations[0].key=dedicated' \ --set 'controllerManager.tolerations[0].operator=Equal' \ --set 'controllerManager.tolerations[0].value=system-cpu' \ @@ -689,7 +689,7 @@ spec: ## restrictive placement makes the pre-delete hook unschedulable. The ## job still renders fully (SA + cleanup container); only nodeSelector ## is dropped. (== null asserts the field is absent, not merely empty.) - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ --set 'controllerManager.selectors.dedicated=system-workload' \ -s templates/cleanup-skyhooks-job.yaml > /tmp/rendered.yaml cat <<'EXPECTED' | ${CHAINSAW_BIN} assert \ @@ -720,7 +720,7 @@ spec: - name: CHAINSAW_BIN value: ($CHAINSAW_BIN) content: | - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ --set 'controllerManager.selectors.dedicated=system-workload' \ -s templates/cleanup-webhook-job.yaml > /tmp/rendered.yaml cat <<'EXPECTED' | ${CHAINSAW_BIN} assert \ @@ -755,7 +755,7 @@ spec: ## restrictive placement makes the pre-delete hook unschedulable. The ## job still renders fully (SA + cleanup container); only affinity is ## dropped. (== null asserts the field is absent, not merely empty.) - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ --set 'controllerManager.nodeAffinity.matchExpressions[0].key=gpu-type' \ --set 'controllerManager.nodeAffinity.matchExpressions[0].operator=In' \ --set 'controllerManager.nodeAffinity.matchExpressions[0].values[0]=a100' \ @@ -783,7 +783,7 @@ spec: - name: CHAINSAW_BIN value: ($CHAINSAW_BIN) content: | - helm template test-release ${CHART} -n skyhook \ + helm template test-release ${CHART} -n nodewright \ --set 'controllerManager.nodeAffinity.matchExpressions[0].key=gpu-type' \ --set 'controllerManager.nodeAffinity.matchExpressions[0].operator=In' \ --set 'controllerManager.nodeAffinity.matchExpressions[0].values[0]=a100' \ diff --git a/k8s-tests/chainsaw/helm/helm-webhook-test/assert-scheduled.yaml b/k8s-tests/chainsaw/helm/helm-webhook-test/assert-scheduled.yaml index e27aa818e..c5d3a065e 100644 --- a/k8s-tests/chainsaw/helm/helm-webhook-test/assert-scheduled.yaml +++ b/k8s-tests/chainsaw/helm/helm-webhook-test/assert-scheduled.yaml @@ -24,7 +24,7 @@ metadata: app.kubernetes.io/instance: webhooks app.kubernetes.io/name: nodewright control-plane: controller-manager - namespace: skyhook + namespace: nodewright ownerReferences: - apiVersion: apps/v1 blockOwnerDeletion: true diff --git a/k8s-tests/chainsaw/helm/helm-webhook-test/assert-webhook.yaml b/k8s-tests/chainsaw/helm/helm-webhook-test/assert-webhook.yaml index d2727a0fe..358e36576 100644 --- a/k8s-tests/chainsaw/helm/helm-webhook-test/assert-webhook.yaml +++ b/k8s-tests/chainsaw/helm/helm-webhook-test/assert-webhook.yaml @@ -19,7 +19,7 @@ apiVersion: v1 kind: Secret metadata: name: webhook-cert - namespace: skyhook + namespace: nodewright --- apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration diff --git a/k8s-tests/chainsaw/helm/install-helm-chart.sh b/k8s-tests/chainsaw/helm/install-helm-chart.sh index 1daafb1a3..290b5e9ee 100755 --- a/k8s-tests/chainsaw/helm/install-helm-chart.sh +++ b/k8s-tests/chainsaw/helm/install-helm-chart.sh @@ -52,4 +52,4 @@ if [ -n "${LOCAL_OPERATOR_IMG:-}" ]; then fi ## install operator -${HELM} upgrade --install ${OPERATOR_NAME} ../../../../chart -n skyhook -f ${VALUES_FILE_NAME} "${LOCAL_OPERATOR_IMG_ARGS[@]}" +${HELM} upgrade --install ${OPERATOR_NAME} ../../../../chart -n nodewright -f ${VALUES_FILE_NAME} "${LOCAL_OPERATOR_IMG_ARGS[@]}" diff --git a/k8s-tests/chainsaw/helm/uninstall-helm-chart.sh b/k8s-tests/chainsaw/helm/uninstall-helm-chart.sh index 5169d51a1..e670f7ec8 100755 --- a/k8s-tests/chainsaw/helm/uninstall-helm-chart.sh +++ b/k8s-tests/chainsaw/helm/uninstall-helm-chart.sh @@ -28,4 +28,4 @@ else fi ## remove operator -${HELM} delete $OPERATOR_NAME -n skyhook +${HELM} delete $OPERATOR_NAME -n nodewright diff --git a/k8s-tests/chainsaw/nodewright/cleanup-pods/assert-config-complete.yaml b/k8s-tests/chainsaw/nodewright/cleanup-pods/assert-config-complete.yaml index e617afc64..3bdf869e7 100644 --- a/k8s-tests/chainsaw/nodewright/cleanup-pods/assert-config-complete.yaml +++ b/k8s-tests/chainsaw/nodewright/cleanup-pods/assert-config-complete.yaml @@ -18,7 +18,7 @@ kind: Pod apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: cleanup-pods nodewright.nvidia.com/package: bb-1.2 diff --git a/k8s-tests/chainsaw/nodewright/cleanup-pods/chainsaw-test.yaml b/k8s-tests/chainsaw/nodewright/cleanup-pods/chainsaw-test.yaml index 78ec49d92..142fca5a8 100644 --- a/k8s-tests/chainsaw/nodewright/cleanup-pods/chainsaw-test.yaml +++ b/k8s-tests/chainsaw/nodewright/cleanup-pods/chainsaw-test.yaml @@ -73,7 +73,7 @@ spec: kind: Pod apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: cleanup-pods nodewright.nvidia.com/package: aa-1.2.3 @@ -110,7 +110,7 @@ spec: kind: Pod apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: cleanup-pods nodewright.nvidia.com/package: aa-1.2.3 @@ -147,7 +147,7 @@ spec: kind: Pod apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: cleanup-pods nodewright.nvidia.com/package: bb-1.2 diff --git a/k8s-tests/chainsaw/nodewright/config-nodewright/assert-cm-deploy.yaml b/k8s-tests/chainsaw/nodewright/config-nodewright/assert-cm-deploy.yaml index 4f0e7b465..8ab0dfe9e 100644 --- a/k8s-tests/chainsaw/nodewright/config-nodewright/assert-cm-deploy.yaml +++ b/k8s-tests/chainsaw/nodewright/config-nodewright/assert-cm-deploy.yaml @@ -19,7 +19,7 @@ kind: ConfigMap apiVersion: v1 metadata: name: config-skyhook-dexter-1.2.3 - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: config-skyhook ownerReferences: @@ -44,7 +44,7 @@ kind: ConfigMap apiVersion: v1 metadata: name: config-skyhook-baxter-3.2.1 - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: config-skyhook ownerReferences: @@ -68,7 +68,7 @@ data: kind: ConfigMap apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/skyhook-node-meta: config-skyhook ownerReferences: diff --git a/k8s-tests/chainsaw/nodewright/config-nodewright/assert-cm-update-no-interrupt.yaml b/k8s-tests/chainsaw/nodewright/config-nodewright/assert-cm-update-no-interrupt.yaml index 7461240f7..93521426c 100644 --- a/k8s-tests/chainsaw/nodewright/config-nodewright/assert-cm-update-no-interrupt.yaml +++ b/k8s-tests/chainsaw/nodewright/config-nodewright/assert-cm-update-no-interrupt.yaml @@ -19,7 +19,7 @@ kind: ConfigMap apiVersion: v1 metadata: name: config-skyhook-dexter-1.2.3 - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: config-skyhook ownerReferences: @@ -38,7 +38,7 @@ kind: ConfigMap apiVersion: v1 metadata: name: config-skyhook-baxter-3.2.1 - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: config-skyhook ownerReferences: @@ -56,7 +56,7 @@ data: kind: ConfigMap apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/skyhook-node-meta: config-skyhook ownerReferences: diff --git a/k8s-tests/chainsaw/nodewright/config-nodewright/assert-cm-update-while-running.yaml b/k8s-tests/chainsaw/nodewright/config-nodewright/assert-cm-update-while-running.yaml index b420236c8..7696edcfc 100644 --- a/k8s-tests/chainsaw/nodewright/config-nodewright/assert-cm-update-while-running.yaml +++ b/k8s-tests/chainsaw/nodewright/config-nodewright/assert-cm-update-while-running.yaml @@ -19,7 +19,7 @@ kind: ConfigMap apiVersion: v1 metadata: name: config-skyhook-dexter-1.2.3 - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: config-skyhook ownerReferences: @@ -44,7 +44,7 @@ kind: ConfigMap apiVersion: v1 metadata: name: config-skyhook-baxter-3.2.1 - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: config-skyhook ownerReferences: @@ -65,7 +65,7 @@ data: kind: ConfigMap apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/skyhook-node-meta: config-skyhook ownerReferences: diff --git a/k8s-tests/chainsaw/nodewright/config-nodewright/assert-cm-update.yaml b/k8s-tests/chainsaw/nodewright/config-nodewright/assert-cm-update.yaml index c980c5217..58dc9069e 100644 --- a/k8s-tests/chainsaw/nodewright/config-nodewright/assert-cm-update.yaml +++ b/k8s-tests/chainsaw/nodewright/config-nodewright/assert-cm-update.yaml @@ -19,7 +19,7 @@ kind: ConfigMap apiVersion: v1 metadata: name: config-skyhook-dexter-1.2.3 - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: config-skyhook ownerReferences: @@ -41,7 +41,7 @@ kind: ConfigMap apiVersion: v1 metadata: name: config-skyhook-baxter-3.2.1 - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: config-skyhook ownerReferences: @@ -62,7 +62,7 @@ data: kind: ConfigMap apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/skyhook-node-meta: config-skyhook ownerReferences: diff --git a/k8s-tests/chainsaw/nodewright/config-nodewright/assert-update-glob.yaml b/k8s-tests/chainsaw/nodewright/config-nodewright/assert-update-glob.yaml index 870022c5c..d3af41e91 100644 --- a/k8s-tests/chainsaw/nodewright/config-nodewright/assert-update-glob.yaml +++ b/k8s-tests/chainsaw/nodewright/config-nodewright/assert-update-glob.yaml @@ -18,7 +18,7 @@ apiVersion: v1 kind: Pod metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: config-skyhook nodewright.nvidia.com/package: dexter-1.2.3 @@ -93,7 +93,7 @@ kind: ConfigMap apiVersion: v1 metadata: name: config-skyhook-dexter-1.2.3 - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: config-skyhook ownerReferences: diff --git a/k8s-tests/chainsaw/nodewright/delete-nodewright/assert.yaml b/k8s-tests/chainsaw/nodewright/delete-nodewright/assert.yaml index 128e43cba..4bcf39ad2 100644 --- a/k8s-tests/chainsaw/nodewright/delete-nodewright/assert.yaml +++ b/k8s-tests/chainsaw/nodewright/delete-nodewright/assert.yaml @@ -90,7 +90,7 @@ kind: ConfigMap apiVersion: v1 metadata: name: delete-skyhook-dexter-1.2.3 - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: delete-skyhook ownerReferences: @@ -114,7 +114,7 @@ data: kind: ConfigMap apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/skyhook-node-meta: delete-skyhook ownerReferences: diff --git a/k8s-tests/chainsaw/nodewright/depends-on/chainsaw-test.yaml b/k8s-tests/chainsaw/nodewright/depends-on/chainsaw-test.yaml index 9009a89f9..3d99b9921 100644 --- a/k8s-tests/chainsaw/nodewright/depends-on/chainsaw-test.yaml +++ b/k8s-tests/chainsaw/nodewright/depends-on/chainsaw-test.yaml @@ -39,7 +39,7 @@ spec: - get: apiVersion: v1 kind: Pod - namespace: skyhook + namespace: nodewright selector: nodewright.nvidia.com/name=depends-on format: yaml steps: @@ -59,7 +59,7 @@ spec: kind: Pod apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: depends-on nodewright.nvidia.com/package: aa-fast-1.2.3 @@ -78,7 +78,7 @@ spec: kind: Pod apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: depends-on nodewright.nvidia.com/package: bb-slow-1.2 @@ -97,7 +97,7 @@ spec: kind: Pod apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: depends-on nodewright.nvidia.com/package: aa-fast-1.2.3 @@ -116,7 +116,7 @@ spec: kind: Pod apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: depends-on nodewright.nvidia.com/package: bb-slow-1.2 @@ -135,7 +135,7 @@ spec: kind: Pod apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: depends-on nodewright.nvidia.com/package: cc-last-5.4.3 @@ -154,7 +154,7 @@ spec: kind: Pod apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: depends-on nodewright.nvidia.com/package: cc-last-5.4.3 diff --git a/k8s-tests/chainsaw/nodewright/drain-config/chainsaw-test.yaml b/k8s-tests/chainsaw/nodewright/drain-config/chainsaw-test.yaml index d858e46bd..3942c17d9 100644 --- a/k8s-tests/chainsaw/nodewright/drain-config/chainsaw-test.yaml +++ b/k8s-tests/chainsaw/nodewright/drain-config/chainsaw-test.yaml @@ -35,18 +35,18 @@ spec: apiVersion: nodewright.nvidia.com/v1alpha1 kind: NodeWright name: drain-config-disable-eviction - namespace: skyhook + namespace: nodewright format: yaml - get: apiVersion: nodewright.nvidia.com/v1alpha1 kind: NodeWright name: drain-config-timeout - namespace: skyhook + namespace: nodewright format: yaml - get: apiVersion: v1 kind: Pod - namespace: skyhook + namespace: nodewright selector: app in (drain-config-pdb,drain-config-blocker) format: yaml steps: @@ -56,29 +56,29 @@ spec: - script: content: | ../nodewright-cli reset drain-config-disable-eviction --confirm 2>/dev/null || true - kubectl -n skyhook delete nodewright drain-config-disable-eviction --ignore-not-found --wait=false - kubectl -n skyhook delete deployment drain-config-pdb --ignore-not-found --wait=false - kubectl -n skyhook delete pdb drain-config-pdb --ignore-not-found - kubectl -n skyhook delete configmap drain-config-original-pod --ignore-not-found - kubectl -n skyhook delete pod -l app=drain-config-pdb --ignore-not-found --wait=false + kubectl -n nodewright delete nodewright drain-config-disable-eviction --ignore-not-found --wait=false + kubectl -n nodewright delete deployment drain-config-pdb --ignore-not-found --wait=false + kubectl -n nodewright delete pdb drain-config-pdb --ignore-not-found + kubectl -n nodewright delete configmap drain-config-original-pod --ignore-not-found + kubectl -n nodewright delete pod -l app=drain-config-pdb --ignore-not-found --wait=false - apply: file: disable-eviction.yaml - script: content: | - kubectl -n skyhook rollout status deployment/drain-config-pdb --timeout=60s - pod="$(kubectl -n skyhook get pod -l app=drain-config-pdb -o jsonpath='{.items[0].metadata.name}')" - kubectl -n skyhook wait --for=condition=Ready "pod/${pod}" --timeout=30s - kubectl -n skyhook create configmap drain-config-original-pod --from-literal=name="${pod}" --dry-run=client -o yaml | kubectl apply -f - - kubectl -n skyhook wait --for=jsonpath='{.status.disruptionsAllowed}'=0 pdb/drain-config-pdb --timeout=60s + kubectl -n nodewright rollout status deployment/drain-config-pdb --timeout=60s + pod="$(kubectl -n nodewright get pod -l app=drain-config-pdb -o jsonpath='{.items[0].metadata.name}')" + kubectl -n nodewright wait --for=condition=Ready "pod/${pod}" --timeout=30s + kubectl -n nodewright create configmap drain-config-original-pod --from-literal=name="${pod}" --dry-run=client -o yaml | kubectl apply -f - + kubectl -n nodewright wait --for=jsonpath='{.status.disruptionsAllowed}'=0 pdb/drain-config-pdb --timeout=60s - apply: file: disable-eviction-nodewright.yaml - script: content: | - kubectl -n skyhook wait --for=condition=Ready nodewright/drain-config-disable-eviction --timeout=180s + kubectl -n nodewright wait --for=condition=Ready nodewright/drain-config-disable-eviction --timeout=180s - script: content: | - pod="$(kubectl -n skyhook get configmap drain-config-original-pod -o jsonpath='{.data.name}')" - if kubectl -n skyhook get pod "${pod}" >/dev/null 2>&1; then + pod="$(kubectl -n nodewright get configmap drain-config-original-pod -o jsonpath='{.data.name}')" + if kubectl -n nodewright get pod "${pod}" >/dev/null 2>&1; then echo "expected original PDB-protected pod ${pod} to be deleted directly" exit 1 fi @@ -86,11 +86,11 @@ spec: - script: content: | ../nodewright-cli reset drain-config-disable-eviction --confirm 2>/dev/null || true - kubectl -n skyhook delete nodewright drain-config-disable-eviction --ignore-not-found --wait=false - kubectl -n skyhook delete deployment drain-config-pdb --ignore-not-found --wait=false - kubectl -n skyhook delete pdb drain-config-pdb --ignore-not-found - kubectl -n skyhook delete configmap drain-config-original-pod --ignore-not-found - kubectl -n skyhook delete pod -l app=drain-config-pdb --ignore-not-found --wait=false + kubectl -n nodewright delete nodewright drain-config-disable-eviction --ignore-not-found --wait=false + kubectl -n nodewright delete deployment drain-config-pdb --ignore-not-found --wait=false + kubectl -n nodewright delete pdb drain-config-pdb --ignore-not-found + kubectl -n nodewright delete configmap drain-config-original-pod --ignore-not-found + kubectl -n nodewright delete pod -l app=drain-config-pdb --ignore-not-found --wait=false kubectl get nodes -l nodewright.nvidia.com/test-node=skyhooke2e -o name | while read -r node; do kubectl uncordon "${node}" || true; done - name: timeout-surfaces-erroring description: Verify timeout marks the node erroring and emits a drain event when drain cannot proceed @@ -98,15 +98,15 @@ spec: - script: content: | ../nodewright-cli reset drain-config-timeout --confirm 2>/dev/null || true - kubectl -n skyhook delete nodewright drain-config-timeout --ignore-not-found --wait=false - kubectl -n skyhook delete pod drain-config-blocker --ignore-not-found --wait=false + kubectl -n nodewright delete nodewright drain-config-timeout --ignore-not-found --wait=false + kubectl -n nodewright delete pod drain-config-blocker --ignore-not-found --wait=false - apply: file: timeout.yaml - wait: apiVersion: v1 kind: Pod name: drain-config-blocker - namespace: skyhook + namespace: nodewright timeout: 30s for: condition: @@ -114,7 +114,7 @@ spec: value: 'true' - script: content: | - kubectl -n skyhook wait --for=jsonpath='{.status.status}'=erroring nodewright/drain-config-timeout --timeout=180s + kubectl -n nodewright wait --for=jsonpath='{.status.status}'=erroring nodewright/drain-config-timeout --timeout=180s - assert: file: timeout-assert.yaml - script: @@ -133,6 +133,6 @@ spec: - script: content: | ../nodewright-cli reset drain-config-timeout --confirm 2>/dev/null || true - kubectl -n skyhook delete nodewright drain-config-timeout --ignore-not-found --wait=false - kubectl -n skyhook delete pod drain-config-blocker --ignore-not-found --wait=false + kubectl -n nodewright delete nodewright drain-config-timeout --ignore-not-found --wait=false + kubectl -n nodewright delete pod drain-config-blocker --ignore-not-found --wait=false kubectl get nodes -l nodewright.nvidia.com/test-node=skyhooke2e -o name | while read -r node; do kubectl uncordon "${node}" || true; done diff --git a/k8s-tests/chainsaw/nodewright/drain-config/disable-eviction-nodewright.yaml b/k8s-tests/chainsaw/nodewright/drain-config/disable-eviction-nodewright.yaml index 247410c7f..9919eebb6 100644 --- a/k8s-tests/chainsaw/nodewright/drain-config/disable-eviction-nodewright.yaml +++ b/k8s-tests/chainsaw/nodewright/drain-config/disable-eviction-nodewright.yaml @@ -18,7 +18,7 @@ apiVersion: nodewright.nvidia.com/v1alpha1 kind: NodeWright metadata: name: drain-config-disable-eviction - namespace: skyhook + namespace: nodewright spec: drainConfig: disableEviction: true diff --git a/k8s-tests/chainsaw/nodewright/drain-config/disable-eviction.yaml b/k8s-tests/chainsaw/nodewright/drain-config/disable-eviction.yaml index d464284a7..e8315e24d 100644 --- a/k8s-tests/chainsaw/nodewright/drain-config/disable-eviction.yaml +++ b/k8s-tests/chainsaw/nodewright/drain-config/disable-eviction.yaml @@ -19,7 +19,7 @@ apiVersion: apps/v1 kind: Deployment metadata: name: drain-config-pdb - namespace: skyhook + namespace: nodewright spec: replicas: 1 selector: @@ -43,7 +43,7 @@ apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: drain-config-pdb - namespace: skyhook + namespace: nodewright spec: minAvailable: 1 selector: diff --git a/k8s-tests/chainsaw/nodewright/drain-config/timeout.yaml b/k8s-tests/chainsaw/nodewright/drain-config/timeout.yaml index c946d0f0b..797c4d28d 100644 --- a/k8s-tests/chainsaw/nodewright/drain-config/timeout.yaml +++ b/k8s-tests/chainsaw/nodewright/drain-config/timeout.yaml @@ -19,7 +19,7 @@ apiVersion: v1 kind: Pod metadata: name: drain-config-blocker - namespace: skyhook + namespace: nodewright labels: app: drain-config-blocker spec: @@ -37,7 +37,7 @@ apiVersion: nodewright.nvidia.com/v1alpha1 kind: NodeWright metadata: name: drain-config-timeout - namespace: skyhook + namespace: nodewright spec: drainConfig: force: false diff --git a/k8s-tests/chainsaw/nodewright/explicit-uninstall/chainsaw-test.yaml b/k8s-tests/chainsaw/nodewright/explicit-uninstall/chainsaw-test.yaml index b30b0caf9..c5e8221e0 100644 --- a/k8s-tests/chainsaw/nodewright/explicit-uninstall/chainsaw-test.yaml +++ b/k8s-tests/chainsaw/nodewright/explicit-uninstall/chainsaw-test.yaml @@ -85,7 +85,7 @@ spec: kind: Pod apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: explicit-uninstall nodewright.nvidia.com/package: mypkg-2.1.4 @@ -148,7 +148,7 @@ spec: kind: Pod apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: explicit-uninstall nodewright.nvidia.com/interrupt: "True" diff --git a/k8s-tests/chainsaw/nodewright/failure-nodewright/node-assert.yaml b/k8s-tests/chainsaw/nodewright/failure-nodewright/node-assert.yaml index aee70e776..50b8b9862 100644 --- a/k8s-tests/chainsaw/nodewright/failure-nodewright/node-assert.yaml +++ b/k8s-tests/chainsaw/nodewright/failure-nodewright/node-assert.yaml @@ -63,7 +63,7 @@ status: # kind: ConfigMap # apiVersion: v1 # metadata: -# namespace: skyhook +# namespace: nodewright # labels: # nodewright.nvidia.com/skyhook-node-meta: failure-skyhook # ownerReferences: diff --git a/k8s-tests/chainsaw/nodewright/interrupt-grouping/chainsaw-test.yaml b/k8s-tests/chainsaw/nodewright/interrupt-grouping/chainsaw-test.yaml index 181f02415..eb3f3d457 100644 --- a/k8s-tests/chainsaw/nodewright/interrupt-grouping/chainsaw-test.yaml +++ b/k8s-tests/chainsaw/nodewright/interrupt-grouping/chainsaw-test.yaml @@ -75,7 +75,7 @@ spec: kind: Pod apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: interrupt-grouping nodewright.nvidia.com/package: dax-1.2.3 @@ -110,7 +110,7 @@ spec: kind: Pod apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: interrupt-grouping nodewright.nvidia.com/package: dax-1.2.3 @@ -142,7 +142,7 @@ spec: kind: Pod apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: interrupt-grouping nodewright.nvidia.com/package: dax-1.2.3 @@ -183,7 +183,7 @@ spec: kind: Pod apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: interrupt-grouping nodewright.nvidia.com/package: dax-1.2.3 @@ -268,7 +268,7 @@ spec: kind: ConfigMap apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/skyhook-node-meta: interrupt-grouping ownerReferences: diff --git a/k8s-tests/chainsaw/nodewright/interrupt/assert-cm-b.yaml b/k8s-tests/chainsaw/nodewright/interrupt/assert-cm-b.yaml index 1f520cfd9..b16f5ecaa 100644 --- a/k8s-tests/chainsaw/nodewright/interrupt/assert-cm-b.yaml +++ b/k8s-tests/chainsaw/nodewright/interrupt/assert-cm-b.yaml @@ -20,7 +20,7 @@ kind: ConfigMap apiVersion: v1 metadata: name: interrupt-dexter-1.2.3 - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: interrupt ownerReferences: @@ -44,7 +44,7 @@ data: kind: ConfigMap apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/skyhook-node-meta: interrupt ownerReferences: diff --git a/k8s-tests/chainsaw/nodewright/interrupt/chainsaw-test.yaml b/k8s-tests/chainsaw/nodewright/interrupt/chainsaw-test.yaml index b50a6f6cd..4adc900ee 100644 --- a/k8s-tests/chainsaw/nodewright/interrupt/chainsaw-test.yaml +++ b/k8s-tests/chainsaw/nodewright/interrupt/chainsaw-test.yaml @@ -73,7 +73,7 @@ spec: kind: Pod apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: interrupt nodewright.nvidia.com/package: jason-1.3.2 @@ -200,7 +200,7 @@ spec: kind: Pod apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: interrupt nodewright.nvidia.com/package: dexter-1.2.3 diff --git a/k8s-tests/chainsaw/nodewright/interrupt/pod.yaml b/k8s-tests/chainsaw/nodewright/interrupt/pod.yaml index 04320ec8d..2c8fd2858 100644 --- a/k8s-tests/chainsaw/nodewright/interrupt/pod.yaml +++ b/k8s-tests/chainsaw/nodewright/interrupt/pod.yaml @@ -52,7 +52,7 @@ apiVersion: v1 kind: Pod metadata: name: invalid-package - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/package: invalid-1.2.3 nodewright.nvidia.com/name: interrupt diff --git a/k8s-tests/chainsaw/nodewright/package-upgrade/assert-cm-update.yaml b/k8s-tests/chainsaw/nodewright/package-upgrade/assert-cm-update.yaml index f5c39288e..82ad96a0a 100644 --- a/k8s-tests/chainsaw/nodewright/package-upgrade/assert-cm-update.yaml +++ b/k8s-tests/chainsaw/nodewright/package-upgrade/assert-cm-update.yaml @@ -20,7 +20,7 @@ kind: ConfigMap apiVersion: v1 metadata: name: package-upgrade-nullptr-2.0.1 - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: package-upgrade ownerReferences: diff --git a/k8s-tests/chainsaw/nodewright/package-upgrade/assert-install.yaml b/k8s-tests/chainsaw/nodewright/package-upgrade/assert-install.yaml index 0bb803cb0..6f3464296 100644 --- a/k8s-tests/chainsaw/nodewright/package-upgrade/assert-install.yaml +++ b/k8s-tests/chainsaw/nodewright/package-upgrade/assert-install.yaml @@ -96,7 +96,7 @@ kind: ConfigMap apiVersion: v1 metadata: name: package-upgrade-nullptr-2.0.0 - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: package-upgrade ownerReferences: diff --git a/k8s-tests/chainsaw/nodewright/package-upgrade/chainsaw-test.yaml b/k8s-tests/chainsaw/nodewright/package-upgrade/chainsaw-test.yaml index 7acbea14a..49db1b26b 100644 --- a/k8s-tests/chainsaw/nodewright/package-upgrade/chainsaw-test.yaml +++ b/k8s-tests/chainsaw/nodewright/package-upgrade/chainsaw-test.yaml @@ -99,7 +99,7 @@ spec: kind: Pod apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: package-upgrade nodewright.nvidia.com/package: nullptr-2.0.1 diff --git a/k8s-tests/chainsaw/nodewright/runtime-required/chainsaw-test.yaml b/k8s-tests/chainsaw/nodewright/runtime-required/chainsaw-test.yaml index 62de28828..f65809e38 100644 --- a/k8s-tests/chainsaw/nodewright/runtime-required/chainsaw-test.yaml +++ b/k8s-tests/chainsaw/nodewright/runtime-required/chainsaw-test.yaml @@ -87,7 +87,7 @@ spec: apiVersion: v1 kind: Pod metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: runtime-required nodewright.nvidia.com/package: spencer-3.2.3 @@ -101,7 +101,7 @@ spec: apiVersion: v1 kind: Pod metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: runtime-required nodewright.nvidia.com/package: spencer-3.2.3 @@ -160,7 +160,7 @@ spec: apiVersion: v1 kind: Pod metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: runtime-required nodewright.nvidia.com/package: spencer-3.2.3 @@ -174,7 +174,7 @@ spec: apiVersion: v1 kind: Pod metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: runtime-required nodewright.nvidia.com/package: spencer-3.2.3 diff --git a/k8s-tests/chainsaw/nodewright/simple-nodewright/assert.yaml b/k8s-tests/chainsaw/nodewright/simple-nodewright/assert.yaml index 5477bcc71..05a7e197d 100644 --- a/k8s-tests/chainsaw/nodewright/simple-nodewright/assert.yaml +++ b/k8s-tests/chainsaw/nodewright/simple-nodewright/assert.yaml @@ -95,7 +95,7 @@ kind: ConfigMap apiVersion: v1 metadata: name: simple-skyhook-dexter-1.2.3 - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: simple-skyhook ownerReferences: @@ -119,7 +119,7 @@ data: kind: ConfigMap apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/skyhook-node-meta: simple-skyhook ownerReferences: diff --git a/k8s-tests/chainsaw/nodewright/simple-nodewright/assert_pods.yaml b/k8s-tests/chainsaw/nodewright/simple-nodewright/assert_pods.yaml index 4ab1496b7..48993d032 100644 --- a/k8s-tests/chainsaw/nodewright/simple-nodewright/assert_pods.yaml +++ b/k8s-tests/chainsaw/nodewright/simple-nodewright/assert_pods.yaml @@ -18,7 +18,7 @@ kind: Pod apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: simple-skyhook nodewright.nvidia.com/package: spencer-3.2.3 @@ -73,7 +73,7 @@ spec: kind: Pod apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: simple-skyhook nodewright.nvidia.com/package: foobar-1.2 diff --git a/k8s-tests/chainsaw/nodewright/simple-nodewright/chainsaw-test.yaml b/k8s-tests/chainsaw/nodewright/simple-nodewright/chainsaw-test.yaml index b4c840c6a..24a60c737 100644 --- a/k8s-tests/chainsaw/nodewright/simple-nodewright/chainsaw-test.yaml +++ b/k8s-tests/chainsaw/nodewright/simple-nodewright/chainsaw-test.yaml @@ -40,7 +40,7 @@ spec: - get: apiVersion: v1 kind: Pod - namespace: skyhook + namespace: nodewright selector: nodewright.nvidia.com/name=simple-skyhook format: yaml steps: diff --git a/k8s-tests/chainsaw/nodewright/simple-nodewright/limitrange.yaml b/k8s-tests/chainsaw/nodewright/simple-nodewright/limitrange.yaml index 4aa1c4473..c06db3b41 100644 --- a/k8s-tests/chainsaw/nodewright/simple-nodewright/limitrange.yaml +++ b/k8s-tests/chainsaw/nodewright/simple-nodewright/limitrange.yaml @@ -18,7 +18,7 @@ apiVersion: v1 kind: LimitRange metadata: name: skyhook-default-limits - namespace: skyhook + namespace: nodewright spec: limits: - type: Container diff --git a/k8s-tests/chainsaw/nodewright/simple-update-nodewright/assert-update.yaml b/k8s-tests/chainsaw/nodewright/simple-update-nodewright/assert-update.yaml index 08fcc63bd..dd011cc54 100644 --- a/k8s-tests/chainsaw/nodewright/simple-update-nodewright/assert-update.yaml +++ b/k8s-tests/chainsaw/nodewright/simple-update-nodewright/assert-update.yaml @@ -19,7 +19,7 @@ kind: ConfigMap apiVersion: v1 metadata: name: simple-update-skyhook-baxter-2.3.1-test - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: simple-update-skyhook ownerReferences: @@ -141,7 +141,7 @@ status: kind: ConfigMap apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/skyhook-node-meta: simple-update-skyhook ownerReferences: diff --git a/k8s-tests/chainsaw/nodewright/simple-update-nodewright/assert.yaml b/k8s-tests/chainsaw/nodewright/simple-update-nodewright/assert.yaml index 97c2d4708..1d842be94 100644 --- a/k8s-tests/chainsaw/nodewright/simple-update-nodewright/assert.yaml +++ b/k8s-tests/chainsaw/nodewright/simple-update-nodewright/assert.yaml @@ -95,7 +95,7 @@ kind: ConfigMap apiVersion: v1 metadata: name: simple-update-skyhook-dexter-1.2.3 - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: simple-update-skyhook ownerReferences: @@ -119,7 +119,7 @@ data: kind: ConfigMap apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/skyhook-node-meta: simple-update-skyhook ownerReferences: diff --git a/k8s-tests/chainsaw/nodewright/strict-order/chainsaw-test.yaml b/k8s-tests/chainsaw/nodewright/strict-order/chainsaw-test.yaml index c1e3cc8c8..1bef22ce9 100644 --- a/k8s-tests/chainsaw/nodewright/strict-order/chainsaw-test.yaml +++ b/k8s-tests/chainsaw/nodewright/strict-order/chainsaw-test.yaml @@ -95,7 +95,7 @@ spec: apiVersion: v1 kind: Pod metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: strict-order-skyhook-zzz nodewright.nvidia.com/package: foobar-1.2 @@ -155,7 +155,7 @@ spec: apiVersion: v1 kind: Pod metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: strict-order-skyhook-zzz nodewright.nvidia.com/package: foobar-1.2 diff --git a/k8s-tests/chainsaw/nodewright/uninstall-mixed-packages/chainsaw-test.yaml b/k8s-tests/chainsaw/nodewright/uninstall-mixed-packages/chainsaw-test.yaml index 50b71988d..dfe2f159a 100644 --- a/k8s-tests/chainsaw/nodewright/uninstall-mixed-packages/chainsaw-test.yaml +++ b/k8s-tests/chainsaw/nodewright/uninstall-mixed-packages/chainsaw-test.yaml @@ -66,7 +66,7 @@ spec: kind: Pod apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: uninstall-mixed-packages nodewright.nvidia.com/package: pkg-remove-2.1.4 diff --git a/k8s-tests/chainsaw/nodewright/uninstall-on-delete/chainsaw-test.yaml b/k8s-tests/chainsaw/nodewright/uninstall-on-delete/chainsaw-test.yaml index b5eb8b05a..7927b647b 100644 --- a/k8s-tests/chainsaw/nodewright/uninstall-on-delete/chainsaw-test.yaml +++ b/k8s-tests/chainsaw/nodewright/uninstall-on-delete/chainsaw-test.yaml @@ -69,7 +69,7 @@ spec: kind: Pod apiVersion: v1 metadata: - namespace: skyhook + namespace: nodewright labels: nodewright.nvidia.com/name: uninstall-on-delete nodewright.nvidia.com/package: enabled-pkg-2.1.4 diff --git a/k8s-tests/migration/lib.sh b/k8s-tests/migration/lib.sh index 132dfdbb8..624c721a5 100644 --- a/k8s-tests/migration/lib.sh +++ b/k8s-tests/migration/lib.sh @@ -19,6 +19,10 @@ # Shared helpers for the Skyhook -> NodeWright upgrade migration test. # Sourced by run.sh; not executable on its own. +# Deliberately still "skyhook", not the current default "nodewright": this test installs +# a pre-rename release and upgrades it in place, and Helm cannot move a release between +# namespaces. Keeping it here is the coverage that an install predating the namespace +# rename keeps upgrading cleanly. NAMESPACE="${NAMESPACE:-skyhook}" RELEASE="${RELEASE:-nodewright-operator}" TEST_NAME="${TEST_NAME:-migration-upgrade-test}" diff --git a/operator/Makefile b/operator/Makefile index edb546518..ffd663342 100644 --- a/operator/Makefile +++ b/operator/Makefile @@ -31,7 +31,7 @@ LOCAL_REGISTRY ?= localhost:5005 LOCAL_OPERATOR_IMG ?= $(LOCAL_REGISTRY)/skyhook-operator:testing PLATFORM := $(shell uname -s 2>/dev/null || echo unknown) -SKYHOOK_NAMESPACE ?= skyhook +SKYHOOK_NAMESPACE ?= nodewright METRICS_TEST_SERVICE_ACCOUNT ?= metrics-reader # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) @@ -402,8 +402,8 @@ else DOCKER_AUTH_FILE=${HOME}/.config/containers/auth.json endif -setup-kind-cluster: ## setup kind cluster with local docker creds and skyhook namespace - ## sets you local $(DOCKER_CMD) creds into a secret in kind in the skyhook namespace +setup-kind-cluster: ## setup kind cluster with local docker creds and nodewright namespace + ## sets you local $(DOCKER_CMD) creds into a secret in kind in the nodewright namespace ## Dual-labelled during the NodeWright rename: the skyhook and deployment-policy ## pools select nodewright.nvidia.com/test-node; the not-yet-migrated cli pool still ## selects skyhook.nvidia.com/test-node. Drop the skyhook label once the cli pool moves. diff --git a/operator/README.md b/operator/README.md index 94d503d10..1d95b7a17 100644 --- a/operator/README.md +++ b/operator/README.md @@ -211,18 +211,18 @@ Operator containers: If you want to test the helm chart, this is how you can deploy it from the repo. ``` -## setup namespace "skyhook" -kubectl create namespace skyhook --dry-run=client -o yaml | kubectl apply -f - -kubectl create secret generic node-init-secret --from-file=.dockerconfigjson=${HOME}/.config/containers/auth.json --type=kubernetes.io/dockerconfigjson -n skyhook +## setup namespace "nodewright" +kubectl create namespace nodewright --dry-run=client -o yaml | kubectl apply -f - +kubectl create secret generic node-init-secret --from-file=.dockerconfigjson=${HOME}/.config/containers/auth.json --type=kubernetes.io/dockerconfigjson -n nodewright ## install operator -helm install skyhook-operator ./chart --namespace skyhook +helm install skyhook-operator ./chart --namespace nodewright ``` to remove operator from a cluster: ``` ## remove operator (automatic cleanup enabled by default) -helm uninstall skyhook-operator --namespace skyhook +helm uninstall skyhook-operator --namespace nodewright ## delete CRD make uninstall diff --git a/operator/RELEASE_NOTES.md b/operator/RELEASE_NOTES.md index 4ba01ee85..155b25e6f 100644 --- a/operator/RELEASE_NOTES.md +++ b/operator/RELEASE_NOTES.md @@ -5,6 +5,25 @@ For the full commit-level log see CHANGELOG.md. ## Unreleased +### Other Changes + +- **The documented install namespace for new deployments is now `nodewright`, not + `skyhook`.** The kustomize overlay moved from `skyhook-operator-system` to + `nodewright-operator-system`, and the operator's `NAMESPACE` env default (used only + when nothing sets it, such as a bare binary or `make run`) moved from `skyhook` to + `nodewright`. + + **Existing installs need no action, and there is no deadline.** Namespaces cannot be + renamed in place and Helm cannot move a release between namespaces, so an install in + `skyhook` stays supported indefinitely. The chart sources the namespace from + `.Release.Namespace` throughout and installs into any namespace, so `helm upgrade` + against a `skyhook`-namespace release is unaffected. The chart always sets `NAMESPACE` + explicitly, so the default change is invisible to chart users. + + `kubectl nodewright` discovers the operator's namespace rather than assuming one, so + it keeps working against a `skyhook`-namespace install. See + [docs/nodewright-migration.md](../docs/nodewright-migration.md#install-namespace-skyhook---nodewright). + ### Breaking Changes - **The primary CRD is renamed from `Skyhook` (`skyhook.nvidia.com/v1alpha1`) to diff --git a/operator/api/v1alpha1/zz_generated.deepcopy.go b/operator/api/v1alpha1/zz_generated.deepcopy.go index 63b3296af..a4ab355be 100644 --- a/operator/api/v1alpha1/zz_generated.deepcopy.go +++ b/operator/api/v1alpha1/zz_generated.deepcopy.go @@ -1,23 +1,5 @@ //go:build !ignore_autogenerated -/* - * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: Apache-2.0 - * - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - // Code generated by controller-gen. DO NOT EDIT. package v1alpha1 diff --git a/operator/cmd/cli/RELEASE_NOTES.md b/operator/cmd/cli/RELEASE_NOTES.md index ba60d4102..ed4e3a177 100644 --- a/operator/cmd/cli/RELEASE_NOTES.md +++ b/operator/cmd/cli/RELEASE_NOTES.md @@ -19,6 +19,31 @@ For the full commit-level log see CHANGELOG.md. ### Changed +- **The `--namespace` default moved from `skyhook` to `nodewright`, and the CLI now + discovers the operator's namespace instead of assuming it.** The documented install + namespace moved with the rename, but a namespace cannot be renamed in place, so + installs that predate the rename legitimately stay in `skyhook` forever. A blind + default change would have answered "not found" for every one of them. + + With no `--namespace`, the CLI now checks `nodewright`, then `skyhook` (printing a + one-line note to stderr when the legacy namespace is what answered), then sweeps + cluster-wide for an operator in some other namespace, and only then falls back to + `nodewright` so the command's own lookup reports the specific miss. An explicit + `--namespace` is always used verbatim, with no discovery and no note. + + Within the set of operators this CLI supports at all (NodeWright-capable ones, per + the Breaking Changes above), the namespace change introduces **no** new + incompatibility: the namespace is only used to locate the operator Deployment and + package pods, and the `NodeWright` and `DeploymentPolicy` CRDs are cluster-scoped, + so no command changes which CRs it sees. This says nothing about Skyhook-only + operators, which remain unsupported for unrelated reasons. See + [docs/cli.md](../../../docs/cli.md#namespace-resolution) for the full resolution + order and the situation matrix. + + The cluster-wide sweep needs cluster-scoped Deployment list permission. Users + without it lose only that last discovery step; the `nodewright`/`skyhook` probes + and explicit `--namespace` are unaffected. + - Commands that read or write `NodeWright` resources now run a preflight check on the served API groups. When the cluster serves only the legacy `skyhook.nvidia.com` group and not `nodewright.nvidia.com`, they fail fast with diff --git a/operator/cmd/cli/app/cli_test.go b/operator/cmd/cli/app/cli_test.go index fad6979b8..1da65c2ef 100644 --- a/operator/cmd/cli/app/cli_test.go +++ b/operator/cmd/cli/app/cli_test.go @@ -246,9 +246,14 @@ var _ = Describe("NodeWright CLI Tests", func() { }) }) - Describe("defaultNamespace constant", func() { - It("should be set to skyhook", func() { - Expect(context.DefaultNamespace).To(Equal("skyhook")) + Describe("default namespace", func() { + It("should be nodewright, with skyhook kept as the legacy fallback", func() { + Expect(utils.DefaultNamespace).To(Equal("nodewright")) + Expect(utils.LegacyDefaultNamespace).To(Equal("skyhook")) + }) + + It("should seed the --namespace flag default", func() { + Expect(context.NewGlobalFlags().Namespace()).To(Equal(utils.DefaultNamespace)) }) }) }) diff --git a/operator/cmd/cli/app/lifecycle.go b/operator/cmd/cli/app/lifecycle.go index fda5566d6..0a6bb628f 100644 --- a/operator/cmd/cli/app/lifecycle.go +++ b/operator/cmd/cli/app/lifecycle.go @@ -115,7 +115,7 @@ func newLifecycleCmd(ctx *cliContext.CLIContext, cfg lifecycleConfig) *cobra.Com opVersion := utils.GetSkyhookVersion(skyhook) if opVersion == "" || !utils.IsValidVersion(opVersion) { // Try to get version from deployment instead - deployVersion, err := utils.DiscoverOperatorVersion(cmd.Context(), kubeClient.Kubernetes(), ctx.GlobalFlags.Namespace()) + deployVersion, err := utils.DiscoverOperatorVersion(cmd.Context(), kubeClient.Kubernetes(), ctx.ResolveNamespace(cmd.Context(), cmd, kubeClient.Kubernetes())) if err == nil && utils.IsValidVersion(deployVersion) { opVersion = deployVersion } else { diff --git a/operator/cmd/cli/app/package/package_logs.go b/operator/cmd/cli/app/package/package_logs.go index 071ba6e23..7ce107123 100644 --- a/operator/cmd/cli/app/package/package_logs.go +++ b/operator/cmd/cli/app/package/package_logs.go @@ -106,7 +106,7 @@ By default, it shows logs from the most relevant stage container.`, return err } - namespace := ctx.GlobalFlags.Namespace() + namespace := ctx.ResolveNamespace(cmd.Context(), cmd, kubeClient.Kubernetes()) return runLogs(cmd.Context(), cmd.OutOrStdout(), kubeClient, opts, namespace) }, } diff --git a/operator/cmd/cli/app/package/package_logs_test.go b/operator/cmd/cli/app/package/package_logs_test.go index 22e10654f..12c7a7438 100644 --- a/operator/cmd/cli/app/package/package_logs_test.go +++ b/operator/cmd/cli/app/package/package_logs_test.go @@ -34,7 +34,10 @@ import ( "github.com/NVIDIA/nodewright/operator/internal/cli/context" ) -const testSkyhookNameLogs = "my-skyhook" +const ( + testSkyhookNameLogs = "my-skyhook" + testNamespace = "nodewright" +) var _ = Describe("Package Logs Command", func() { Describe("getContainerStatus", func() { @@ -282,7 +285,7 @@ var _ = Describe("Package Logs Command", func() { packageName: "pkg1", } - err := runLogs(gocontext.Background(), output, kubeClient, opts, "skyhook") + err := runLogs(gocontext.Background(), output, kubeClient, opts, testNamespace) Expect(err).NotTo(HaveOccurred()) Expect(output.String()).To(ContainSubstring("No pods found")) }) @@ -292,7 +295,7 @@ var _ = Describe("Package Logs Command", func() { pod := &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: "other-pod", - Namespace: context.DefaultNamespace, + Namespace: testNamespace, Labels: map[string]string{ v1alpha1.METADATA_PREFIX + "/name": "other-skyhook", v1alpha1.METADATA_PREFIX + "/package": "other-pkg", @@ -302,14 +305,14 @@ var _ = Describe("Package Logs Command", func() { NodeName: "node1", }, } - _, _ = fakeKube.CoreV1().Pods(context.DefaultNamespace).Create(gocontext.Background(), pod, metav1.CreateOptions{}) + _, _ = fakeKube.CoreV1().Pods(testNamespace).Create(gocontext.Background(), pod, metav1.CreateOptions{}) opts := &logsOptions{ skyhookName: testSkyhookNameLogs, packageName: "pkg1", } - err := runLogs(gocontext.Background(), output, kubeClient, opts, "skyhook") + err := runLogs(gocontext.Background(), output, kubeClient, opts, testNamespace) Expect(err).NotTo(HaveOccurred()) Expect(output.String()).To(ContainSubstring("No pods found")) }) @@ -320,7 +323,7 @@ var _ = Describe("Package Logs Command", func() { pod := &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: "pod-" + nodeName, - Namespace: context.DefaultNamespace, + Namespace: testNamespace, Labels: map[string]string{ v1alpha1.METADATA_PREFIX + "/name": testSkyhookNameLogs, v1alpha1.METADATA_PREFIX + "/package": "pkg1-1.0.0", @@ -344,7 +347,7 @@ var _ = Describe("Package Logs Command", func() { }, }, } - _, _ = fakeKube.CoreV1().Pods(context.DefaultNamespace).Create(gocontext.Background(), pod, metav1.CreateOptions{}) + _, _ = fakeKube.CoreV1().Pods(testNamespace).Create(gocontext.Background(), pod, metav1.CreateOptions{}) } opts := &logsOptions{ @@ -353,7 +356,7 @@ var _ = Describe("Package Logs Command", func() { node: "node1", } - err := runLogs(gocontext.Background(), output, kubeClient, opts, "skyhook") + err := runLogs(gocontext.Background(), output, kubeClient, opts, testNamespace) Expect(err).NotTo(HaveOccurred()) // Should only show pod on node1 Expect(output.String()).To(ContainSubstring("pod-node1")) @@ -364,7 +367,7 @@ var _ = Describe("Package Logs Command", func() { pod := &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: "test-pod", - Namespace: context.DefaultNamespace, + Namespace: testNamespace, Labels: map[string]string{ v1alpha1.METADATA_PREFIX + "/name": testSkyhookNameLogs, v1alpha1.METADATA_PREFIX + "/package": "pkg1-1.0.0", @@ -388,14 +391,14 @@ var _ = Describe("Package Logs Command", func() { }, }, } - _, _ = fakeKube.CoreV1().Pods(context.DefaultNamespace).Create(gocontext.Background(), pod, metav1.CreateOptions{}) + _, _ = fakeKube.CoreV1().Pods(testNamespace).Create(gocontext.Background(), pod, metav1.CreateOptions{}) opts := &logsOptions{ skyhookName: testSkyhookNameLogs, packageName: "pkg1", } - err := runLogs(gocontext.Background(), output, kubeClient, opts, "skyhook") + err := runLogs(gocontext.Background(), output, kubeClient, opts, testNamespace) Expect(err).NotTo(HaveOccurred()) Expect(output.String()).To(ContainSubstring("test-pod")) }) @@ -404,7 +407,7 @@ var _ = Describe("Package Logs Command", func() { pod := &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: "test-pod", - Namespace: context.DefaultNamespace, + Namespace: testNamespace, Labels: map[string]string{ v1alpha1.METADATA_PREFIX + "/name": testSkyhookNameLogs, v1alpha1.METADATA_PREFIX + "/package": "other-pkg-1.0.0", @@ -414,14 +417,14 @@ var _ = Describe("Package Logs Command", func() { NodeName: "node1", }, } - _, _ = fakeKube.CoreV1().Pods(context.DefaultNamespace).Create(gocontext.Background(), pod, metav1.CreateOptions{}) + _, _ = fakeKube.CoreV1().Pods(testNamespace).Create(gocontext.Background(), pod, metav1.CreateOptions{}) opts := &logsOptions{ skyhookName: testSkyhookNameLogs, packageName: "pkg1", } - err := runLogs(gocontext.Background(), output, kubeClient, opts, "skyhook") + err := runLogs(gocontext.Background(), output, kubeClient, opts, testNamespace) Expect(err).NotTo(HaveOccurred()) Expect(output.String()).To(ContainSubstring("No pods matched")) }) @@ -532,9 +535,9 @@ var _ = Describe("Package Logs Command", func() { }) }) - Describe("skyhookNamespace constant", func() { - It("should be set to skyhook", func() { - Expect(context.DefaultNamespace).To(Equal("skyhook")) + Describe("default namespace", func() { + It("should be nodewright", func() { + Expect(context.NewGlobalFlags().Namespace()).To(Equal("nodewright")) }) }) }) diff --git a/operator/cmd/cli/app/reset.go b/operator/cmd/cli/app/reset.go index b21e11fc0..56b28c31a 100644 --- a/operator/cmd/cli/app/reset.go +++ b/operator/cmd/cli/app/reset.go @@ -366,7 +366,7 @@ func runPackageReset( if err != nil { return fmt.Errorf("fetching NodeWright %q: %w", skyhookName, err) } - if err := utils.CheckNodeStateOperatorVersion(ctx, cmd, kubeClient.Kubernetes(), cliCtx.GlobalFlags.Namespace(), skyhook); err != nil { + if err := utils.CheckNodeStateOperatorVersion(ctx, cmd, kubeClient.Kubernetes(), cliCtx.ResolveNamespace(ctx, cmd, kubeClient.Kubernetes()), skyhook); err != nil { return err } diff --git a/operator/cmd/cli/app/update_state.go b/operator/cmd/cli/app/update_state.go index f9c6d043f..fcf079cbb 100644 --- a/operator/cmd/cli/app/update_state.go +++ b/operator/cmd/cli/app/update_state.go @@ -233,7 +233,7 @@ func runUpdateState(ctx context.Context, cmd *cobra.Command, kubeClient *client. return fmt.Errorf("fetching NodeWright %q: %w", skyhookName, err) } - if err := utils.CheckNodeStateOperatorVersion(ctx, cmd, kubeClient.Kubernetes(), cliCtx.GlobalFlags.Namespace(), skyhook); err != nil { + if err := utils.CheckNodeStateOperatorVersion(ctx, cmd, kubeClient.Kubernetes(), cliCtx.ResolveNamespace(ctx, cmd, kubeClient.Kubernetes()), skyhook); err != nil { return err } diff --git a/operator/cmd/cli/app/version.go b/operator/cmd/cli/app/version.go index 6b4939620..2001d188f 100644 --- a/operator/cmd/cli/app/version.go +++ b/operator/cmd/cli/app/version.go @@ -51,7 +51,7 @@ func NewVersionCmd(ctx *cliContext.CLIContext) *cobra.Command { kubectl nodewright version --client-only # Query operator in a specific namespace - kubectl nodewright version -n skyhook`, + kubectl nodewright version -n nodewright`, RunE: func(cmd *cobra.Command, args []string) error { _, _ = fmt.Fprintf(cmd.OutOrStdout(), "NodeWright plugin:\t%s\n", version.Summary()) @@ -68,7 +68,7 @@ func NewVersionCmd(ctx *cliContext.CLIContext) *cobra.Command { cmdCtx, cancel := context.WithTimeout(cmd.Context(), timeout) defer cancel() - opVersion, err := utils.DiscoverOperatorVersion(cmdCtx, kubeClient.Kubernetes(), ctx.GlobalFlags.Namespace()) + opVersion, err := utils.DiscoverOperatorVersion(cmdCtx, kubeClient.Kubernetes(), ctx.ResolveNamespace(cmdCtx, cmd, kubeClient.Kubernetes())) if err != nil { _, _ = fmt.Fprintf(cmd.OutOrStdout(), "NodeWright operator:\tunknown (%v)\n", err) return nil diff --git a/operator/config/crd/bases/nodewright.nvidia.com_deploymentpolicies.yaml b/operator/config/crd/bases/nodewright.nvidia.com_deploymentpolicies.yaml index 737be8cc0..64165a32a 100644 --- a/operator/config/crd/bases/nodewright.nvidia.com_deploymentpolicies.yaml +++ b/operator/config/crd/bases/nodewright.nvidia.com_deploymentpolicies.yaml @@ -1,7 +1,6 @@ # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 # -# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/operator/config/crd/bases/nodewright.nvidia.com_nodewrights.yaml b/operator/config/crd/bases/nodewright.nvidia.com_nodewrights.yaml index 57c4010a9..0f5a08297 100644 --- a/operator/config/crd/bases/nodewright.nvidia.com_nodewrights.yaml +++ b/operator/config/crd/bases/nodewright.nvidia.com_nodewrights.yaml @@ -1,7 +1,6 @@ # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 # -# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/operator/config/crd/bases/skyhook.nvidia.com_deploymentpolicies.yaml b/operator/config/crd/bases/skyhook.nvidia.com_deploymentpolicies.yaml index b92fd4396..2a27ebf34 100644 --- a/operator/config/crd/bases/skyhook.nvidia.com_deploymentpolicies.yaml +++ b/operator/config/crd/bases/skyhook.nvidia.com_deploymentpolicies.yaml @@ -1,7 +1,6 @@ # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 # -# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/operator/config/crd/bases/skyhook.nvidia.com_skyhooks.yaml b/operator/config/crd/bases/skyhook.nvidia.com_skyhooks.yaml index f7d406853..3fc98f5c2 100644 --- a/operator/config/crd/bases/skyhook.nvidia.com_skyhooks.yaml +++ b/operator/config/crd/bases/skyhook.nvidia.com_skyhooks.yaml @@ -1,7 +1,6 @@ # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 # -# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/operator/config/default/kustomization.yaml b/operator/config/default/kustomization.yaml index 58cc86d8d..7376dbe9e 100644 --- a/operator/config/default/kustomization.yaml +++ b/operator/config/default/kustomization.yaml @@ -15,13 +15,16 @@ # limitations under the License. # Adds namespace to all resources. -namespace: skyhook-operator-system +namespace: nodewright-operator-system # Value of this field is prepended to the # names of all resources, e.g. a deployment named # "wordpress" becomes "alices-wordpress". -# Note that it should also match with the prefix (text before '-') of the namespace -# field above. +# The kubebuilder convention is for this to match the prefix of the namespace field +# above; it deliberately does not right now. Renaming the in-cluster resource names is +# a separate, riskier change than renaming the namespace (see #285: the last one broke +# `helm upgrade` on the immutable Deployment selector), so the namespace moved to +# nodewright first and the resource names still lag. namePrefix: skyhook-operator- # Labels to add to all resources and selectors. diff --git a/operator/config/default/manager_metrics_patch.yaml b/operator/config/default/manager_metrics_patch.yaml index 0b48b947f..d4598c7b0 100644 --- a/operator/config/default/manager_metrics_patch.yaml +++ b/operator/config/default/manager_metrics_patch.yaml @@ -38,4 +38,4 @@ spec: - name: ENABLE_WEBHOOKS value: "true" - name: NAMESPACE - value: skyhook-operator-system + value: nodewright-operator-system diff --git a/operator/config/manager/manager.yaml b/operator/config/manager/manager.yaml index 8a557b42e..e85bd5f6c 100644 --- a/operator/config/manager/manager.yaml +++ b/operator/config/manager/manager.yaml @@ -96,7 +96,7 @@ spec: - name: ENABLE_WEBHOOKS value: "true" - name: NAMESPACE - value: skyhook-operator-system + value: nodewright-operator-system - name: IMAGE_PULL_SECRET value: "" - name: COPY_DIR_ROOT diff --git a/operator/config/rbac/role.yaml b/operator/config/rbac/role.yaml index d389684d3..208388e67 100644 --- a/operator/config/rbac/role.yaml +++ b/operator/config/rbac/role.yaml @@ -1,7 +1,6 @@ # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 # -# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/operator/config/webhook/manifests.yaml b/operator/config/webhook/manifests.yaml index 86389f881..f0ed78013 100644 --- a/operator/config/webhook/manifests.yaml +++ b/operator/config/webhook/manifests.yaml @@ -1,7 +1,6 @@ # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 # -# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at diff --git a/operator/internal/cli/context/context.go b/operator/internal/cli/context/context.go index ad538ee50..c1cf37bb4 100644 --- a/operator/internal/cli/context/context.go +++ b/operator/internal/cli/context/context.go @@ -19,17 +19,23 @@ package context import ( + gocontext "context" "fmt" "io" "os" "strings" + "sync" + "github.com/spf13/cobra" "github.com/spf13/pflag" "k8s.io/cli-runtime/pkg/genericclioptions" + "k8s.io/client-go/kubernetes" + + "github.com/NVIDIA/nodewright/operator/internal/cli/utils" ) -// DefaultNamespace is the default namespace for Skyhook resources -const DefaultNamespace = "skyhook" +// namespaceFlagName is the flag whose explicit use suppresses namespace discovery. +const namespaceFlagName = "namespace" // GlobalFlags holds persistent CLI flags that every command uses (kubeconfig, namespace, output, etc.). type GlobalFlags struct { @@ -46,7 +52,7 @@ func NewGlobalFlags() *GlobalFlags { flags.Namespace = new(string) } if *flags.Namespace == "" { - *flags.Namespace = DefaultNamespace + *flags.Namespace = utils.DefaultNamespace } return &GlobalFlags{ @@ -79,14 +85,16 @@ func (f *GlobalFlags) Validate() error { return nil } -// Namespace returns the namespace selected via kubeconfig or flag (default "skyhook"). +// Namespace returns the namespace selected via the --namespace flag, falling back to +// utils.DefaultNamespace. It does not consult the cluster; prefer +// CLIContext.ResolveNamespace, which also finds installs in the legacy namespace. func (f *GlobalFlags) Namespace() string { if f.ConfigFlags == nil || f.ConfigFlags.Namespace == nil { - return DefaultNamespace + return utils.DefaultNamespace } ns := strings.TrimSpace(*f.ConfigFlags.Namespace) if ns == "" { - return DefaultNamespace + return utils.DefaultNamespace } return ns } @@ -96,6 +104,12 @@ func (f *GlobalFlags) Namespace() string { type CLIContext struct { GlobalFlags *GlobalFlags config *CLIConfig + + // Namespace discovery is one cluster round trip per invocation at most, shared by + // every command that needs it. Guarded because a single command may ask more than + // once (version check, then pod lookup). + namespaceOnce sync.Once + namespace string } // CLIConfig holds the configuration for the CLI execution. @@ -152,3 +166,31 @@ func NewCLIContext(config *CLIConfig) *CLIContext { func (c *CLIContext) Config() *CLIConfig { return c.config } + +// ResolveNamespace returns the namespace the command should operate in. +// +// An explicit --namespace always wins and is never second-guessed. Otherwise the +// namespace is discovered from the cluster, because the install namespace moved +// from "skyhook" to "nodewright" with the rename and a namespace cannot be renamed +// in place: an install that predates the rename is still in "skyhook" and must keep +// working. When the answer comes from the legacy namespace a one-line deprecation +// notice is written to the command's stderr. +// +// The result is cached for the lifetime of the CLIContext. +func (c *CLIContext) ResolveNamespace(ctx gocontext.Context, cmd *cobra.Command, kube kubernetes.Interface) string { + if cmd != nil && cmd.Flags().Changed(namespaceFlagName) { + return c.GlobalFlags.Namespace() + } + + c.namespaceOnce.Do(func() { + namespace, found, legacy := utils.ResolveOperatorNamespace(ctx, kube) + c.namespace = namespace + if found && legacy && cmd != nil { + _, _ = fmt.Fprintf(cmd.ErrOrStderr(), + "Note: using the legacy %q namespace; new installs default to %q. Pass --namespace to silence this.\n", + utils.LegacyDefaultNamespace, utils.DefaultNamespace) + } + }) + + return c.namespace +} diff --git a/operator/internal/cli/context/context_test.go b/operator/internal/cli/context/context_test.go index baa5a2c49..47aef5857 100644 --- a/operator/internal/cli/context/context_test.go +++ b/operator/internal/cli/context/context_test.go @@ -20,11 +20,17 @@ package context import ( "bytes" + gocontext "context" "testing" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "github.com/spf13/cobra" "github.com/spf13/pflag" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes/fake" ) func TestContext(t *testing.T) { @@ -38,7 +44,7 @@ var _ = Describe("CLI Context", func() { It("should initialize with default namespace", func() { flags := NewGlobalFlags() Expect(flags.ConfigFlags.Namespace).NotTo(BeNil()) - Expect(*flags.ConfigFlags.Namespace).To(Equal("skyhook")) + Expect(*flags.ConfigFlags.Namespace).To(Equal("nodewright")) }) It("should initialize with default output format", func() { @@ -120,7 +126,7 @@ var _ = Describe("CLI Context", func() { Describe("Namespace", func() { It("should return default namespace when not set", func() { flags := NewGlobalFlags() - Expect(flags.Namespace()).To(Equal("skyhook")) + Expect(flags.Namespace()).To(Equal("nodewright")) }) It("should return custom namespace when set", func() { @@ -134,20 +140,20 @@ var _ = Describe("CLI Context", func() { flags := NewGlobalFlags() ns := "" flags.ConfigFlags.Namespace = &ns - Expect(flags.Namespace()).To(Equal("skyhook")) + Expect(flags.Namespace()).To(Equal("nodewright")) }) It("should return default namespace for whitespace", func() { flags := NewGlobalFlags() ns := " " flags.ConfigFlags.Namespace = &ns - Expect(flags.Namespace()).To(Equal("skyhook")) + Expect(flags.Namespace()).To(Equal("nodewright")) }) It("should return default namespace when nil", func() { flags := NewGlobalFlags() flags.ConfigFlags.Namespace = nil - Expect(flags.Namespace()).To(Equal("skyhook")) + Expect(flags.Namespace()).To(Equal("nodewright")) }) }) }) @@ -186,5 +192,74 @@ var _ = Describe("CLI Context", func() { Expect(ctx.Config()).To(Equal(config)) }) + Describe("ResolveNamespace", func() { + operatorIn := func(namespace string) *appsv1.Deployment { + return &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "controller-manager", + Namespace: namespace, + Labels: map[string]string{"control-plane": "controller-manager"}, + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{Containers: []corev1.Container{{Image: "ghcr.io/nvidia/nodewright/operator:v1"}}}, + }, + }, + } + } + + // The command must have the flag registered for Changed() to be meaningful. + newCmd := func(cliCtx *CLIContext, args ...string) (*cobra.Command, *bytes.Buffer) { + stderr := &bytes.Buffer{} + cmd := &cobra.Command{Use: "test", RunE: func(*cobra.Command, []string) error { return nil }} + cliCtx.GlobalFlags.AddFlags(cmd.Flags()) + cmd.SetErr(stderr) + // Must be non-nil: cobra falls back to os.Args (which carries go test's + // own -test.* flags) when SetArgs is given nil. + cmd.SetArgs(append([]string{}, args...)) + Expect(cmd.Execute()).To(Succeed()) + return cmd, stderr + } + + It("honors an explicit --namespace without touching the cluster", func() { + cliCtx := NewCLIContext(nil) + cmd, stderr := newCmd(cliCtx, "--namespace", "team-platform") + + Expect(cliCtx.ResolveNamespace(gocontext.Background(), cmd, fake.NewClientset(operatorIn("nodewright")))). + To(Equal("team-platform")) + Expect(stderr.String()).To(BeEmpty()) + }) + + It("discovers the nodewright namespace without a note", func() { + cliCtx := NewCLIContext(nil) + cmd, stderr := newCmd(cliCtx) + + Expect(cliCtx.ResolveNamespace(gocontext.Background(), cmd, fake.NewClientset(operatorIn("nodewright")))). + To(Equal("nodewright")) + Expect(stderr.String()).To(BeEmpty()) + }) + + It("discovers a legacy skyhook install and notes it once", func() { + cliCtx := NewCLIContext(nil) + cmd, stderr := newCmd(cliCtx) + kube := fake.NewClientset(operatorIn("skyhook")) + + Expect(cliCtx.ResolveNamespace(gocontext.Background(), cmd, kube)).To(Equal("skyhook")) + Expect(stderr.String()).To(ContainSubstring("legacy \"skyhook\" namespace")) + + // Cached: a second call must not re-probe or re-warn. + stderr.Reset() + Expect(cliCtx.ResolveNamespace(gocontext.Background(), cmd, kube)).To(Equal("skyhook")) + Expect(stderr.String()).To(BeEmpty()) + }) + + It("falls back to the default when no operator is found", func() { + cliCtx := NewCLIContext(nil) + cmd, stderr := newCmd(cliCtx) + + Expect(cliCtx.ResolveNamespace(gocontext.Background(), cmd, fake.NewClientset())).To(Equal("nodewright")) + Expect(stderr.String()).To(BeEmpty()) + }) + }) }) }) diff --git a/operator/internal/cli/utils/utils.go b/operator/internal/cli/utils/utils.go index 37c9a5c8b..caada123c 100644 --- a/operator/internal/cli/utils/utils.go +++ b/operator/internal/cli/utils/utils.go @@ -339,7 +339,15 @@ func outputTableInternal[T any](out io.Writer, cfg TableConfig[T], items []T, wi // Operator version discovery constants const ( - DefaultNamespace = "skyhook" + // DefaultNamespace is the namespace new NodeWright installs use, and the single + // source of truth for the CLI's --namespace default (internal/cli/context seeds + // the flag from it). + DefaultNamespace = "nodewright" + // LegacyDefaultNamespace is the namespace Skyhook installs used before the rename. + // Namespaces cannot be renamed in place, so an existing install legitimately stays + // here; the CLI discovers it rather than forcing a reinstall. See + // ResolveOperatorNamespace. + LegacyDefaultNamespace = "skyhook" // MinAnnotationSupportVersion is the minimum operator version that supports annotation-based pause/disable MinAnnotationSupportVersion = "v0.8.0" // MinNodeStateSupportVersion is the lowest operator version known to use @@ -475,6 +483,73 @@ func DiscoverOperatorVersion(ctx context.Context, kube kubernetes.Interface, nam return "", fmt.Errorf("unable to determine operator version; no nodewright operator deployment found in namespace %q", namespace) } +// ResolveOperatorNamespace works out which namespace the operator is installed in +// when the user did not pass --namespace. +// +// WHY this exists rather than a plain default: the install namespace moved from +// "skyhook" to "nodewright" with the rename, and a namespace cannot be renamed in +// place. Existing installs legitimately stay in "skyhook" forever, so defaulting +// blindly to "nodewright" would answer "not found" for every one of them with no +// explanation. Probing is two namespaced List calls at worst, and needs no +// cluster-wide RBAC. +// +// Resolution order: DefaultNamespace, then LegacyDefaultNamespace, then a +// best-effort cluster-wide sweep for installs in some other namespace. When +// nothing answers, DefaultNamespace is returned so callers still produce their +// own, more specific error. found reports whether an operator was actually +// located, and legacy reports that the answer came from LegacyDefaultNamespace so +// the caller can warn. +func ResolveOperatorNamespace(ctx context.Context, kube kubernetes.Interface) (namespace string, found bool, legacy bool) { + if kube == nil { + return DefaultNamespace, false, false + } + + for _, candidate := range []string{DefaultNamespace, LegacyDefaultNamespace} { + if hasOperatorDeployment(ctx, kube, candidate) { + return candidate, true, candidate == LegacyDefaultNamespace + } + } + + // Last resort. This needs cluster-wide list permission, which a scoped user may + // not have, so a failure here is not an error: fall through to the default and + // let the caller's own lookup report what is actually missing. + deployments, err := kube.AppsV1().Deployments(metav1.NamespaceAll).List(ctx, controllerManagerSelector) + if err != nil { + return DefaultNamespace, false, false + } + for i := range deployments.Items { + if isSkyhookOperatorDeployment(&deployments.Items[i]) { + return deployments.Items[i].Namespace, true, false + } + } + + return DefaultNamespace, false, false +} + +// controllerManagerSelector narrows a Deployment list to the operator's own +// controller-manager, which both the chart and the kustomize overlay label. +// +// WHY this is stricter than DiscoverOperatorVersion's substring match: that match +// accepts any image or label merely CONTAINING "nodewright" or "skyhook", which is +// tolerable when the caller already named the namespace. Namespace resolution has +// no such anchor, so an unrelated deployment (say a "billing-nodewright-exporter" +// in the nodewright namespace) would otherwise decide the namespace and send every +// subsequent lookup to the wrong place. +var controllerManagerSelector = metav1.ListOptions{LabelSelector: "control-plane=controller-manager"} + +func hasOperatorDeployment(ctx context.Context, kube kubernetes.Interface, namespace string) bool { + deployments, err := kube.AppsV1().Deployments(namespace).List(ctx, controllerManagerSelector) + if err != nil { + return false + } + for i := range deployments.Items { + if isSkyhookOperatorDeployment(&deployments.Items[i]) { + return true + } + } + return false +} + // isSkyhookOperatorDeployment checks if a deployment looks like the operator by // examining container images (most reliable), then labels as fallback. It matches // both "nodewright" (current) and "skyhook" (legacy): the operator image and names diff --git a/operator/internal/cli/utils/utils_test.go b/operator/internal/cli/utils/utils_test.go index 00e1b9251..6116119f6 100644 --- a/operator/internal/cli/utils/utils_test.go +++ b/operator/internal/cli/utils/utils_test.go @@ -506,4 +506,85 @@ var _ = Describe("CLI Utility Functions", func() { Expect(isSkyhookOperatorDeployment(dep("busybox:latest", map[string]string{"app": "other"}))).To(BeFalse()) }) }) + + Describe("ResolveOperatorNamespace", func() { + operatorIn := func(namespace string) *appsv1.Deployment { + return &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "controller-manager", + Namespace: namespace, + Labels: map[string]string{"control-plane": "controller-manager"}, + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{Containers: []corev1.Container{{Image: "ghcr.io/nvidia/nodewright/operator:v1"}}}, + }, + }, + } + } + + // Same substring the loose image/label heuristic keys on, but not a + // controller-manager: it must not decide the namespace. + lookalikeIn := func(namespace string) *appsv1.Deployment { + return &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{Name: "billing-nodewright-exporter", Namespace: namespace}, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{Containers: []corev1.Container{{Image: "registry.example/billing-nodewright-exporter:v1"}}}, + }, + }, + } + } + + It("prefers the nodewright namespace", func() { + kube := fake.NewClientset(operatorIn(DefaultNamespace), operatorIn(LegacyDefaultNamespace)) + + namespace, found, legacy := ResolveOperatorNamespace(context.Background(), kube) + Expect(namespace).To(Equal(DefaultNamespace)) + Expect(found).To(BeTrue()) + Expect(legacy).To(BeFalse()) + }) + + It("falls back to the legacy skyhook namespace and flags it", func() { + kube := fake.NewClientset(operatorIn(LegacyDefaultNamespace)) + + namespace, found, legacy := ResolveOperatorNamespace(context.Background(), kube) + Expect(namespace).To(Equal(LegacyDefaultNamespace)) + Expect(found).To(BeTrue()) + Expect(legacy).To(BeTrue()) + }) + + It("finds an install in an arbitrary namespace via the cluster-wide sweep", func() { + kube := fake.NewClientset(operatorIn("platform-tools")) + + namespace, found, legacy := ResolveOperatorNamespace(context.Background(), kube) + Expect(namespace).To(Equal("platform-tools")) + Expect(found).To(BeTrue()) + Expect(legacy).To(BeFalse()) + }) + + It("ignores a non-controller-manager lookalike and picks the real namespace", func() { + kube := fake.NewClientset(lookalikeIn(DefaultNamespace), operatorIn(LegacyDefaultNamespace)) + + namespace, found, legacy := ResolveOperatorNamespace(context.Background(), kube) + Expect(namespace).To(Equal(LegacyDefaultNamespace)) + Expect(found).To(BeTrue()) + Expect(legacy).To(BeTrue()) + }) + + It("reports the default when no operator is installed", func() { + kube := fake.NewClientset() + + namespace, found, legacy := ResolveOperatorNamespace(context.Background(), kube) + Expect(namespace).To(Equal(DefaultNamespace)) + Expect(found).To(BeFalse()) + Expect(legacy).To(BeFalse()) + }) + + It("reports the default when there is no client", func() { + namespace, found, _ := ResolveOperatorNamespace(context.Background(), nil) + Expect(namespace).To(Equal(DefaultNamespace)) + Expect(found).To(BeFalse()) + }) + }) }) diff --git a/operator/internal/controller/skyhook_controller.go b/operator/internal/controller/skyhook_controller.go index bbe99ca69..9dbb6d9c6 100644 --- a/operator/internal/controller/skyhook_controller.go +++ b/operator/internal/controller/skyhook_controller.go @@ -111,7 +111,7 @@ const ( ) type SkyhookOperatorOptions struct { - Namespace string `env:"NAMESPACE, default=skyhook"` + Namespace string `env:"NAMESPACE, default=nodewright"` MaxInterval time.Duration `env:"DEFAULT_INTERVAL, default=10m"` ImagePullSecret string `env:"IMAGE_PULL_SECRET"` CopyDirRoot string `env:"COPY_DIR_ROOT, default=/var/lib/skyhook"` diff --git a/scripts/scale_test.sh b/scripts/scale_test.sh index b1b1f6d99..6b2df6886 100755 --- a/scripts/scale_test.sh +++ b/scripts/scale_test.sh @@ -23,7 +23,7 @@ # - EKS cluster already exists; kubectl context is set to that cluster. # - A node group exists and is the one you pass via --node-group (script scales # it with aws eks update-nodegroup-config and uses it as node selector). -# - skyhook-operator is installed in the cluster (default namespace: skyhook-operator). +# - the operator is installed in the cluster (default namespace: nodewright). # # Metrics endpoint (for --metrics-source): # - kube (default): uses kubectl top for operator pod memory. Install metrics-server @@ -52,7 +52,7 @@ POLICY_YAML="${SCRIPT_DIR}/scale_test_policy.yaml" SKYHOOK_YAML="${SCRIPT_DIR}/scale_test_skyhook.yaml" # Defaults -NAMESPACE="${NAMESPACE:-skyhook-operator}" +NAMESPACE="${NAMESPACE:-nodewright}" METRICS_SOURCE="${METRICS_SOURCE:-kube}" METRICS_SERVICE_ACCOUNT="${METRICS_SERVICE_ACCOUNT:-scale-test-metrics}" OUTPUT_FILE="" @@ -76,7 +76,7 @@ Required: --final-size Final desired node count (inclusive) Options: - --namespace Operator namespace (default: skyhook-operator) + --namespace Operator namespace (default: nodewright) --metrics-source kube|prometheus (default: kube). kube uses kubectl top; prometheus uses authenticated HTTPS on operator :8443/metrics. --output Write CSV results to this path (default: ./scale_test_results_.csv) --no-clear-annotations Do not remove skyhook annotations/labels from nodes (Skyhook/Policy CRs are still deleted)