diff --git a/cli/updater/updater.go b/cli/updater/updater.go index 79ee595e..7b9902dd 100644 --- a/cli/updater/updater.go +++ b/cli/updater/updater.go @@ -15,6 +15,7 @@ import ( "coopcloud.tech/abra/pkg/upstream/convert" "coopcloud.tech/abra/pkg/upstream/stack" "coopcloud.tech/tagcmp" + composetypes "github.com/docker/cli/cli/compose/types" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" dockerclient "github.com/docker/docker/client" @@ -66,6 +67,7 @@ var UpgradeAll = cli.Command{ if err != nil { logrus.Fatal(err) } + // can't import this lib: // stacks := swarm.GetStacks(cl) stacks, err := stack.GetStacks(cl) if err != nil { @@ -154,18 +156,7 @@ func getEnv(cl *dockerclient.Client, stackName string) config.AppEnv { return envMap } -func upgrade(cl *dockerclient.Client, stackName string, recipeName string) { - logrus.Debugf("Upgrade StackName: %s \n Recipe: %s", stackName, recipeName) - app := config.App{ - Name: stackName, - Recipe: recipeName, - Server: "localhost", - Env: getEnv(cl, stackName), - } - // Workaround, is there a better way? - app.Env["STACK_NAME"] = stackName - // TODO: evaluate ENABLE_AUTO_UPDATE env var - +func getAvailableUpgrades(cl *dockerclient.Client, stackName string, recipeName string) []string { logrus.Debugf("Retrieve deployed version whether %s is already deployed", stackName) isDeployed, deployedVersion, err := stack.IsDeployed(context.Background(), cl, stackName) if err != nil { @@ -193,10 +184,11 @@ func upgrade(cl *dockerclient.Client, stackName string, recipeName string) { var availableUpgrades []string if deployedVersion == "unknown" { availableUpgrades = versions - logrus.Warnf("failed to determine version of deployed %s", stackName) + logrus.Fatalf("failed to determine deployed version of %s", stackName) } if deployedVersion != "unknown" { + logrus.Infof("%s is deployed on %s with version %s", recipeName, stackName, deployedVersion) for _, version := range versions { parsedDeployedVersion, err := tagcmp.Parse(deployedVersion) if err != nil { @@ -216,37 +208,33 @@ func upgrade(cl *dockerclient.Client, stackName string, recipeName string) { } } - if len(availableUpgrades) == 0 { - logrus.Infof("no available upgrades for %s, you're on latest (%s)", stackName, deployedVersion) - return - } + } else { + logrus.Warnf("Could not determine the deployed version for %s", stackName) } + return availableUpgrades - availableUpgrades = internal.ReverseStringList(availableUpgrades) - - var chosenUpgrade string - if len(availableUpgrades) > 0 { - chosenUpgrade = availableUpgrades[len(availableUpgrades)-1] - logrus.Infof("choosing %s as version to upgrade to", chosenUpgrade) - } +} +// clone, pull, checkout version and lint the recipe repository +func processRecipeRepoVersion(recipeName string, version string) { if err := recipe.EnsureExists(recipeName); err != nil { logrus.Fatal(err) } if err := recipe.EnsureUpToDate(recipeName); err != nil { logrus.Fatal(err) } - r, err := recipe.Get(app.Recipe) - if err != nil { + if err := recipe.EnsureVersion(recipeName, version); err != nil { logrus.Fatal(err) } - if err := lint.LintForErrors(r); err != nil { - logrus.Fatal(err) - } - if err := recipe.EnsureVersion(recipeName, chosenUpgrade); err != nil { + if r, err := recipe.Get(recipeName); err != nil { + logrus.Fatal(err) + } else if err := lint.LintForErrors(r); err != nil { logrus.Fatal(err) } +} +// merge abra.sh env's into app env's +func mergeAbraShEnv(recipeName string, env config.AppEnv) { abraShPath := fmt.Sprintf("%s/%s/%s", config.RECIPES_DIR, recipeName, "abra.sh") abraShEnv, err := config.ReadAbraShEnvVars(abraShPath) if err != nil { @@ -254,10 +242,15 @@ func upgrade(cl *dockerclient.Client, stackName string, recipeName string) { } for k, v := range abraShEnv { logrus.Debugf("read v:%s k: %s", v, k) - app.Env[k] = v + env[k] = v } +} - composeFiles, err := config.GetAppComposeFiles(recipeName, app.Env) +func createDeployConfig(recipeName string, stackName string, env config.AppEnv) (*composetypes.Config, stack.Deploy) { + // Workaround, is there a better way? + env["STACK_NAME"] = stackName + + composeFiles, err := config.GetAppComposeFiles(recipeName, env) if err != nil { logrus.Fatal(err) } @@ -267,14 +260,44 @@ func upgrade(cl *dockerclient.Client, stackName string, recipeName string) { Prune: false, ResolveImage: stack.ResolveImageAlways, } - compose, err := config.GetAppComposeConfig(stackName, deployOpts, app.Env) + compose, err := config.GetAppComposeConfig(stackName, deployOpts, env) if err != nil { logrus.Fatal(err) } - config.ExposeAllEnv(compose, app.Env) - // after the upgrade the deployment won't be in chaos state any more + config.ExposeAllEnv(compose, env) + // after the upgrade the deployment won't be in chaos state anymore config.SetChaosLabel(compose, stackName, false) - config.SetRecipeLabel(compose, stackName, app.Recipe) + config.SetRecipeLabel(compose, stackName, recipeName) + return compose, deployOpts +} + +func upgrade(cl *dockerclient.Client, stackName string, recipeName string) { + logrus.Debugf("Upgrade StackName: %s \n Recipe: %s", stackName, recipeName) + app := config.App{ + Name: stackName, + Recipe: recipeName, + Server: "localhost", + Env: getEnv(cl, stackName), + } + // TODO: evaluate ENABLE_AUTO_UPDATE env var + + availableUpgrades := getAvailableUpgrades(cl, stackName, recipeName) + if len(availableUpgrades) == 0 { + logrus.Infof("no available upgrades for %s", stackName) + return + } + availableUpgrades = internal.ReverseStringList(availableUpgrades) + var chosenUpgrade string + if len(availableUpgrades) > 0 { + chosenUpgrade = availableUpgrades[len(availableUpgrades)-1] + logrus.Infof("choosing %s as version to upgrade to", chosenUpgrade) + } + + processRecipeRepoVersion(recipeName, chosenUpgrade) + + mergeAbraShEnv(recipeName, app.Env) + + compose, deployOpts := createDeployConfig(recipeName, stackName, app.Env) if err := stack.RunDeploy(cl, deployOpts, compose, stackName, true); err != nil { logrus.Fatal(err)