diff --git a/test/e2e/clusterctl_upgrade.go b/test/e2e/clusterctl_upgrade.go index 868e779c552a..c76578e74ad0 100644 --- a/test/e2e/clusterctl_upgrade.go +++ b/test/e2e/clusterctl_upgrade.go @@ -201,6 +201,9 @@ func ClusterctlUpgradeSpec(ctx context.Context, inputGetter func() ClusterctlUpg err := os.Chmod(clusterctlBinaryPath, 0744) //nolint:gosec Expect(err).ToNot(HaveOccurred(), "failed to chmod temporary file") + // Adjusts the clusterctlConfigPath in case the clusterctl version <= v1.3 (thus using a config file with only the providers supported in those versions) + clusterctlConfigPath := clusterctl.AdjustConfigPathForBinary(clusterctlBinaryPath, input.ClusterctlConfigPath) + By("Initializing the workload cluster with older versions of providers") // NOTE: by default we are considering all the providers, no matter of the contract. @@ -222,7 +225,7 @@ func ClusterctlUpgradeSpec(ctx context.Context, inputGetter func() ClusterctlUpg clusterctl.InitManagementClusterAndWatchControllerLogs(ctx, clusterctl.InitManagementClusterAndWatchControllerLogsInput{ ClusterctlBinaryPath: clusterctlBinaryPath, // use older version of clusterctl to init the management cluster ClusterProxy: managementClusterProxy, - ClusterctlConfigPath: input.ClusterctlConfigPath, + ClusterctlConfigPath: clusterctlConfigPath, CoreProvider: input.E2EConfig.GetProviderLatestVersionsByContract(contract, config.ClusterAPIProviderName)[0], BootstrapProviders: input.E2EConfig.GetProviderLatestVersionsByContract(contract, config.KubeadmBootstrapProviderName), ControlPlaneProviders: input.E2EConfig.GetProviderLatestVersionsByContract(contract, config.KubeadmControlPlaneProviderName), @@ -261,7 +264,7 @@ func ClusterctlUpgradeSpec(ctx context.Context, inputGetter func() ClusterctlUpg // pass reference to the management cluster hosting this test KubeconfigPath: managementClusterProxy.GetKubeconfigPath(), // pass the clusterctl config file that points to the local provider repository created for this test, - ClusterctlConfigPath: input.ClusterctlConfigPath, + ClusterctlConfigPath: clusterctlConfigPath, // select template Flavor: input.WorkloadFlavor, // define template variables diff --git a/test/framework/clusterctl/client.go b/test/framework/clusterctl/client.go index 0d7da962ca1d..18367405b637 100644 --- a/test/framework/clusterctl/client.go +++ b/test/framework/clusterctl/client.go @@ -107,7 +107,7 @@ func InitWithBinary(_ context.Context, binary string, input InitInput) { input.KubeconfigPath, ) - args := []string{binary, "init", "--config", input.ClusterctlConfigPath, "--kubeconfig", input.KubeconfigPath} + args := []string{"init", "--config", input.ClusterctlConfigPath, "--kubeconfig", input.KubeconfigPath} if input.CoreProvider != "" { args = append(args, "--core", input.CoreProvider) } diff --git a/test/framework/clusterctl/repository.go b/test/framework/clusterctl/repository.go index 7b46d8ae192b..9e52592c189b 100644 --- a/test/framework/clusterctl/repository.go +++ b/test/framework/clusterctl/repository.go @@ -28,6 +28,7 @@ import ( "regexp" "strings" + "github.com/blang/semver" . "github.com/onsi/gomega" "github.com/pkg/errors" @@ -74,6 +75,9 @@ func (i *CreateRepositoryInput) RegisterClusterResourceSetConfigMapTransformatio }) } +const clusterctlConfigFileName = "clusterctl-config.yaml" +const clusterctlConfigV1_2FileName = "clusterctl-config.v1.2.yaml" + // CreateRepository creates a clusterctl local repository based on the e2e test config, and the returns the path // to a clusterctl config file to be used for working with such repository. func CreateRepository(ctx context.Context, input CreateRepositoryInput) string { @@ -81,6 +85,7 @@ func CreateRepository(ctx context.Context, input CreateRepositoryInput) string { Expect(os.MkdirAll(input.RepositoryFolder, 0750)).To(Succeed(), "Failed to create the clusterctl local repository folder %s", input.RepositoryFolder) providers := []providerConfig{} + providersV1_2 := []providerConfig{} for _, provider := range input.E2EConfig.Providers { providerLabel := clusterctlv1.ManifestLabel(provider.Name, clusterctlv1.ProviderType(provider.Type)) providerURL := filepath.Join(input.RepositoryFolder, providerLabel, "latest", "components.yaml") @@ -110,11 +115,15 @@ func CreateRepository(ctx context.Context, input CreateRepositoryInput) string { Expect(os.WriteFile(destinationFile, data, 0600)).To(Succeed(), "Failed to write clusterctl local repository file %q / %q", provider.Name, file.TargetName) } } - providers = append(providers, providerConfig{ + p := providerConfig{ Name: provider.Name, URL: providerURL, Type: provider.Type, - }) + } + providers = append(providers, p) + if !(clusterctlv1.ProviderType(provider.Type) == clusterctlv1.IPAMProviderType || clusterctlv1.ProviderType(provider.Type) == clusterctlv1.RuntimeExtensionProviderType) { + providersV1_2 = append(providersV1_2, p) + } } // set this path to an empty file under the repository path, so test can run in isolation without user's overrides kicking in @@ -123,7 +132,7 @@ func CreateRepository(ctx context.Context, input CreateRepositoryInput) string { // creates a clusterctl config file to be used for working with such repository clusterctlConfigFile := &clusterctlConfig{ - Path: filepath.Join(input.RepositoryFolder, "clusterctl-config.yaml"), + Path: filepath.Join(input.RepositoryFolder, clusterctlConfigFileName), Values: map[string]interface{}{ "providers": providers, "overridesFolder": overridePath, @@ -134,9 +143,44 @@ func CreateRepository(ctx context.Context, input CreateRepositoryInput) string { } clusterctlConfigFile.write() + // creates a clusterctl config file to be used for working with such repository with only the providers supported in clusterctl < v1.3 + clusterctlConfigFileV1_2 := &clusterctlConfig{ + Path: filepath.Join(input.RepositoryFolder, clusterctlConfigV1_2FileName), + Values: map[string]interface{}{ + "providers": providersV1_2, + "overridesFolder": overridePath, + }, + } + for key := range input.E2EConfig.Variables { + clusterctlConfigFileV1_2.Values[key] = input.E2EConfig.GetVariable(key) + } + clusterctlConfigFileV1_2.write() + return clusterctlConfigFile.Path } +// AdjustConfigPathForBinary adjusts the clusterctlConfigPath in case the clusterctl version v1.3. +func AdjustConfigPathForBinary(clusterctPath, clusterctlConfigPath string) string { + clusterctl := exec.NewCommand( + exec.WithCommand(clusterctPath), + exec.WithArgs("version", "--output", "short"), + ) + stdout, stderr, err := clusterctl.Run(context.Background()) + if err != nil { + Expect(err).ToNot(HaveOccurred(), "failed to run clusterctl version:\nstdout:\n%s\nstderr:\n%s", string(stdout), stderr) + } + data := stdout + version, err := semver.ParseTolerant(string(data)) + if err != nil { + Expect(err).ToNot(HaveOccurred(), "clusterctl version returned an invalid version: %s (%v)", string(data), err) + } + + if version.LT(semver.MustParse("1.3.0")) { + return strings.Replace(clusterctlConfigPath, clusterctlConfigFileName, clusterctlConfigV1_2FileName, -1) + } + return clusterctlConfigPath +} + // YAMLForComponentSource returns the YAML for the provided component source. func YAMLForComponentSource(ctx context.Context, source ProviderVersionSource) ([]byte, error) { var data []byte