diff --git a/internal/compatibility/compatibility.go b/internal/compatibility/compatibility.go index e089a7ddd..6340a967b 100644 --- a/internal/compatibility/compatibility.go +++ b/internal/compatibility/compatibility.go @@ -50,6 +50,17 @@ func (e *InvalidUpgradeError) Error() string { return fmt.Sprintf("upgrading from %s to %s is not a valid upgrade: %s", e.from, e.to, e.innerErr) } +// UnnecessaryUpgradeError is returned if both versions are the same. +type UnnecessaryUpgradeError struct { + from string + to string +} + +// Error returns the String representation of this error. +func (e *UnnecessaryUpgradeError) Error() string { + return fmt.Sprintf("no upgrade required from %s to %s", e.from, e.to) +} + // EnsurePrefixV returns the input string prefixed with the letter "v", if the string doesn't already start with that letter. func EnsurePrefixV(str string) string { if strings.HasPrefix(str, "v") { @@ -67,7 +78,11 @@ func IsValidUpgrade(a, b string) error { return NewInvalidUpgradeError(a, b, ErrSemVer) } - if semver.Compare(a, b) >= 0 { + if semver.Compare(a, b) == 0 { + return &UnnecessaryUpgradeError{a, b} + } + + if semver.Compare(a, b) > 0 { return NewInvalidUpgradeError(a, b, errors.New("current version newer than or equal to new version")) } diff --git a/internal/constellation/helm/actionfactory.go b/internal/constellation/helm/actionfactory.go index 67ca3ab34..81e44906a 100644 --- a/internal/constellation/helm/actionfactory.go +++ b/internal/constellation/helm/actionfactory.go @@ -100,6 +100,11 @@ func (a actionFactory) appendNewAction( a.log.Debug(fmt.Sprintf("Current %q version: %q", release.releaseName, currentVersion)) a.log.Debug(fmt.Sprintf("New %q version: %q", release.releaseName, newVersion)) + if currentVersion.Compare(newVersion) == 0 { + // Nothing to do. + return nil + } + if !force { // For charts we package ourselves, the version is equal to the CLI version (charts are embedded in the binary). // We need to make sure this matches with the version in a user's config, if an upgrade should be applied. diff --git a/internal/constellation/kubecmd/kubecmd.go b/internal/constellation/kubecmd/kubecmd.go index 1ebf99265..1daeab017 100644 --- a/internal/constellation/kubecmd/kubecmd.go +++ b/internal/constellation/kubecmd/kubecmd.go @@ -138,12 +138,21 @@ func (k *KubeCmd) UpgradeKubernetesVersion(ctx context.Context, kubernetesVersio )) } components, err := k.prepareUpdateK8s(&nodeVersion, versionConfig.ClusterVersion, versionConfig.KubernetesComponents, force) - if err != nil { - return err - } - if err := k.applyComponentsCM(ctx, components); err != nil { - return fmt.Errorf("applying k8s components ConfigMap: %w", err) + var invalidUpgradeErr *compatibility.InvalidUpgradeError + var unnecessaryUpgradeErr *compatibility.UnnecessaryUpgradeError + switch { + case err == nil: + err := k.applyComponentsCM(ctx, components) + if err != nil { + return fmt.Errorf("applying k8s components ConfigMap: %w", err) + } + case errors.As(err, &unnecessaryUpgradeErr): + return nil + case errors.As(err, &invalidUpgradeErr): + return fmt.Errorf("skipping Kubernetes upgrade: %w", err) + default: + return fmt.Errorf("updating Kubernetes version: %w", err) } updatedNodeVersion, err := k.applyNodeVersion(ctx, nodeVersion)