From 07d9fbe8e22ef99ccf180f1f8807af820940ff66 Mon Sep 17 00:00:00 2001 From: corang Date: Thu, 29 Sep 2022 17:17:45 -0500 Subject: [PATCH 1/6] add new example for no wait --- Makefile | 2 ++ examples/helm-no-wait/README.md | 17 +++++++++++++ examples/helm-no-wait/never-ready.pod.yaml | 23 +++++++++++++++++ examples/helm-no-wait/zarf.yaml | 16 ++++++++++++ src/test/e2e/28_wait_test.go | 29 ++++++++++++++++++++++ 5 files changed, 87 insertions(+) create mode 100644 examples/helm-no-wait/README.md create mode 100644 examples/helm-no-wait/never-ready.pod.yaml create mode 100644 examples/helm-no-wait/zarf.yaml create mode 100644 src/test/e2e/28_wait_test.go diff --git a/Makefile b/Makefile index a6df12401c..b6581d2108 100644 --- a/Makefile +++ b/Makefile @@ -142,6 +142,8 @@ build-examples: @test -s ./build/zarf-package-flux-test-${ARCH}.tar.zst || $(ZARF_BIN) package create examples/flux-test -o build -a $(ARCH) --confirm + @test -s ./build/zarf-package-test-helm-wait-$(ARCH).tar.zst || $(ZARF_BIN) package create examples/helm-no-wait -o build -a $(ARCH) --confirm + ## Run e2e tests. Will automatically build any required dependencies that aren't present. ## Requires an existing cluster for the env var APPLIANCE_MODE=true .PHONY: test-e2e diff --git a/examples/helm-no-wait/README.md b/examples/helm-no-wait/README.md new file mode 100644 index 0000000000..9863ab94cd --- /dev/null +++ b/examples/helm-no-wait/README.md @@ -0,0 +1,17 @@ +# Helm Alt Release Name + +This example shows how you can specify for zarf to not wait for resources to report ready within a component's `manifests`. This is also applicable to `charts`. + +:::info + +To view the example source code, select the `Edit this page` link below the article and select the parent folder. + +::: + +``` +components: + - name: component-name + manifests: + - name: chart-name + wait: false +``` diff --git a/examples/helm-no-wait/never-ready.pod.yaml b/examples/helm-no-wait/never-ready.pod.yaml new file mode 100644 index 0000000000..615dc2cb3b --- /dev/null +++ b/examples/helm-no-wait/never-ready.pod.yaml @@ -0,0 +1,23 @@ +apiVersion: v1 +kind: Pod +metadata: + name: never-ready-zarf-wait-test +spec: + containers: + - name: alpine + image: alpine:latest + command: + - "sleep" + - "infinity" + resources: + requests: + memory: "64Mi" + cpu: "250m" + limits: + memory: "128Mi" + cpu: "500m" + readinessProbe: + exec: + command: + - "exit" + - "1" \ No newline at end of file diff --git a/examples/helm-no-wait/zarf.yaml b/examples/helm-no-wait/zarf.yaml new file mode 100644 index 0000000000..f5297a200a --- /dev/null +++ b/examples/helm-no-wait/zarf.yaml @@ -0,0 +1,16 @@ +kind: ZarfPackageConfig +metadata: + name: test-helm-wait + description: "Deploys a pod which never becomes ready" +components: + - name: zarf-helm-no-wait + required: true + manifests: + - name: never-ready + namespace: no-wait + wait: false + files: + - never-ready.pod.yaml + images: + - alpine:latest + diff --git a/src/test/e2e/28_wait_test.go b/src/test/e2e/28_wait_test.go new file mode 100644 index 0000000000..00839324b5 --- /dev/null +++ b/src/test/e2e/28_wait_test.go @@ -0,0 +1,29 @@ +package test + +import ( + "fmt" + "os/exec" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestWait(t *testing.T) { + t.Log("E2E: Helm Wait") + e2e.setup(t) + defer e2e.teardown(t) + + path := fmt.Sprintf("build/zarf-package-test-helm-releasename-%s.tar.zst", e2e.arch) + + // Deploy the charts + stdOut, stdErr, err := e2e.execZarfCommand("package", "deploy", path, "--confirm") + require.NoError(t, err, stdOut, stdErr) + + // Verify multiple helm installs of different release names were deployed + kubectlOut, _ := exec.Command("kubectl", "get", "pods", "-n=helm-releasename", "--no-headers").Output() + assert.Contains(t, string(kubectlOut), "zarf-cool-name-podinfo") + + stdOut, stdErr, err = e2e.execZarfCommand("package", "remove", "test-helm-releasename", "--confirm") + require.NoError(t, err, stdOut, stdErr) +} From 762010bd889aaea4e9011d587ebae35c9cfd217f Mon Sep 17 00:00:00 2001 From: corang Date: Thu, 29 Sep 2022 18:12:58 -0500 Subject: [PATCH 2/6] working test I think --- src/test/e2e/28_wait_test.go | 50 +++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/src/test/e2e/28_wait_test.go b/src/test/e2e/28_wait_test.go index 00839324b5..e6485b115a 100644 --- a/src/test/e2e/28_wait_test.go +++ b/src/test/e2e/28_wait_test.go @@ -1,29 +1,61 @@ package test import ( + // "context" "fmt" - "os/exec" + "time" + + // "os/exec" "testing" - "github.com/stretchr/testify/assert" + // "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) +type zarfCommandResult struct { + stdOut string + stdErr string + err error +} + +func zarfCommandWStruct(e2e ZarfE2ETest, path string) (result zarfCommandResult) { + result.stdOut, result.stdErr, result.err = e2e.execZarfCommand("package", "deploy", path, "--confirm") + return result +} + func TestWait(t *testing.T) { t.Log("E2E: Helm Wait") e2e.setup(t) defer e2e.teardown(t) - path := fmt.Sprintf("build/zarf-package-test-helm-releasename-%s.tar.zst", e2e.arch) + path := fmt.Sprintf("build/zarf-package-test-helm-wait-%s.tar.zst", e2e.arch) + + zarfChannel := make(chan zarfCommandResult, 1) + go func() { + zarfChannel <- zarfCommandWStruct(e2e, path) + }() + + var stdOut string + var stdErr string + var err error + + select{ + case res := <-zarfChannel: + stdOut = res.stdOut + stdErr = res.stdErr + err = res.err + case <-time.After(10 * time.Second): + t.Error("Timeout waiting for zarf deploy (it tried to wait)") + } // Deploy the charts - stdOut, stdErr, err := e2e.execZarfCommand("package", "deploy", path, "--confirm") + // stdOut, stdErr, err := e2e.execZarfCommand("package", "deploy", path, "--confirm") require.NoError(t, err, stdOut, stdErr) - // Verify multiple helm installs of different release names were deployed - kubectlOut, _ := exec.Command("kubectl", "get", "pods", "-n=helm-releasename", "--no-headers").Output() - assert.Contains(t, string(kubectlOut), "zarf-cool-name-podinfo") + // // Verify multiple helm installs of different release names were deployed + // kubectlOut, _ := exec.Command("kubectl", "get", "pods", "-n=helm-releasename", "--no-headers").Output() + // assert.Contains(t, string(kubectlOut), "zarf-cool-name-podinfo") - stdOut, stdErr, err = e2e.execZarfCommand("package", "remove", "test-helm-releasename", "--confirm") + stdOut, stdErr, err = e2e.execZarfCommand("package", "remove", "test-helm-wait", "--confirm") require.NoError(t, err, stdOut, stdErr) -} +} \ No newline at end of file From 461152c4bca060ce26b96c273b01ae2765deca87 Mon Sep 17 00:00:00 2001 From: corang Date: Mon, 3 Oct 2022 12:46:36 -0500 Subject: [PATCH 3/6] added noWait functionality in zarf.yaml --- examples/helm-no-wait/zarf.yaml | 2 +- src/internal/helm/chart.go | 8 ++++---- src/test/e2e/28_wait_test.go | 8 ++++++++ src/types/component.go | 2 ++ 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/examples/helm-no-wait/zarf.yaml b/examples/helm-no-wait/zarf.yaml index f5297a200a..23e28c18ed 100644 --- a/examples/helm-no-wait/zarf.yaml +++ b/examples/helm-no-wait/zarf.yaml @@ -8,7 +8,7 @@ components: manifests: - name: never-ready namespace: no-wait - wait: false + noWait: true files: - never-ready.pod.yaml images: diff --git a/src/internal/helm/chart.go b/src/internal/helm/chart.go index e39e06e423..2406e13c4d 100644 --- a/src/internal/helm/chart.go +++ b/src/internal/helm/chart.go @@ -26,7 +26,6 @@ type ChartOptions struct { ChartOverride *chart.Chart ValueOverride map[string]any Component types.ZarfComponent - NoWait bool } // InstallOrUpgradeChart performs a helm install of the given chart @@ -53,7 +52,7 @@ func InstallOrUpgradeChart(options ChartOptions) (types.ConnectStrings, string) // Do not wait for the chart to be ready if data injections are present if len(options.Component.DataInjections) > 0 { spinner.Updatef("Data injections detected, not waiting for chart to be ready") - options.NoWait = true + options.Chart.NoWait = true } actionConfig, err := createActionConfig(options.Chart.Namespace, spinner) @@ -207,6 +206,7 @@ func GenerateChart(basePath string, manifest types.ZarfManifest, component types ReleaseName: sha1ReleaseName, Version: tmpChart.Metadata.Version, Namespace: manifest.Namespace, + NoWait: manifest.NoWait, }, ChartOverride: tmpChart, // We don't have any values because we do not expose them in the zarf.yaml currently @@ -229,7 +229,7 @@ func installChart(actionConfig *action.Configuration, options ChartOptions, post client.Timeout = 15 * time.Minute // Default helm behavior for Zarf is to wait for the resources to deploy, NoWait overrides that for special cases (such as data-injection) - client.Wait = !options.NoWait + client.Wait = !options.Chart.NoWait // We need to include CRDs or operator installations will fail spectacularly client.SkipCRDs = false @@ -260,7 +260,7 @@ func upgradeChart(actionConfig *action.Configuration, options ChartOptions, post client.Timeout = 15 * time.Minute // Default helm behavior for Zarf is to wait for the resources to deploy, NoWait overrides that for special cases (such as data-injection)k3 - client.Wait = !options.NoWait + client.Wait = !options.Chart.NoWait client.SkipCRDs = true diff --git a/src/test/e2e/28_wait_test.go b/src/test/e2e/28_wait_test.go index e6485b115a..75f22674e9 100644 --- a/src/test/e2e/28_wait_test.go +++ b/src/test/e2e/28_wait_test.go @@ -3,6 +3,7 @@ package test import ( // "context" "fmt" + "os/exec" "time" // "os/exec" @@ -46,6 +47,13 @@ func TestWait(t *testing.T) { err = res.err case <-time.After(10 * time.Second): t.Error("Timeout waiting for zarf deploy (it tried to wait)") + t.Log("Removing hanging namespace...") + kubectlOut, err := exec.Command("kubectl", "delete", "namespace", "no-wait", "--force=true", "--wait=false", "--grace-period=0").Output() + if err != nil { + t.Log(kubectlOut) + } else { + panic(err) + } } // Deploy the charts diff --git a/src/types/component.go b/src/types/component.go index f74f844b46..b88cdbdd0f 100644 --- a/src/types/component.go +++ b/src/types/component.go @@ -78,6 +78,7 @@ type ZarfChart struct { Namespace string `json:"namespace" jsonschema:"description=The namespace to deploy the chart to"` ValuesFiles []string `json:"valuesFiles,omitempty" jsonschema:"description=List of values files to include in the package, these will be merged together"` GitPath string `json:"gitPath,omitempty" jsonschema:"description=If using a git repo, the path to the chart in the repo"` + NoWait bool `json:"noWait,omitempty" jsonschema:"description=Wait for chart resources to be ready before continuing"` } // ZarfManifest defines raw manifests Zarf will deploy as a helm chart @@ -87,6 +88,7 @@ type ZarfManifest struct { Files []string `json:"files,omitempty" jsonschema:"description=List of individual K8s YAML files to deploy (in order)"` KustomizeAllowAnyDirectory bool `json:"kustomizeAllowAnyDirectory,omitempty" jsonschema:"description=Allow traversing directory above the current directory if needed for kustomization"` Kustomizations []string `json:"kustomizations,omitempty" jsonschema:"description=List of kustomization paths to include in the package"` + NoWait bool `json:"noWait,omitempty" jsonschema:"description=Wait for manifest resources to be ready before continuing"` } // ZarfComponentScripts are scripts that run before or after a component is deployed From 172fba150af63d6144274b6d8c281d9b72ab2dc8 Mon Sep 17 00:00:00 2001 From: corang Date: Mon, 3 Oct 2022 12:54:25 -0500 Subject: [PATCH 4/6] schema update --- docs/4-user-guide/3-zarf-schema.md | 30 ++++++++++++++++++++++++++++++ src/ui/lib/api-types.ts | 10 ++++++++++ zarf.schema.json | 8 ++++++++ 3 files changed, 48 insertions(+) diff --git a/docs/4-user-guide/3-zarf-schema.md b/docs/4-user-guide/3-zarf-schema.md index 9c9d4f4031..c236281573 100644 --- a/docs/4-user-guide/3-zarf-schema.md +++ b/docs/4-user-guide/3-zarf-schema.md @@ -947,6 +947,21 @@ Must be one of: +
+ noWait + + +  +
+ +**Description:** Wait for chart resources to be ready before continuing + +| Type | `boolean` | +| ---- | --------- | + +
+
+ @@ -1078,6 +1093,21 @@ Must be one of: +
+ noWait + + +  +
+ +**Description:** Wait for manifest resources to be ready before continuing + +| Type | `boolean` | +| ---- | --------- | + +
+
+ diff --git a/src/ui/lib/api-types.ts b/src/ui/lib/api-types.ts index 62d8d907ff..b16ea7a95e 100644 --- a/src/ui/lib/api-types.ts +++ b/src/ui/lib/api-types.ts @@ -139,6 +139,10 @@ export interface ZarfChart { * The namespace to deploy the chart to */ namespace: string; + /** + * Wait for chart resources to be ready before continuing + */ + noWait?: boolean; /** * The name of the release to create */ @@ -248,6 +252,10 @@ export interface ZarfManifest { * The namespace to deploy the manifests to */ namespace?: string; + /** + * Wait for manifest resources to be ready before continuing + */ + noWait?: boolean; } /** @@ -784,6 +792,7 @@ const typeMap: any = { { json: "gitPath", js: "gitPath", typ: u(undefined, "") }, { json: "name", js: "name", typ: "" }, { json: "namespace", js: "namespace", typ: "" }, + { json: "noWait", js: "noWait", typ: u(undefined, true) }, { json: "releaseName", js: "releaseName", typ: u(undefined, "") }, { json: "url", js: "url", typ: "" }, { json: "valuesFiles", js: "valuesFiles", typ: u(undefined, a("")) }, @@ -817,6 +826,7 @@ const typeMap: any = { { json: "kustomizeAllowAnyDirectory", js: "kustomizeAllowAnyDirectory", typ: u(undefined, true) }, { json: "name", js: "name", typ: "" }, { json: "namespace", js: "namespace", typ: u(undefined, "") }, + { json: "noWait", js: "noWait", typ: u(undefined, true) }, ], false), "ZarfComponentOnlyTarget": o([ { json: "cluster", js: "cluster", typ: u(undefined, r("ZarfComponentOnlyCluster")) }, diff --git a/zarf.schema.json b/zarf.schema.json index 2194783b10..47de89aaab 100644 --- a/zarf.schema.json +++ b/zarf.schema.json @@ -68,6 +68,10 @@ "gitPath": { "type": "string", "description": "If using a git repo" + }, + "noWait": { + "type": "boolean", + "description": "Wait for chart resources to be ready before continuing" } }, "additionalProperties": false, @@ -377,6 +381,10 @@ }, "type": "array", "description": "List of kustomization paths to include in the package" + }, + "noWait": { + "type": "boolean", + "description": "Wait for manifest resources to be ready before continuing" } }, "additionalProperties": false, From 1434ccdaa73273c7f4e7f322db8b06213dd630ff Mon Sep 17 00:00:00 2001 From: corang Date: Mon, 3 Oct 2022 12:56:30 -0500 Subject: [PATCH 5/6] example docs fix --- examples/helm-no-wait/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/helm-no-wait/README.md b/examples/helm-no-wait/README.md index 9863ab94cd..ab2f7623ab 100644 --- a/examples/helm-no-wait/README.md +++ b/examples/helm-no-wait/README.md @@ -13,5 +13,5 @@ components: - name: component-name manifests: - name: chart-name - wait: false + noWait: true ``` From ef7011f7b2c036c349fb9e1ac7898cd71d47989a Mon Sep 17 00:00:00 2001 From: corang Date: Wed, 5 Oct 2022 14:23:04 -0500 Subject: [PATCH 6/6] PR requested fixes --- examples/helm-no-wait/README.md | 2 +- examples/helm-no-wait/never-ready.pod.yaml | 2 +- src/test/e2e/28_wait_test.go | 9 +-------- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/examples/helm-no-wait/README.md b/examples/helm-no-wait/README.md index ab2f7623ab..3bd823d823 100644 --- a/examples/helm-no-wait/README.md +++ b/examples/helm-no-wait/README.md @@ -1,4 +1,4 @@ -# Helm Alt Release Name +# Helm No Wait This example shows how you can specify for zarf to not wait for resources to report ready within a component's `manifests`. This is also applicable to `charts`. diff --git a/examples/helm-no-wait/never-ready.pod.yaml b/examples/helm-no-wait/never-ready.pod.yaml index 615dc2cb3b..6fa1682d52 100644 --- a/examples/helm-no-wait/never-ready.pod.yaml +++ b/examples/helm-no-wait/never-ready.pod.yaml @@ -20,4 +20,4 @@ spec: exec: command: - "exit" - - "1" \ No newline at end of file + - "1" diff --git a/src/test/e2e/28_wait_test.go b/src/test/e2e/28_wait_test.go index 75f22674e9..ec618af276 100644 --- a/src/test/e2e/28_wait_test.go +++ b/src/test/e2e/28_wait_test.go @@ -55,15 +55,8 @@ func TestWait(t *testing.T) { panic(err) } } - - // Deploy the charts - // stdOut, stdErr, err := e2e.execZarfCommand("package", "deploy", path, "--confirm") require.NoError(t, err, stdOut, stdErr) - // // Verify multiple helm installs of different release names were deployed - // kubectlOut, _ := exec.Command("kubectl", "get", "pods", "-n=helm-releasename", "--no-headers").Output() - // assert.Contains(t, string(kubectlOut), "zarf-cool-name-podinfo") - stdOut, stdErr, err = e2e.execZarfCommand("package", "remove", "test-helm-wait", "--confirm") require.NoError(t, err, stdOut, stdErr) -} \ No newline at end of file +}