@@ -16,6 +16,7 @@ import (
1616 "github.com/replicatedhq/embedded-cluster/cmd/installer/goods"
1717 "github.com/replicatedhq/embedded-cluster/cmd/installer/kotscli"
1818 ecv1beta1 "github.com/replicatedhq/embedded-cluster/kinds/apis/v1beta1"
19+ "github.com/replicatedhq/embedded-cluster/pkg-new/replicatedapi"
1920 "github.com/replicatedhq/embedded-cluster/pkg/airgap"
2021 "github.com/replicatedhq/embedded-cluster/pkg/helpers"
2122 "github.com/replicatedhq/embedded-cluster/pkg/kubeutils"
@@ -24,6 +25,7 @@ import (
2425 "github.com/replicatedhq/embedded-cluster/pkg/release"
2526 "github.com/replicatedhq/embedded-cluster/pkg/runtimeconfig"
2627 rcutil "github.com/replicatedhq/embedded-cluster/pkg/runtimeconfig/util"
28+ "github.com/replicatedhq/embedded-cluster/pkg/validation"
2729 "github.com/replicatedhq/embedded-cluster/pkg/versions"
2830 "github.com/replicatedhq/embedded-cluster/web"
2931 kotsv1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1"
@@ -59,6 +61,8 @@ type upgradeConfig struct {
5961 managerPort int
6062 requiresInfraUpgrade bool
6163 kotsadmNamespace string
64+ currentAppVersion * kotscli.AppVersionInfo
65+ replicatedAPIClient replicatedapi.Client
6266}
6367
6468// UpgradeCmd returns a cobra command for upgrading the embedded cluster application.
@@ -110,7 +114,7 @@ func UpgradeCmd(ctx context.Context, appSlug, appTitle string) *cobra.Command {
110114 if err := preRunUpgrade (ctx , flags , & upgradeConfig , existingRC , kcli , appSlug ); err != nil {
111115 return err
112116 }
113- if err := verifyAndPromptUpgrade (ctx , flags , upgradeConfig , prompts .New ()); err != nil {
117+ if err := verifyAndPromptUpgrade (ctx , flags , upgradeConfig , prompts .New (), kcli , appSlug ); err != nil {
114118 return err
115119 }
116120
@@ -267,6 +271,7 @@ func preRunUpgrade(ctx context.Context, flags UpgradeCmdFlags, upgradeConfig *up
267271 }
268272 upgradeConfig .license = updatedLicense
269273 upgradeConfig .licenseBytes = licenseBytes
274+ upgradeConfig .replicatedAPIClient = replicatedAPI
270275 }
271276
272277 // Continue using "kotsadm" namespace if it exists for backwards compatibility, otherwise use the appSlug
@@ -337,10 +342,17 @@ func preRunUpgrade(ctx context.Context, flags UpgradeCmdFlags, upgradeConfig *up
337342 }
338343 upgradeConfig .requiresInfraUpgrade = requiresInfraUpgrade
339344
345+ // Get current app version for deployability validation
346+ currentAppVersion , err := kotscli .GetCurrentAppVersion (appSlug , upgradeConfig .kotsadmNamespace )
347+ if err != nil {
348+ return fmt .Errorf ("failed to get current app version: %w" , err )
349+ }
350+ upgradeConfig .currentAppVersion = currentAppVersion
351+
340352 return nil
341353}
342354
343- func verifyAndPromptUpgrade (ctx context.Context , flags UpgradeCmdFlags , upgradeConfig upgradeConfig , prompt prompts.Prompt ) error {
355+ func verifyAndPromptUpgrade (ctx context.Context , flags UpgradeCmdFlags , upgradeConfig upgradeConfig , prompt prompts.Prompt , kcli client. Client , appSlug string ) error {
344356 isAirgap := flags .airgapBundle != ""
345357
346358 err := verifyChannelRelease ("upgrade" , isAirgap , flags .assumeYes )
@@ -355,6 +367,11 @@ func verifyAndPromptUpgrade(ctx context.Context, flags UpgradeCmdFlags, upgradeC
355367 }
356368 }
357369
370+ // Validate release deployability
371+ if err := validateReleaseDeployability (ctx , upgradeConfig , kcli , appSlug , isAirgap ); err != nil {
372+ return fmt .Errorf ("upgrade validation failed: %w" , err )
373+ }
374+
358375 if ! isAirgap {
359376 if err := maybePromptForAppUpdate (ctx , prompt , upgradeConfig .license , flags .assumeYes ); err != nil {
360377 if errors .As (err , & ErrorNothingElseToAdd {}) {
@@ -543,3 +560,64 @@ func checkRequiresInfraUpgrade(ctx context.Context) (bool, error) {
543560
544561 return ! bytes .Equal (currentJSON , targetJSON ), nil
545562}
563+
564+ // validateReleaseDeployability validates that the target release can be safely deployed
565+ func validateReleaseDeployability (ctx context.Context , upgradeConfig upgradeConfig , kcli client.Client , appSlug string , isAirgap bool ) error {
566+ // Get current installation for version information
567+ currentInstallation , err := kubeutils .GetLatestInstallation (ctx , kcli )
568+ if err != nil {
569+ return fmt .Errorf ("get current installation: %w" , err )
570+ }
571+
572+ // Get target release data
573+ releaseData := release .GetReleaseData ()
574+ if releaseData == nil {
575+ return fmt .Errorf ("release data not found" )
576+ }
577+
578+ // Get channel release info
579+ channelRelease := releaseData .ChannelRelease
580+ if channelRelease == nil {
581+ return fmt .Errorf ("channel release not found in release data" )
582+ }
583+
584+ // Get current and target EC/K8s versions
585+ var currentECVersion string
586+ if currentInstallation .Spec .Config != nil {
587+ currentECVersion = currentInstallation .Spec .Config .Version
588+ }
589+
590+ targetECVersion := versions .Version
591+
592+ // Build validation options
593+ opts := validation.UpgradableOptions {
594+ IsAirgap : isAirgap ,
595+ CurrentECVersion : currentECVersion ,
596+ TargetECVersion : targetECVersion ,
597+ License : upgradeConfig .license ,
598+ AirgapMetadata : upgradeConfig .airgapMetadata ,
599+ }
600+
601+ // Add current app version info if available
602+ if upgradeConfig .currentAppVersion != nil {
603+ opts .CurrentAppVersion = upgradeConfig .currentAppVersion .VersionLabel
604+ opts .CurrentAppSequence = upgradeConfig .currentAppVersion .ChannelSequence
605+ }
606+
607+ // Add target app version info
608+ opts .TargetAppVersion = channelRelease .VersionLabel
609+ opts .TargetAppSequence = channelRelease .ChannelSequence
610+
611+ // For online upgrades, add the replicated API client and channel ID
612+ if ! isAirgap && upgradeConfig .replicatedAPIClient != nil {
613+ opts .ReplicatedAPI = upgradeConfig .replicatedAPIClient
614+ opts .ChannelID = channelRelease .ChannelID
615+ }
616+
617+ // Perform validation
618+ if err := validation .ValidateIsReleaseUpgradable (ctx , opts ); err != nil {
619+ return err
620+ }
621+
622+ return nil
623+ }
0 commit comments