package app import ( "fmt" "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/catalogue" "coopcloud.tech/abra/pkg/client" stack "coopcloud.tech/abra/pkg/client/stack" "coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/recipe" "coopcloud.tech/tagcmp" "github.com/AlecAivazis/survey/v2" "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" ) var appUpgradeCommand = &cli.Command{ Name: "upgrade", Aliases: []string{"u"}, Usage: "Upgrade an app", ArgsUsage: "", Flags: []cli.Flag{ internal.ForceFlag, }, Description: ` This command supports upgrading an app. You can use it to choose and roll out a new upgrade to an existing app. This command specifically supports changing the version of running apps, as opposed to "abra app deploy ". This action could be destructive, please ensure you have a copy of your app data beforehand - see "abra app backup " for more. `, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) stackName := app.StackName() cl, err := client.New(app.Server) if err != nil { logrus.Fatal(err) } logrus.Debugf("checking whether '%s' is already deployed", stackName) isDeployed, deployedVersion, err := stack.IsDeployed(c.Context, cl, stackName) if err != nil { logrus.Fatal(err) } if deployedVersion == "" { logrus.Fatalf("failed to determine version of deployed '%s'", app.Name) } if !isDeployed { logrus.Fatalf("'%s' is not deployed?", app.Name) } versions, err := catalogue.GetRecipeCatalogueVersions(app.Type) if err != nil { logrus.Fatal(err) } var availableUpgrades []string for _, version := range versions { parsedDeployedVersion, err := tagcmp.Parse(deployedVersion) if err != nil { logrus.Fatal(err) } parsedVersion, err := tagcmp.Parse(version) if err != nil { logrus.Fatal(err) } if parsedVersion.IsGreaterThan(parsedDeployedVersion) { availableUpgrades = append(availableUpgrades, version) } } if len(availableUpgrades) == 0 { logrus.Fatal("no available upgrades, you're on latest") } var chosenUpgrade string if !internal.Force { prompt := &survey.Select{ Message: fmt.Sprintf("Please select an upgrade (current version: '%s'):", deployedVersion), Options: availableUpgrades, } if err := survey.AskOne(prompt, &chosenUpgrade); err != nil { return err } } if internal.Force { chosenUpgrade = availableUpgrades[len(availableUpgrades)-1] logrus.Debugf("choosing '%s' as version to upgrade to", chosenUpgrade) } if err := recipe.EnsureVersion(app.Type, chosenUpgrade); err != nil { logrus.Fatal(err) } abraShPath := fmt.Sprintf("%s/%s/%s", config.APPS_DIR, app.Type, "abra.sh") abraShEnv, err := config.ReadAbraShEnvVars(abraShPath) if err != nil { logrus.Fatal(err) } for k, v := range abraShEnv { app.Env[k] = v } composeFiles, err := config.GetAppComposeFiles(app.Type, app.Env) if err != nil { logrus.Fatal(err) } deployOpts := stack.Deploy{ Composefiles: composeFiles, Namespace: stackName, Prune: false, ResolveImage: stack.ResolveImageAlways, } compose, err := config.GetAppComposeConfig(app.Name, deployOpts, app.Env) if err != nil { logrus.Fatal(err) } if !internal.Force { if err := DeployOverview(app, chosenUpgrade); err != nil { logrus.Fatal(err) } } if err := stack.RunDeploy(cl, deployOpts, compose); err != nil { logrus.Fatal(err) } return nil }, BashComplete: func(c *cli.Context) { appNames, err := config.GetAppNames() if err != nil { logrus.Warn(err) } if c.NArg() > 0 { return } for _, a := range appNames { fmt.Println(a) } }, }