From 99a2c65be97c13ee2fcfd97fa9257d55bfc450df Mon Sep 17 00:00:00 2001 From: kerimov Date: Tue, 14 Oct 2025 19:27:05 +0300 Subject: [PATCH 1/2] [deckhouse-cli] handle non-existing release channels Signed-off-by: kerimov --- internal/mirror/releases/versions.go | 40 +++++++++++++++++++--------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/internal/mirror/releases/versions.go b/internal/mirror/releases/versions.go index c9418f5e..08a56232 100644 --- a/internal/mirror/releases/versions.go +++ b/internal/mirror/releases/versions.go @@ -33,17 +33,25 @@ import ( ) func VersionsToMirror(pullParams *params.PullParams) ([]semver.Version, error) { - releaseChannelsToCopy := []string{"alpha", "beta", "early-access", "stable", "rock-solid", "lts"} - releaseChannelsVersions := make([]*semver.Version, len(releaseChannelsToCopy)) - for i, channel := range releaseChannelsToCopy { + allChannels := []string{"alpha", "beta", "early-access", "stable", "rock-solid", "lts"} + channelVersions := make(map[string]*semver.Version) + + // Collect available channel versions + for _, channel := range allChannels { v, err := getReleaseChannelVersionFromRegistry(pullParams, channel) if err != nil { return nil, fmt.Errorf("get %s release version from registry: %w", channel, err) } - releaseChannelsVersions[i] = v + if v != nil { + channelVersions[channel] = v + } } - rockSolidVersion := releaseChannelsVersions[len(releaseChannelsToCopy)-1] + // Direct access to required versions + rockSolidVersion := channelVersions["rock-solid"] + if rockSolidVersion == nil { + return nil, fmt.Errorf("rock-solid channel is required but not available") + } mirrorFromVersion := *rockSolidVersion if pullParams.SinceVersion != nil { mirrorFromVersion = *pullParams.SinceVersion @@ -57,17 +65,21 @@ func VersionsToMirror(pullParams *params.PullParams) ([]semver.Version, error) { return nil, fmt.Errorf("get releases from github: %w", err) } - alphaChannelVersion := releaseChannelsVersions[0] - for i := range releaseChannelsToCopy { - if releaseChannelsToCopy[i] == "alpha" { - alphaChannelVersion = releaseChannelsVersions[i] - break - } + // Direct access to alpha version + alphaChannelVersion := channelVersions["alpha"] + if alphaChannelVersion == nil { + return nil, fmt.Errorf("alpha channel is required but not available") } versionsAboveMinimal := parseAndFilterVersionsAboveMinimalAnbBelowAlpha(&mirrorFromVersion, tags, alphaChannelVersion) versionsAboveMinimal = FilterOnlyLatestPatches(versionsAboveMinimal) - return deduplicateVersions(append(releaseChannelsVersions, versionsAboveMinimal...)), nil + // Convert map values to slice for deduplication + var versions []*semver.Version + for _, v := range channelVersions { + versions = append(versions, v) + } + + return deduplicateVersions(append(versions, versionsAboveMinimal...)), nil } func getReleasedTagsFromRegistry(pullParams *params.PullParams) ([]string, error) { @@ -130,6 +142,10 @@ func getReleaseChannelVersionFromRegistry(mirrorCtx *params.PullParams, releaseC rockSolidReleaseImage, err := remote.Image(ref, remoteOpts...) if err != nil { + // If release channel doesn't exist, don't return an error + if errorutil.IsImageNotFoundError(err) { + return nil, nil + } return nil, fmt.Errorf("get %s release channel data: %w", releaseChannel, err) } From 4266b7b749b8189008a4c12cecb4cbc8c4829ae4 Mon Sep 17 00:00:00 2001 From: kerimov Date: Mon, 20 Oct 2025 14:05:30 +0300 Subject: [PATCH 2/2] [deckhouse-cli] handle non-known release channels Signed-off-by: kerimov --- internal/mirror/releases/versions.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/internal/mirror/releases/versions.go b/internal/mirror/releases/versions.go index 08a56232..548678b3 100644 --- a/internal/mirror/releases/versions.go +++ b/internal/mirror/releases/versions.go @@ -19,6 +19,7 @@ package releases import ( "encoding/json" "fmt" + "slices" "github.com/Masterminds/semver/v3" "github.com/google/go-containerregistry/pkg/authn" @@ -32,8 +33,10 @@ import ( "github.com/deckhouse/deckhouse-cli/pkg/libmirror/util/errorutil" ) +// allKnownChannels contains all officially supported release channels +var allChannels = []string{"alpha", "beta", "early-access", "stable", "rock-solid", "lts"} + func VersionsToMirror(pullParams *params.PullParams) ([]semver.Version, error) { - allChannels := []string{"alpha", "beta", "early-access", "stable", "rock-solid", "lts"} channelVersions := make(map[string]*semver.Version) // Collect available channel versions @@ -78,7 +81,7 @@ func VersionsToMirror(pullParams *params.PullParams) ([]semver.Version, error) { for _, v := range channelVersions { versions = append(versions, v) } - + return deduplicateVersions(append(versions, versionsAboveMinimal...)), nil } @@ -131,6 +134,10 @@ func FilterOnlyLatestPatches(versions []*semver.Version) []*semver.Version { return topPatches } +func isReleaseChannel(channel string) bool { + return slices.Contains(allChannels, channel) +} + func getReleaseChannelVersionFromRegistry(mirrorCtx *params.PullParams, releaseChannel string) (*semver.Version, error) { nameOpts, remoteOpts := auth.MakeRemoteRegistryRequestOptionsFromMirrorParams(&mirrorCtx.BaseParams) nameOpts = append(nameOpts, name.StrictValidation) @@ -142,8 +149,8 @@ func getReleaseChannelVersionFromRegistry(mirrorCtx *params.PullParams, releaseC rockSolidReleaseImage, err := remote.Image(ref, remoteOpts...) if err != nil { - // If release channel doesn't exist, don't return an error - if errorutil.IsImageNotFoundError(err) { + // If release channel doesn't exist, only ignore for known channels + if errorutil.IsImageNotFoundError(err) && isReleaseChannel(releaseChannel) { return nil, nil } return nil, fmt.Errorf("get %s release channel data: %w", releaseChannel, err)