From 95ad2917099b4b7c72e429b308de8261820fc232 Mon Sep 17 00:00:00 2001 From: Matt Boersma Date: Wed, 15 Jun 2022 13:42:15 -0600 Subject: [PATCH] Find current Kubernetes versions for e2e testing --- azure/services/virtualmachineimages/images.go | 10 ++-- test/e2e/helpers.go | 56 +++++++++++-------- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/azure/services/virtualmachineimages/images.go b/azure/services/virtualmachineimages/images.go index bd88849c9698..c6edfdef0173 100644 --- a/azure/services/virtualmachineimages/images.go +++ b/azure/services/virtualmachineimages/images.go @@ -89,6 +89,11 @@ func (s *Service) GetDefaultWindowsImage(ctx context.Context, location, k8sVersi osAndVersion = azure.DefaultWindowsOsAndVersion } + // Starting with 1.22 we default to containerd for Windows unless the runtime flag is set. + if v.GE(v122) && runtime != "dockershim" && !strings.HasSuffix(osAndVersion, "-containerd") { + osAndVersion += "-containerd" + } + publisher, offer := azure.DefaultImagePublisherID, azure.DefaultWindowsImageOfferID skuID, version, err := s.getDefaultImageSKUIDAndVersion( ctx, location, publisher, offer, k8sVersion, osAndVersion) @@ -96,11 +101,6 @@ func (s *Service) GetDefaultWindowsImage(ctx context.Context, location, k8sVersi return nil, errors.Wrap(err, "failed to get default image") } - // Starting with 1.22 we default to containerd for Windows unless the runtime flag is set. - if v.GTE(v122) && runtime != "dockershim" { - skuID += "-containerd" - } - defaultImage := &infrav1.Image{ Marketplace: &infrav1.AzureMarketplaceImage{ ImagePlan: infrav1.ImagePlan{ diff --git a/test/e2e/helpers.go b/test/e2e/helpers.go index 6b8bb0b9d893..fb99fdf40bb0 100644 --- a/test/e2e/helpers.go +++ b/test/e2e/helpers.go @@ -714,11 +714,8 @@ func resolveKubetestRepoListPath(version string, path string) (string, error) { // resolveKubernetesVersions looks at Kubernetes versions set as variables in the e2e config and sets them to a valid k8s version // that has an existing capi offer image available. For example, if the version is "stable-1.22", the function will set it to the latest 1.22 version that has a published reference image. func resolveKubernetesVersions(config *clusterctl.E2EConfig) { - ubuntuSkus := getImageSkusInOffer(context.TODO(), os.Getenv(AzureLocation), capiImagePublisher, capiOfferName) - ubuntuVersions := parseImageSkuNames(ubuntuSkus) - - windowsSkus := getImageSkusInOffer(context.TODO(), os.Getenv(AzureLocation), capiImagePublisher, capiWindowsOfferName) - windowsVersions := parseImageSkuNames(windowsSkus) + ubuntuVersions := getVersionsInOffer(context.TODO(), os.Getenv(AzureLocation), capiImagePublisher, capiOfferName) + windowsVersions := getVersionsInOffer(context.TODO(), os.Getenv(AzureLocation), capiImagePublisher, capiWindowsOfferName) // find the intersection of ubuntu and windows versions available, since we need an image for both. var versions semver.Versions @@ -747,8 +744,8 @@ func resolveKubernetesVersion(config *clusterctl.E2EConfig, versions semver.Vers config.Variables[varName] = v } -// getImageSkusInOffer returns all skus for an offer that have at least one image. -func getImageSkusInOffer(ctx context.Context, location, publisher, offer string) []string { +// newImagesClient returns a new VM images client using environmental settings for auth. +func newImagesClient() compute.VirtualMachineImagesClient { settings, err := auth.GetSettingsFromEnvironment() Expect(err).NotTo(HaveOccurred()) subscriptionID := settings.GetSubscriptionID() @@ -757,34 +754,47 @@ func getImageSkusInOffer(ctx context.Context, location, publisher, offer string) imagesClient := compute.NewVirtualMachineImagesClient(subscriptionID) imagesClient.Authorizer = authorizer - Byf("Finding image skus for offer %s/%s in %s", publisher, offer, location) + return imagesClient +} - res, err := imagesClient.ListSkus(ctx, location, publisher, offer) +// getVersionsInOffer returns a map of Kubernetes versions as strings to semver.Versions. +func getVersionsInOffer(ctx context.Context, location, publisher, offer string) map[string]semver.Version { + Byf("Finding image skus and versions for offer %s/%s in %s", publisher, offer, location) + imagesClient := newImagesClient() + skusList, err := imagesClient.ListSkus(ctx, location, publisher, offer) Expect(err).NotTo(HaveOccurred()) - var skus []string - if res.Value != nil { - skus = make([]string, len(*res.Value)) - for i, sku := range *res.Value { - // we have to do this to make sure the SKU has existing images - // see https://github.com/Azure/azure-cli/issues/20115. + var skus map[string]*compute.ListVirtualMachineImageResource + if skusList.Value != nil { + skus = make(map[string]*compute.ListVirtualMachineImageResource, len(*skusList.Value)) + for _, sku := range *skusList.Value { res, err := imagesClient.List(ctx, location, publisher, offer, *sku.Name, "", nil, "") Expect(err).NotTo(HaveOccurred()) + // Don't use SKUs without existing images. See https://github.com/Azure/azure-cli/issues/20115. if res.Value != nil && len(*res.Value) > 0 { - skus[i] = *sku.Name + skus[*sku.Name] = &res } } } - return skus -} -// parseImageSkuNames parses SKU names in format "k8s-1dot17dot2-os-123" to extract the Kubernetes version. -// it returns a sorted list of all k8s versions found. -func parseImageSkuNames(skus []string) map[string]semver.Version { - capiSku := regexp.MustCompile(`^k8s-(0|[1-9][0-9]*)dot(0|[1-9][0-9]*)dot(0|[1-9][0-9]*)-[a-z]*.*$`) + capiSku := regexp.MustCompile(`^[\w-]+-gen[12]$`) + capiVersion := regexp.MustCompile(`^(\d)(\d{1,2})\.(\d{1,2})\.\d{8}$`) + oldCapiSku := regexp.MustCompile(`^k8s-(0|[1-9][0-9]*)dot(0|[1-9][0-9]*)dot(0|[1-9][0-9]*)-[a-z]*.*$`) versions := make(map[string]semver.Version, len(skus)) - for _, sku := range skus { + for sku, res := range skus { + // New SKUs don't contain the Kubernetes version and are named like "ubuntu-2004-gen1". match := capiSku.FindStringSubmatch(sku) + if len(match) != 0 { + for _, vmImage := range *res.Value { + // Versions are named like "121.13.20220601", for Kubernetes v1.21.13 published on June 1, 2022. + match = capiVersion.FindStringSubmatch(*vmImage.Name) + stringVer := fmt.Sprintf("%s.%s.%s", match[1], match[2], match[3]) + versions[stringVer] = semver.MustParse(stringVer) + } + continue + } + // Old SKUs before 1.21.12, 1.22.9, or 1.23.6 are named like "k8s-1dot21dot2-ubuntu-2004". + match = oldCapiSku.FindStringSubmatch(sku) if len(match) != 0 { stringVer := fmt.Sprintf("%s.%s.%s", match[1], match[2], match[3]) versions[stringVer] = semver.MustParse(stringVer)