From 32e22a7bc273e287307098fd95c7eaf982dd9eb4 Mon Sep 17 00:00:00 2001 From: Stefan Bueringer Date: Wed, 17 Nov 2021 10:09:26 +0100 Subject: [PATCH] Fix clusterctl upgrade test (v1-0 => main) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stefan Büringer buringerst@vmware.com --- .../hack/create-local-repository.py | 8 +- test/e2e/config/docker.yaml | 45 ++++++++- test/framework/clusterctl/client.go | 92 ++++++++++++++----- 3 files changed, 114 insertions(+), 31 deletions(-) diff --git a/cmd/clusterctl/hack/create-local-repository.py b/cmd/clusterctl/hack/create-local-repository.py index fcb63b93ef58..06574faaeabf 100755 --- a/cmd/clusterctl/hack/create-local-repository.py +++ b/cmd/clusterctl/hack/create-local-repository.py @@ -53,24 +53,24 @@ providers = { 'cluster-api': { 'componentsFile': 'core-components.yaml', - 'nextVersion': 'v1.0.99', + 'nextVersion': 'v1.1.99', 'type': 'CoreProvider', }, 'bootstrap-kubeadm': { 'componentsFile': 'bootstrap-components.yaml', - 'nextVersion': 'v1.0.99', + 'nextVersion': 'v1.1.99', 'type': 'BootstrapProvider', 'configFolder': 'bootstrap/kubeadm/config/default', }, 'control-plane-kubeadm': { 'componentsFile': 'control-plane-components.yaml', - 'nextVersion': 'v1.0.99', + 'nextVersion': 'v1.1.99', 'type': 'ControlPlaneProvider', 'configFolder': 'controlplane/kubeadm/config/default', }, 'infrastructure-docker': { 'componentsFile': 'infrastructure-components.yaml', - 'nextVersion': 'v1.0.99', + 'nextVersion': 'v1.1.99', 'type': 'InfrastructureProvider', 'configFolder': 'test/infrastructure/docker/config/default', }, diff --git a/test/e2e/config/docker.yaml b/test/e2e/config/docker.yaml index c0c9993c1350..28944683148e 100644 --- a/test/e2e/config/docker.yaml +++ b/test/e2e/config/docker.yaml @@ -47,7 +47,16 @@ providers: new: --metrics-addr=:8080 files: - sourcePath: "../data/shared/v1alpha4/metadata.yaml" - - name: v1.0.99 # next; use manifest from source files + - name: v1.0.1 # latest published release in the v1beta1 series; this is used for v1beta1 --> main clusterctl upgrades test only. + value: "https://github.com/kubernetes-sigs/cluster-api/releases/download/v1.0.1/core-components.yaml" + type: "url" + contract: v1beta1 + replacements: + - old: --metrics-addr=127.0.0.1:8080 + new: --metrics-addr=:8080 + files: + - sourcePath: "../data/shared/v1beta1/metadata.yaml" + - name: v1.1.99 # next; use manifest from source files value: ../../../config/default replacements: - old: --metrics-bind-addr=localhost:8080 @@ -76,7 +85,16 @@ providers: new: --metrics-addr=:8080 files: - sourcePath: "../data/shared/v1alpha4/metadata.yaml" - - name: v1.0.99 # next; use manifest from source files + - name: v1.0.1 # latest published release in the v1beta1 series; this is used for v1beta1 --> main clusterctl upgrades test only. + value: "https://github.com/kubernetes-sigs/cluster-api/releases/download/v1.0.1/bootstrap-components.yaml" + type: "url" + contract: v1beta1 + replacements: + - old: --metrics-addr=127.0.0.1:8080 + new: --metrics-addr=:8080 + files: + - sourcePath: "../data/shared/v1beta1/metadata.yaml" + - name: v1.1.99 # next; use manifest from source files value: ../../../bootstrap/kubeadm/config/default replacements: - old: --metrics-bind-addr=localhost:8080 @@ -105,7 +123,16 @@ providers: new: --metrics-addr=:8080 files: - sourcePath: "../data/shared/v1alpha4/metadata.yaml" - - name: v1.0.99 # next; use manifest from source files + - name: v1.0.1 # latest published release in the v1beta1 series; this is used for v1beta1 --> main clusterctl upgrades test only. + value: "https://github.com/kubernetes-sigs/cluster-api/releases/download/v1.0.1/control-plane-components.yaml" + type: "url" + contract: v1beta1 + replacements: + - old: --metrics-addr=127.0.0.1:8080 + new: --metrics-addr=:8080 + files: + - sourcePath: "../data/shared/v1beta1/metadata.yaml" + - name: v1.1.99 # next; use manifest from source files value: ../../../controlplane/kubeadm/config/default replacements: - old: --metrics-bind-addr=localhost:8080 @@ -136,7 +163,17 @@ providers: files: - sourcePath: "../data/shared/v1alpha4/metadata.yaml" - sourcePath: "../data/infrastructure-docker/v1alpha4/cluster-template.yaml" - - name: v1.0.99 # next; use manifest from source files + - name: v1.0.1 # latest published release in the v1beta1 series; this is used for v1beta1 --> main clusterctl upgrades test only. + value: "https://github.com/kubernetes-sigs/cluster-api/releases/download/v1.0.1/infrastructure-components-development.yaml" + type: "url" + contract: v1beta1 + replacements: + - old: --metrics-addr=127.0.0.1:8080 + new: --metrics-addr=:8080 + files: + - sourcePath: "../data/shared/v1beta1/metadata.yaml" + - sourcePath: "../data/infrastructure-docker/v1beta1/cluster-template.yaml" + - name: v1.1.99 # next; use manifest from source files value: ../../../test/infrastructure/docker/config/default replacements: - old: --metrics-bind-addr=localhost:8080 diff --git a/test/framework/clusterctl/client.go b/test/framework/clusterctl/client.go index 55eca28a86fd..2eecfbbe18e1 100644 --- a/test/framework/clusterctl/client.go +++ b/test/framework/clusterctl/client.go @@ -103,7 +103,13 @@ func InitWithBinary(_ context.Context, binary string, input InitInput) { out, err := cmd.CombinedOutput() _ = os.WriteFile(filepath.Join(input.LogFolder, "clusterctl-init.log"), out, 0644) //nolint:gosec // this is a log file to be shared via prow artifacts - Expect(err).ToNot(HaveOccurred(), "failed to run clusterctl init:\n%s", string(out)) + var stdErr string + if err != nil { + if exitErr, ok := err.(*exec.ExitError); ok { + stdErr = string(exitErr.Stderr) + } + } + Expect(err).ToNot(HaveOccurred(), "failed to run clusterctl init:\nstdout:\n%s\nstderr:\n%s", string(out), stdErr) } // UpgradeInput is the input for Upgrade. @@ -215,32 +221,72 @@ func ConfigCluster(ctx context.Context, input ConfigClusterInput) []byte { return yaml } -// ConfigClusterWithBinary uses clusterctl binary to run config cluster. +// ConfigClusterWithBinary uses clusterctl binary to run config cluster or generate cluster. +// NOTE: This func detects the clusterctl version and uses config cluster or generate cluster +// accordingly. We can drop the detection when we don't have to support clusterctl v0.3.x anymore. func ConfigClusterWithBinary(_ context.Context, clusterctlBinaryPath string, input ConfigClusterInput) []byte { - log.Logf("clusterctl config cluster %s --infrastructure %s --kubernetes-version %s --control-plane-machine-count %d --worker-machine-count %d --flavor %s", - input.ClusterName, - valueOrDefault(input.InfrastructureProvider), - input.KubernetesVersion, - *input.ControlPlaneMachineCount, - *input.WorkerMachineCount, - valueOrDefault(input.Flavor), - ) + log.Logf("Detect clusterctl version via: clusterctl version") + + out, err := exec.Command(clusterctlBinaryPath, "version").Output() + Expect(err).ToNot(HaveOccurred(), "error running clusterctl version") + var clusterctlSupportsGenerateCluster bool + if strings.Contains(string(out), "Major:\"1\"") { + log.Logf("Detected clusterctl v1.x") + clusterctlSupportsGenerateCluster = true + } - cmd := exec.Command(clusterctlBinaryPath, "config", "cluster", //nolint:gosec // We don't care about command injection here. - input.ClusterName, - "--infrastructure", input.InfrastructureProvider, - "--kubernetes-version", input.KubernetesVersion, - "--control-plane-machine-count", fmt.Sprint(*input.ControlPlaneMachineCount), - "--worker-machine-count", fmt.Sprint(*input.WorkerMachineCount), - "--flavor", input.Flavor, - "--target-namespace", input.Namespace, - "--config", input.ClusterctlConfigPath, - "--kubeconfig", input.KubeconfigPath, - ) + var cmd *exec.Cmd + if clusterctlSupportsGenerateCluster { + log.Logf("clusterctl generate cluster %s --infrastructure %s --kubernetes-version %s --control-plane-machine-count %d --worker-machine-count %d --flavor %s", + input.ClusterName, + valueOrDefault(input.InfrastructureProvider), + input.KubernetesVersion, + *input.ControlPlaneMachineCount, + *input.WorkerMachineCount, + valueOrDefault(input.Flavor), + ) + cmd = exec.Command(clusterctlBinaryPath, "generate", "cluster", //nolint:gosec // We don't care about command injection here. + input.ClusterName, + "--infrastructure", input.InfrastructureProvider, + "--kubernetes-version", input.KubernetesVersion, + "--control-plane-machine-count", fmt.Sprint(*input.ControlPlaneMachineCount), + "--worker-machine-count", fmt.Sprint(*input.WorkerMachineCount), + "--flavor", input.Flavor, + "--target-namespace", input.Namespace, + "--config", input.ClusterctlConfigPath, + "--kubeconfig", input.KubeconfigPath, + ) + } else { + log.Logf("clusterctl config cluster %s --infrastructure %s --kubernetes-version %s --control-plane-machine-count %d --worker-machine-count %d --flavor %s", + input.ClusterName, + valueOrDefault(input.InfrastructureProvider), + input.KubernetesVersion, + *input.ControlPlaneMachineCount, + *input.WorkerMachineCount, + valueOrDefault(input.Flavor), + ) + cmd = exec.Command(clusterctlBinaryPath, "config", "cluster", //nolint:gosec // We don't care about command injection here. + input.ClusterName, + "--infrastructure", input.InfrastructureProvider, + "--kubernetes-version", input.KubernetesVersion, + "--control-plane-machine-count", fmt.Sprint(*input.ControlPlaneMachineCount), + "--worker-machine-count", fmt.Sprint(*input.WorkerMachineCount), + "--flavor", input.Flavor, + "--target-namespace", input.Namespace, + "--config", input.ClusterctlConfigPath, + "--kubeconfig", input.KubeconfigPath, + ) + } - out, err := cmd.Output() + out, err = cmd.Output() _ = os.WriteFile(filepath.Join(input.LogFolder, fmt.Sprintf("%s-cluster-template.yaml", input.ClusterName)), out, 0644) //nolint:gosec // this is a log file to be shared via prow artifacts - Expect(err).ToNot(HaveOccurred(), "failed to run clusterctl config cluster:\n%s", string(out)) + var stdErr string + if err != nil { + if exitErr, ok := err.(*exec.ExitError); ok { + stdErr = string(exitErr.Stderr) + } + } + Expect(err).ToNot(HaveOccurred(), "failed to run clusterctl config cluster:\nstdout:\n%s\nstderr:\n%s", string(out), stdErr) return out }