Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ linters:
# for github.com/sapcc/keppel et al
- github.com/go-gorp/gorp/v3
toolchain-forbidden: true
go-version-pattern: 1\.\d+(\.0)?$
go-version-pattern: 1\.\d+(\.\d+)?$
gosec:
excludes:
# gosec wants us to set a short ReadHeaderTimeout to avoid Slowloris attacks, but doing so would expose us to Keep-Alive race conditions (see https://iximiuz.com/en/posts/reverse-proxy-http-keep-alive-and-502s/
Expand Down
43 changes: 36 additions & 7 deletions cloudprofilesync/imageupdater.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ import (
func filterImages(log logr.Logger, versions []SourceImage) []SourceImage {
filtered := make([]SourceImage, 0, len(versions))
for _, version := range versions {
_, err := semver.Parse(version.Version)
versionStr := version.effectiveVersion()
_, err := semver.Parse(versionStr)
if err != nil {
log.V(1).Info("skipping invalid version", "version", version.Version)
log.V(1).Info("skipping invalid version", "version", versionStr)
continue
}
if len(version.Architectures) == 0 {
log.V(1).Info("skipping version with no architectures", "version", version.Version)
log.V(1).Info("skipping version with no architectures", "version", versionStr)
continue
}
filtered = append(filtered, version)
Expand All @@ -32,10 +33,11 @@ func filterImages(log logr.Logger, versions []SourceImage) []SourceImage {
}

type ImageUpdater struct {
Log logr.Logger
Source Source
Provider Provider
ImageName string
Log logr.Logger
Source Source
Provider Provider
ImageName string
EnableCapabilities bool
}

func (iu *ImageUpdater) Update(ctx context.Context, cpSpec *gardenerv1beta1.CloudProfileSpec) error {
Expand All @@ -48,6 +50,9 @@ func (iu *ImageUpdater) Update(ctx context.Context, cpSpec *gardenerv1beta1.Clou
// in the source images may lead to a changed order in the CloudProfile,
// causing unnecesscary reconciliations.
slices.SortFunc(sourceImages, func(a, b SourceImage) int {
if c := cmp.Compare(a.effectiveVersion(), b.effectiveVersion()); c != 0 {
return c
}
return cmp.Compare(a.Version, b.Version)
})
imageIndex := slices.IndexFunc(cpSpec.MachineImages, func(img gardenerv1beta1.MachineImage) bool {
Expand All @@ -62,7 +67,9 @@ func (iu *ImageUpdater) Update(ctx context.Context, cpSpec *gardenerv1beta1.Clou
for idx, version := range image.Versions {
existingVersions[version.Version] = idx
}

for _, sourceImage := range sourceImages {
// Always write the full tag version (legacy path, safe for running Shoots).
if idx, exists := existingVersions[sourceImage.Version]; exists {
image.Versions[idx].Architectures = sourceImage.Architectures
} else {
Expand All @@ -72,8 +79,30 @@ func (iu *ImageUpdater) Update(ctx context.Context, cpSpec *gardenerv1beta1.Clou
},
Architectures: sourceImage.Architectures,
})
existingVersions[sourceImage.Version] = len(image.Versions) - 1
}

// When capabilities are enabled, also write the clean version entry.
if iu.EnableCapabilities && sourceImage.CleanVersion != "" && sourceImage.CleanVersion != sourceImage.Version {
if idx, exists := existingVersions[sourceImage.CleanVersion]; exists {
existing := &image.Versions[idx]
for _, arch := range sourceImage.Architectures {
if !slices.Contains(existing.Architectures, arch) {
existing.Architectures = append(existing.Architectures, arch)
}
}
} else {
image.Versions = append(image.Versions, gardenerv1beta1.MachineImageVersion{
ExpirableVersion: gardenerv1beta1.ExpirableVersion{
Version: sourceImage.CleanVersion,
},
Architectures: slices.Clone(sourceImage.Architectures),
})
existingVersions[sourceImage.CleanVersion] = len(image.Versions) - 1
}
}
}

if iu.Provider != nil {
if err := iu.Provider.Configure(cpSpec, sourceImages); err != nil {
return fmt.Errorf("failed to invoke provider: %w", err)
Expand Down
Loading
Loading