Skip to content

Commit

Permalink
Look up CI versions via Community gallery too
Browse files Browse the repository at this point in the history
  • Loading branch information
mboersma committed Oct 8, 2024
1 parent e2792e3 commit d66f4df
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 57 deletions.
19 changes: 17 additions & 2 deletions azure/services/virtualmachineimages/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (

infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
"sigs.k8s.io/cluster-api-provider-azure/azure"
"sigs.k8s.io/cluster-api-provider-azure/util/tele"
)

// Service provides operations on Azure VM Images.
Expand All @@ -45,7 +46,10 @@ func New(auth azure.Authorizer) (*Service, error) {
}

// GetDefaultUbuntuImage returns the default image spec for Ubuntu.
func (s *Service) GetDefaultUbuntuImage(ctx context.Context, location, k8sVersion string) (*infrav1.Image, error) {
func (s *Service) GetDefaultUbuntuImage(ctx context.Context, _, k8sVersion string) (*infrav1.Image, error) {
_, _, done := tele.StartSpanWithLogger(ctx, "azure.services.virtualmachineimages.GetDefaultUbuntuImage")
defer done()

v, err := semver.ParseTolerant(k8sVersion)
if err != nil {
return nil, errors.Wrapf(err, "unable to parse Kubernetes version \"%s\"", k8sVersion)
Expand All @@ -63,12 +67,23 @@ func (s *Service) GetDefaultUbuntuImage(ctx context.Context, location, k8sVersio
}

// GetDefaultWindowsImage returns the default image spec for Windows.
func (s *Service) GetDefaultWindowsImage(ctx context.Context, location, k8sVersion, runtime, osAndVersion string) (*infrav1.Image, error) {
func (s *Service) GetDefaultWindowsImage(ctx context.Context, _, k8sVersion, runtime, osAndVersion string) (*infrav1.Image, error) {
_, _, done := tele.StartSpanWithLogger(ctx, "azure.services.virtualmachineimages.GetDefaultWindowsImage")
defer done()

v, err := semver.ParseTolerant(k8sVersion)
if err != nil {
return nil, errors.Wrapf(err, "unable to parse Kubernetes version \"%s\"", k8sVersion)
}

if runtime != "" && runtime != "containerd" {
return nil, errors.Errorf("unsupported runtime %s", runtime)
}

if osAndVersion != "" && osAndVersion != "windows-2022" {
return nil, errors.Errorf("unsupported osAndVersion %s", osAndVersion)
}

defaultImage := &infrav1.Image{
ComputeGallery: &infrav1.AzureComputeGalleryImage{
Gallery: azure.DefaultPublicGalleryName,
Expand Down
9 changes: 0 additions & 9 deletions azure/services/virtualmachineimages/images_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -581,17 +581,8 @@ func TestGetDefaultImageSKUID(t *testing.T) {
List(gomock.Any(), location, azure.DefaultPublicGalleryName, azure.DefaultLinuxGalleryImageName).
Return(test.versions, nil)
}
// id, version, err := svc.getSKUAndVersion(context.TODO(), location, azure.DefaultImagePublisherID,
// offer, test.k8sVersion, test.osAndVersion)

g := NewWithT(t)
// if test.expectedError {
// g.Expect(err).To(HaveOccurred())
// } else {
// g.Expect(err).NotTo(HaveOccurred())
// }
// g.Expect(id).To(Equal(test.expectedSKU))
// g.Expect(version).To(Equal(test.expectedVersion))

// TODO: temp hack
g.Expect(svc).NotTo(BeNil())
Expand Down
2 changes: 1 addition & 1 deletion hack/create-dev-cluster.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export CONTROL_PLANE_MACHINE_COUNT=${CONTROL_PLANE_MACHINE_COUNT:-3}
export AZURE_CONTROL_PLANE_MACHINE_TYPE="${CONTROL_PLANE_MACHINE_TYPE:-Standard_B2s}"
export AZURE_NODE_MACHINE_TYPE="${NODE_MACHINE_TYPE:-Standard_B2s}"
export WORKER_MACHINE_COUNT=${WORKER_MACHINE_COUNT:-2}
export KUBERNETES_VERSION="${KUBERNETES_VERSION:-v1.29.5}"
export KUBERNETES_VERSION="${KUBERNETES_VERSION:-v1.29.9}"
export CLUSTER_TEMPLATE="${CLUSTER_TEMPLATE:-cluster-template.yaml}"

# identity secret settings.
Expand Down
1 change: 1 addition & 0 deletions test/e2e/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ const (
capiImagePublisher = "cncf-upstream"
capiOfferName = "capi"
capiWindowsOfferName = "capi-windows"
capiCommunityGallery = "capzed-489de9a5-a0a0-4e79-a806-ad5479ec43a5"
aksClusterNameSuffix = "aks"
flatcarCAPICommunityGallery = "flatcar4capi-742ef0cb-dcaa-4ecb-9cb0-bfd2e43dccc0"
defaultNamespace = "default"
Expand Down
56 changes: 11 additions & 45 deletions test/e2e/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -699,13 +699,13 @@ 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) {
ubuntuVersions := getVersionsInOffer(context.TODO(), os.Getenv(AzureLocation), capiImagePublisher, capiOfferName)
windowsVersions := getVersionsInOffer(context.TODO(), os.Getenv(AzureLocation), capiImagePublisher, capiWindowsOfferName)
linuxVersions := getVersionsInCommunityGallery(context.TODO(), os.Getenv(AzureLocation), capiCommunityGallery, "capi-ubun2-2404")
windowsVersions := getVersionsInCommunityGallery(context.TODO(), os.Getenv(AzureLocation), capiCommunityGallery, "capi-win-2022-containerd")
flatcarK8sVersions := getFlatcarK8sVersions(context.TODO(), os.Getenv(AzureLocation), flatcarCAPICommunityGallery)

// find the intersection of ubuntu and windows versions available, since we need an image for both.
var versions semver.Versions
for k, v := range ubuntuVersions {
for k, v := range linuxVersions {
if _, ok := windowsVersions[k]; ok {
versions = append(versions, v)
}
Expand Down Expand Up @@ -758,16 +758,6 @@ func resolveFlatcarVersion(config *clusterctl.E2EConfig, versions semver.Version
resolveVariable(config, varName, version)
}

// newImagesClient returns a new VM images client using environmental settings for auth.
func newImagesClient() *armcompute.VirtualMachineImagesClient {
cred, err := azidentity.NewDefaultAzureCredential(nil)
Expect(err).NotTo(HaveOccurred())
imagesClient, err := armcompute.NewVirtualMachineImagesClient(getSubscriptionID(Default), cred, nil)
Expect(err).NotTo(HaveOccurred())

return imagesClient
}

func newCommunityGalleryImagesClient() *armcompute.CommunityGalleryImagesClient {
cred, err := azidentity.NewDefaultAzureCredential(nil)
Expect(err).NotTo(HaveOccurred())
Expand All @@ -786,40 +776,16 @@ func newCommunityGalleryImageVersionsClient() *armcompute.CommunityGalleryImageV
return communityGalleryImageVersionsClient
}

// 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 {
Logf("Finding image skus and versions for offer %s/%s in %s", publisher, offer, location)
var versions map[string]semver.Version
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]*.*$`)
imagesClient := newImagesClient()
resp, err := imagesClient.ListSKUs(ctx, location, publisher, offer, nil)
Expect(err).NotTo(HaveOccurred())

skus := resp.VirtualMachineImageResourceArray
func getVersionsInCommunityGallery(ctx context.Context, location, galleryName, image string) map[string]semver.Version {
versions := make(map[string]semver.Version)

versions = make(map[string]semver.Version, len(skus))
for _, sku := range skus {
res, err := imagesClient.List(ctx, location, publisher, offer, *sku.Name, nil)
client := newCommunityGalleryImageVersionsClient()
pager := client.NewListPager(location, galleryName, image, nil)
for pager.More() {
resp, err := pager.NextPage(ctx)
Expect(err).NotTo(HaveOccurred())
// Don't use SKUs without existing images. See https://github.com/Azure/azure-cli/issues/20115.
if len(res.VirtualMachineImageResourceArray) > 0 {
// New SKUs don't contain the Kubernetes version and are named like "ubuntu-2004-gen1".
if match := capiSku.FindStringSubmatch(*sku.Name); len(match) > 0 {
for _, vmImage := range res.VirtualMachineImageResourceArray {
// 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".
if match := oldCapiSku.FindStringSubmatch(*sku.Name); len(match) > 0 {
stringVer := fmt.Sprintf("%s.%s.%s", match[1], match[2], match[3])
versions[stringVer] = semver.MustParse(stringVer)
}
for _, version := range resp.Value {
versions[*version.Name] = semver.MustParse(*version.Name)
}
}

Expand Down

0 comments on commit d66f4df

Please sign in to comment.