Skip to content

Commit

Permalink
Find current Kubernetes versions for e2e testing
Browse files Browse the repository at this point in the history
  • Loading branch information
mboersma committed Jun 16, 2022
1 parent 23ebb58 commit 95ad291
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 28 deletions.
10 changes: 5 additions & 5 deletions azure/services/virtualmachineimages/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,18 +89,18 @@ 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)
if err != nil {
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{
Expand Down
56 changes: 33 additions & 23 deletions test/e2e/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand All @@ -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)
Expand Down

0 comments on commit 95ad291

Please sign in to comment.