0
0
forked from toolshed/abra

Compare commits

..

3 Commits

27 changed files with 680 additions and 291 deletions

View File

@ -261,7 +261,7 @@ func init() {
AppCmdCommand.Flags().BoolVarP( AppCmdCommand.Flags().BoolVarP(
&requestTTY, &requestTTY,
"tty", "tty",
"T", "t",
false, false,
"request remote TTY", "request remote TTY",
) )

View File

@ -3,7 +3,6 @@ package app
import ( import (
"context" "context"
"fmt" "fmt"
"strings"
"coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/cli/internal"
"coopcloud.tech/abra/pkg/app" "coopcloud.tech/abra/pkg/app"
@ -65,8 +64,10 @@ checkout as-is. Recipe commit hashes are also supported as values for
}, },
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
var ( var (
deployWarnMessages []string deployWarnMessages []string
toDeployVersion string toDeployVersion string
isChaosCommit bool
toDeployChaosVersion = config.CHAOS_DEFAULT
) )
app := internal.ValidateApp(args) app := internal.ValidateApp(args)
@ -79,6 +80,10 @@ checkout as-is. Recipe commit hashes are also supported as values for
log.Fatal(err) log.Fatal(err)
} }
if err := lint.LintForErrors(app.Recipe); err != nil {
log.Fatal(err)
}
cl, err := client.New(app.Server) cl, err := client.New(app.Server)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
@ -95,20 +100,28 @@ checkout as-is. Recipe commit hashes are also supported as values for
log.Fatalf("%s is already deployed", app.Name) log.Fatalf("%s is already deployed", app.Name)
} }
toDeployVersion, err = getDeployVersion(args, deployMeta, app) toDeployVersion, toDeployChaosVersion, err = getDeployVersion(args, deployMeta, app)
if err != nil { if err != nil {
log.Fatal(fmt.Errorf("get deploy version: %s", err)) log.Fatal(err)
} }
if !internal.Chaos { if !internal.Chaos {
_, err = app.Recipe.EnsureVersion(toDeployVersion) isChaosCommit, err = app.Recipe.EnsureVersion(toDeployVersion)
if err != nil { if err != nil {
log.Fatalf("ensure recipe: %s", err) log.Fatal(err)
} }
}
if err := lint.LintForErrors(app.Recipe); err != nil { if isChaosCommit {
log.Fatal(err) log.Debugf("assuming chaos commit: %s", toDeployVersion)
internal.Chaos = true
toDeployChaosVersion = toDeployVersion
toDeployVersion, err = app.Recipe.GetVersionLabelLocal()
if err != nil {
log.Fatal(err)
}
}
} }
if err := validateSecrets(cl, app); err != nil { if err := validateSecrets(cl, app); err != nil {
@ -141,14 +154,18 @@ checkout as-is. Recipe commit hashes are also supported as values for
log.Fatal(err) log.Fatal(err)
} }
toDeployChaosVersionLabel := toDeployChaosVersion
if app.Recipe.Dirty {
toDeployChaosVersionLabel = formatter.AddDirtyMarker(toDeployChaosVersionLabel)
}
appPkg.ExposeAllEnv(stackName, compose, app.Env) appPkg.ExposeAllEnv(stackName, compose, app.Env)
appPkg.SetRecipeLabel(compose, stackName, app.Recipe.Name) appPkg.SetRecipeLabel(compose, stackName, app.Recipe.Name)
appPkg.SetChaosLabel(compose, stackName, internal.Chaos) appPkg.SetChaosLabel(compose, stackName, internal.Chaos)
if internal.Chaos { if internal.Chaos {
appPkg.SetChaosVersionLabel(compose, stackName, toDeployVersion) appPkg.SetChaosVersionLabel(compose, stackName, toDeployChaosVersionLabel)
} }
appPkg.SetUpdateLabel(compose, stackName, app.Env) appPkg.SetUpdateLabel(compose, stackName, app.Env)
appPkg.SetVersionLabel(compose, stackName, toDeployVersion)
envVars, err := appPkg.CheckEnv(app) envVars, err := appPkg.CheckEnv(app)
if err != nil { if err != nil {
@ -180,12 +197,19 @@ checkout as-is. Recipe commit hashes are also supported as values for
deployedVersion = deployMeta.Version deployedVersion = deployMeta.Version
} }
toWriteVersion := toDeployVersion
if internal.Chaos || isChaosCommit {
toWriteVersion = toDeployChaosVersion
}
if err := internal.DeployOverview( if err := internal.DeployOverview(
app, app,
deployedVersion,
toDeployVersion,
"",
deployWarnMessages, deployWarnMessages,
deployedVersion,
deployMeta.ChaosVersion,
toDeployVersion,
toDeployChaosVersion,
toWriteVersion,
); err != nil { ); err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -209,28 +233,43 @@ checkout as-is. Recipe commit hashes are also supported as values for
} }
} }
if err := app.WriteRecipeVersion(toDeployVersion, false); err != nil { if err := app.WriteRecipeVersion(toWriteVersion, false); err != nil {
log.Fatalf("writing recipe version failed: %s", err) log.Fatalf("writing recipe version failed: %s", err)
} }
}, },
} }
func getLatestVersionOrCommit(app app.App) (string, error) { func getChaosVersion(app app.App, toDeployVersion, toDeployChaosVersion *string) error {
var err error
*toDeployChaosVersion, err = app.Recipe.ChaosVersion()
if err != nil {
return err
}
*toDeployVersion, err = app.Recipe.GetVersionLabelLocal()
if err != nil {
return err
}
return nil
}
func getLatestVersionOrCommit(app app.App) (string, string, error) {
versions, err := app.Recipe.Tags() versions, err := app.Recipe.Tags()
if err != nil { if err != nil {
return "", err return "", "", err
} }
if len(versions) > 0 && !internal.Chaos { if len(versions) > 0 && !internal.Chaos {
return versions[len(versions)-1], nil return versions[len(versions)-1], "", nil
} }
head, err := app.Recipe.Head() head, err := app.Recipe.Head()
if err != nil { if err != nil {
return "", err return "", "", err
} }
return formatter.SmallSHA(head.String()), nil return "", formatter.SmallSHA(head.String()), nil
} }
// validateArgsAndFlags ensures compatible args/flags. // validateArgsAndFlags ensures compatible args/flags.
@ -257,44 +296,48 @@ func validateSecrets(cl *dockerClient.Client, app app.App) error {
return nil return nil
} }
func getDeployVersion(cliArgs []string, deployMeta stack.DeployMeta, app app.App) (string, error) { func getDeployVersion(cliArgs []string, deployMeta stack.DeployMeta, app app.App) (string, string, error) {
// Chaos mode overrides everything // Chaos mode overrides everything
if internal.Chaos { if internal.Chaos {
v, err := app.Recipe.ChaosVersion() v, err := app.Recipe.ChaosVersion()
if err != nil { if err != nil {
return "", err return "", "", err
} }
log.Debugf("version: taking chaos version: %s", v) cv, err := app.Recipe.GetVersionLabelLocal()
return v, nil if err != nil {
return "", "", err
}
log.Debugf("version: taking chaos version: %s, %s", v, cv)
return v, cv, nil
} }
// Check if the deploy version is set with a cli argument // Check if the deploy version is set with a cli argument
if len(cliArgs) == 2 && cliArgs[1] != "" { if len(cliArgs) == 2 && cliArgs[1] != "" {
log.Debugf("version: taking version from cli arg: %s", cliArgs[1]) log.Debugf("version: taking version from cli arg: %s", cliArgs[1])
return cliArgs[1], nil return cliArgs[1], "", nil
} }
// Check if the recipe has a version in the .env file // Check if the recipe has a version in the .env file
if app.Recipe.EnvVersion != "" && !internal.IgnoreEnvVersion { if app.Recipe.EnvVersion != "" && !internal.IgnoreEnvVersion {
if strings.HasSuffix(app.Recipe.EnvVersionRaw, "+U") {
return "", fmt.Errorf("version: can not redeploy chaos version %s", app.Recipe.EnvVersionRaw)
}
log.Debugf("version: taking version from .env file: %s", app.Recipe.EnvVersion) log.Debugf("version: taking version from .env file: %s", app.Recipe.EnvVersion)
return app.Recipe.EnvVersion, nil return app.Recipe.EnvVersion, "", nil
} }
// Take deployed version // Take deployed version
if deployMeta.IsDeployed { if deployMeta.IsDeployed {
log.Debugf("version: taking deployed version: %s", deployMeta.Version) log.Debugf("version: taking deployed version: %s", deployMeta.Version)
return deployMeta.Version, nil return deployMeta.Version, "", nil
} }
v, err := getLatestVersionOrCommit(app) v, vc, err := getLatestVersionOrCommit(app)
log.Debugf("version: taking new recipe version: %s", v) log.Debugf("version: taking new recipe versio: %s, %s", v, vc)
if err != nil { if err != nil {
return "", err log.Fatal(err)
} }
return v, nil if v == "" {
return vc, vc, nil
}
return v, vc, nil
} }
func init() { func init() {

View File

@ -81,8 +81,35 @@ var AppNewCommand = &cobra.Command{
log.Fatal(err) log.Fatal(err)
} }
recipeVersion = chaosVersion // NOTE(d1): rely on tags as there is no recipe.EnvVersion yet because
} else { // the app has not been fully created. we rely on the local git state of
// the repository
tags, err := recipe.Tags()
if err != nil {
log.Fatal(err)
}
internal.SortVersionsDesc(tags)
if len(tags) == 0 {
// NOTE(d1): this is a new recipe with no released versions
recipeVersion = config.UNKNOWN_DEFAULT
} else {
recipeVersion = tags[len(tags)-1]
}
if err := recipe.IsDirty(); err != nil {
log.Fatal(err)
}
if !internal.Offline && !recipe.Dirty {
if err := recipe.EnsureUpToDate(); err != nil {
log.Fatal(err)
}
}
}
if !internal.Chaos {
if err := recipe.EnsureIsClean(); err != nil { if err := recipe.EnsureIsClean(); err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -209,7 +236,16 @@ var AppNewCommand = &cobra.Command{
log.Fatal(err) log.Fatal(err)
} }
if err := app.WriteRecipeVersion(recipeVersion, false); err != nil { if err := app.Recipe.IsDirty(); err != nil {
log.Fatal(err)
}
toWriteVersion := recipeVersion
if internal.Chaos || app.Recipe.Dirty {
toWriteVersion = chaosVersion
}
if err := app.WriteRecipeVersion(toWriteVersion, false); err != nil {
log.Fatalf("writing recipe version failed: %s", err) log.Fatalf("writing recipe version failed: %s", err)
} }
}, },

View File

@ -183,13 +183,20 @@ beforehand. See "abra app backup" for more.`,
} }
appPkg.SetUpdateLabel(compose, stackName, app.Env) appPkg.SetUpdateLabel(compose, stackName, app.Env)
chaosVersion := config.CHAOS_DEFAULT
if deployMeta.IsChaos {
chaosVersion = deployMeta.ChaosVersion
}
// NOTE(d1): no release notes implemeneted for rolling back // NOTE(d1): no release notes implemeneted for rolling back
if err := internal.DeployOverview( if err := internal.NewVersionOverview(
app, app,
downgradeWarnMessages,
"rollback",
deployMeta.Version, deployMeta.Version,
chaosVersion,
chosenDowngrade, chosenDowngrade,
"", "",
downgradeWarnMessages,
); err != nil { ); err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -242,7 +249,7 @@ func validateDowngradeVersionArg(
) error { ) error {
parsedDeployedVersion, err := tagcmp.Parse(deployMeta.Version) parsedDeployedVersion, err := tagcmp.Parse(deployMeta.Version)
if err != nil { if err != nil {
return fmt.Errorf("current deployment '%s' is not a known version for %s", deployMeta.Version, app.Recipe.Name) return fmt.Errorf("'%s' is not a known version for %s", deployMeta.Version, app.Recipe.Name)
} }
parsedSpecificVersion, err := tagcmp.Parse(specificVersion) parsedSpecificVersion, err := tagcmp.Parse(specificVersion)

View File

@ -49,11 +49,11 @@ var AppSecretGenerateCommand = &cobra.Command{
log.Fatal(err) log.Fatal(err)
} }
if len(args) <= 2 && !generateAllSecrets { if len(args) == 1 && !generateAllSecrets {
log.Fatal("missing arguments [secret]/[version] or '--all'") log.Fatal("missing arguments [secret]/[version] or '--all'")
} }
if len(args) > 2 && generateAllSecrets { if len(args) > 1 && generateAllSecrets {
log.Fatal("cannot use '[secret] [version]' and '--all' together") log.Fatal("cannot use '[secret] [version]' and '--all' together")
} }

View File

@ -54,12 +54,21 @@ Passing "--prune/-p" does not remove those volumes.`,
log.Fatalf("%s is not deployed?", app.Name) log.Fatalf("%s is not deployed?", app.Name)
} }
if err := internal.DeployOverview( chaosVersion := config.CHAOS_DEFAULT
if deployMeta.IsChaos {
chaosVersion = deployMeta.ChaosVersion
}
toWriteVersion := deployMeta.Version
if deployMeta.IsChaos {
toWriteVersion = chaosVersion
}
if err := internal.UndeployOverview(
app, app,
deployMeta.Version, deployMeta.Version,
config.NO_DOMAIN_DEFAULT, chaosVersion,
"", toWriteVersion,
nil,
); err != nil { ); err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -78,7 +87,7 @@ Passing "--prune/-p" does not remove those volumes.`,
} }
} }
if err := app.WriteRecipeVersion(deployMeta.Version, false); err != nil { if err := app.WriteRecipeVersion(toWriteVersion, false); err != nil {
log.Fatalf("writing recipe version failed: %s", err) log.Fatalf("writing recipe version failed: %s", err)
} }
}, },

View File

@ -43,8 +43,7 @@ beforehand. See "abra app backup" for more.`,
ValidArgsFunction: func( ValidArgsFunction: func(
cmd *cobra.Command, cmd *cobra.Command,
args []string, args []string,
toComplete string, toComplete string) ([]string, cobra.ShellCompDirective) {
) ([]string, cobra.ShellCompDirective) {
switch l := len(args); l { switch l := len(args); l {
case 0: case 0:
return autocomplete.AppNameComplete() return autocomplete.AppNameComplete()
@ -207,21 +206,23 @@ beforehand. See "abra app backup" for more.`,
return return
} }
if upgradeReleaseNotes != "" && chosenUpgrade != "" { chaosVersion := config.CHAOS_DEFAULT
fmt.Print(upgradeReleaseNotes) if deployMeta.IsChaos {
} else { chaosVersion = deployMeta.ChaosVersion
upgradeWarnMessages = append(
upgradeWarnMessages, if deployMeta.ChaosVersion == "" {
fmt.Sprintf("no release notes available for %s", chosenUpgrade), chaosVersion = config.UNKNOWN_DEFAULT
) }
} }
if err := internal.DeployOverview( if err := internal.NewVersionOverview(
app, app,
upgradeWarnMessages,
"upgrade",
deployMeta.Version, deployMeta.Version,
chaosVersion,
chosenUpgrade, chosenUpgrade,
upgradeReleaseNotes, upgradeReleaseNotes,
upgradeWarnMessages,
); err != nil { ); err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -364,7 +365,7 @@ func validateUpgradeVersionArg(
parsedDeployedVersion, err := tagcmp.Parse(deployMeta.Version) parsedDeployedVersion, err := tagcmp.Parse(deployMeta.Version)
if err != nil { if err != nil {
return fmt.Errorf("'%s' is not a known version", deployMeta.Version) return err
} }
if parsedSpecificVersion.IsLessThan(parsedDeployedVersion) && if parsedSpecificVersion.IsLessThan(parsedDeployedVersion) &&
@ -396,7 +397,9 @@ func ensureDeployed(cl *dockerClient.Client, app app.App) (stack.DeployMeta, err
return deployMeta, nil return deployMeta, nil
} }
var showReleaseNotes bool var (
showReleaseNotes bool
)
func init() { func init() {
AppUpgradeCommand.Flags().BoolVarP( AppUpgradeCommand.Flags().BoolVarP(

View File

@ -10,6 +10,7 @@ import (
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/formatter"
"coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/log"
"coopcloud.tech/abra/pkg/recipe"
"coopcloud.tech/tagcmp" "coopcloud.tech/tagcmp"
"github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2"
"github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss"
@ -37,21 +38,18 @@ func horizontal(left, mid, right string) string {
return lipgloss.JoinHorizontal(lipgloss.Left, left, mid, right) return lipgloss.JoinHorizontal(lipgloss.Left, left, mid, right)
} }
func formatComposeFiles(composeFiles string) string { // NewVersionOverview shows an upgrade or downgrade overview
return strings.ReplaceAll(composeFiles, ":", "\n") func NewVersionOverview(
}
// DeployOverview shows a deployment overview
func DeployOverview(
app appPkg.App, app appPkg.App,
deployedVersion string,
toDeployVersion string,
info string,
warnMessages []string, warnMessages []string,
) error { kind,
deployedVersion,
deployedChaosVersion,
toDeployVersion,
releaseNotes string) error {
deployConfig := "compose.yml" deployConfig := "compose.yml"
if composeFiles, ok := app.Env["COMPOSE_FILE"]; ok { if composeFiles, ok := app.Env["COMPOSE_FILE"]; ok {
deployConfig = formatComposeFiles(composeFiles) deployConfig = composeFiles
} }
server := app.Server server := app.Server
@ -64,7 +62,13 @@ func DeployOverview(
domain = config.NO_DOMAIN_DEFAULT domain = config.NO_DOMAIN_DEFAULT
} }
envVersion := app.Recipe.EnvVersionRaw upperKind := strings.ToUpper(kind)
envVersion, err := recipe.GetEnvVersionRaw(app.Recipe.Name)
if err != nil {
return err
}
if envVersion == "" { if envVersion == "" {
envVersion = config.NO_VERSION_DEFAULT envVersion = config.NO_VERSION_DEFAULT
} }
@ -74,19 +78,33 @@ func DeployOverview(
{"RECIPE", app.Recipe.Name}, {"RECIPE", app.Recipe.Name},
{"SERVER", server}, {"SERVER", server},
{"CONFIG", deployConfig}, {"CONFIG", deployConfig},
{"", ""},
{"CURRENT DEPLOYMENT", formatter.BoldDirtyDefault(deployedVersion)}, {"CURRENT DEPLOYMENT", "---"},
{"ENV VERSION", formatter.BoldDirtyDefault(envVersion)}, {"VERSION", formatter.BoldDirtyDefault(deployedVersion)},
{"NEW DEPLOYMENT", formatter.BoldDirtyDefault(toDeployVersion)}, {"CHAOS ", formatter.BoldDirtyDefault(deployedChaosVersion)},
{upperKind, "---"},
{"VERSION", formatter.BoldDirtyDefault(toDeployVersion)},
{fmt.Sprintf("%s.ENV", strings.ToUpper(app.Domain)), "---"},
{"CURRENT VERSION", formatter.BoldDirtyDefault(envVersion)},
{"NEW VERSION", formatter.BoldDirtyDefault(toDeployVersion)},
} }
deployType := getDeployType(deployedVersion, toDeployVersion) overview := formatter.CreateOverview(
overview := formatter.CreateOverview(fmt.Sprintf("%s OVERVIEW", deployType), rows) fmt.Sprintf("%s OVERVIEW", upperKind),
rows,
)
fmt.Println(overview) fmt.Println(overview)
if info != "" { if releaseNotes != "" && toDeployVersion != "" {
fmt.Println(info) fmt.Print(releaseNotes)
} else {
warnMessages = append(
warnMessages,
fmt.Sprintf("no release notes available for %s", toDeployVersion),
)
} }
for _, msg := range warnMessages { for _, msg := range warnMessages {
@ -110,34 +128,164 @@ func DeployOverview(
return nil return nil
} }
func getDeployType(currentVersion, newVersion string) string { // DeployOverview shows a deployment overview
if newVersion == config.NO_DOMAIN_DEFAULT { func DeployOverview(
return "UNDEPLOY" app appPkg.App,
warnMessages []string,
deployedVersion string,
deployedChaosVersion string,
toDeployVersion,
toDeployChaosVersion string,
toWriteVersion string,
) error {
deployConfig := "compose.yml"
if composeFiles, ok := app.Env["COMPOSE_FILE"]; ok {
deployConfig = composeFiles
} }
if strings.Contains(newVersion, "+U") {
return "CHAOS DEPLOY" server := app.Server
if app.Server == "default" {
server = "local"
} }
if strings.Contains(currentVersion, "+U") {
return "UNCHAOS DEPLOY" domain := app.Domain
if domain == "" {
domain = config.NO_DOMAIN_DEFAULT
} }
if currentVersion == newVersion {
return "REDEPLOY" if app.Recipe.Dirty {
toWriteVersion = formatter.AddDirtyMarker(toWriteVersion)
toDeployChaosVersion = formatter.AddDirtyMarker(toDeployChaosVersion)
} }
if currentVersion == config.NO_VERSION_DEFAULT {
return "NEW DEPLOY" recipeName, exists := app.Env["RECIPE"]
if !exists {
recipeName = app.Env["TYPE"]
} }
currentParsed, err := tagcmp.Parse(currentVersion)
envVersion, err := recipe.GetEnvVersionRaw(recipeName)
if err != nil { if err != nil {
return "DEPLOY" return err
} }
newParsed, err := tagcmp.Parse(newVersion)
if envVersion == "" {
envVersion = config.NO_VERSION_DEFAULT
}
rows := [][]string{
{"DOMAIN", domain},
{"RECIPE", app.Recipe.Name},
{"SERVER", server},
{"CONFIG", deployConfig},
{"CURRENT DEPLOYMENT", "---"},
{"VERSION", formatter.BoldDirtyDefault(deployedVersion)},
{"CHAOS", formatter.BoldDirtyDefault(deployedChaosVersion)},
{"NEW DEPLOYMENT", "---"},
{"VERSION", formatter.BoldDirtyDefault(toDeployVersion)},
{"CHAOS", formatter.BoldDirtyDefault(toDeployChaosVersion)},
{fmt.Sprintf("%s.ENV", strings.ToUpper(app.Name)), "---"},
{"CURRENT VERSION", formatter.BoldDirtyDefault(envVersion)},
{"NEW VERSION", formatter.BoldDirtyDefault(toWriteVersion)},
}
overview := formatter.CreateOverview("DEPLOY OVERVIEW", rows)
fmt.Println(overview)
for _, msg := range warnMessages {
log.Warn(msg)
}
if NoInput {
return nil
}
response := false
prompt := &survey.Confirm{Message: "proceed?"}
if err := survey.AskOne(prompt, &response); err != nil {
return err
}
if !response {
log.Fatal("deployment cancelled")
}
return nil
}
// UndeployOverview shows an undeployment overview
func UndeployOverview(
app appPkg.App,
deployedVersion,
deployedChaosVersion,
toWriteVersion string,
) error {
deployConfig := "compose.yml"
if composeFiles, ok := app.Env["COMPOSE_FILE"]; ok {
deployConfig = composeFiles
}
server := app.Server
if app.Server == "default" {
server = "local"
}
domain := app.Domain
if domain == "" {
domain = config.NO_DOMAIN_DEFAULT
}
recipeName, exists := app.Env["RECIPE"]
if !exists {
recipeName = app.Env["TYPE"]
}
envVersion, err := recipe.GetEnvVersionRaw(recipeName)
if err != nil { if err != nil {
return "DEPLOY" return err
} }
if currentParsed.IsLessThan(newParsed) {
return "UPGRADE" if envVersion == "" {
envVersion = config.NO_VERSION_DEFAULT
} }
return "DOWNGRADE"
rows := [][]string{
{"DOMAIN", domain},
{"RECIPE", app.Recipe.Name},
{"SERVER", server},
{"CONFIG", deployConfig},
{"CURRENT DEPLOYMENT", "---"},
{"VERSION", formatter.BoldDirtyDefault(deployedVersion)},
{"CHAOS", formatter.BoldDirtyDefault(deployedChaosVersion)},
{fmt.Sprintf("%s.ENV", strings.ToUpper(app.Name)), "---"},
{"CURRENT VERSION", formatter.BoldDirtyDefault(envVersion)},
{"NEW VERSION", formatter.BoldDirtyDefault(toWriteVersion)},
}
overview := formatter.CreateOverview("UNDEPLOY OVERVIEW", rows)
fmt.Println(overview)
if NoInput {
return nil
}
response := false
prompt := &survey.Confirm{Message: "proceed?"}
if err := survey.AskOne(prompt, &response); err != nil {
return err
}
if !response {
log.Fatal("undeploy cancelled")
}
return nil
} }
// PostCmds parses a string of commands and executes them inside of the respective services // PostCmds parses a string of commands and executes them inside of the respective services

View File

@ -655,6 +655,19 @@ func (a App) WriteRecipeVersion(version string, dryRun bool) error {
splitted := strings.Split(line, ":") splitted := strings.Split(line, ":")
if a.Recipe.Dirty {
dirtyVersion = fmt.Sprintf("%s%s", version, config.DIRTY_DEFAULT)
if strings.Contains(line, dirtyVersion) {
skipped = true
lines = append(lines, line)
continue
}
line = fmt.Sprintf("%s:%s", splitted[0], dirtyVersion)
lines = append(lines, line)
continue
}
line = fmt.Sprintf("%s:%s", splitted[0], version) line = fmt.Sprintf("%s:%s", splitted[0], version)
lines = append(lines, line) lines = append(lines, line)
} }

View File

@ -223,4 +223,16 @@ func TestWriteRecipeVersionOverwrite(t *testing.T) {
} }
assert.Equal(t, "foo", app.Recipe.EnvVersion) assert.Equal(t, "foo", app.Recipe.EnvVersion)
app.Recipe.Dirty = true
if err := app.WriteRecipeVersion("foo+U", false); err != nil {
t.Fatal(err)
}
app, err = appPkg.GetApp(testPkg.ExpectedAppFiles, testPkg.AppName)
if err != nil {
t.Fatal(err)
}
assert.Equal(t, "foo+U", app.Recipe.EnvVersion)
} }

View File

@ -44,16 +44,6 @@ func SetChaosVersionLabel(compose *composetypes.Config, stackName string, chaosV
} }
} }
func SetVersionLabel(compose *composetypes.Config, stackName string, version string) {
for _, service := range compose.Services {
if service.Name == "app" {
log.Debugf("set label 'coop-cloud.%s.version' to %v for %s", stackName, version, stackName)
labelKey := fmt.Sprintf("coop-cloud.%s.version", stackName)
service.Deploy.Labels[labelKey] = version
}
}
}
// SetUpdateLabel adds env ENABLE_AUTO_UPDATE as label to enable/disable the // SetUpdateLabel adds env ENABLE_AUTO_UPDATE as label to enable/disable the
// auto update process for this app. The default if this variable is not set is to disable // auto update process for this app. The default if this variable is not set is to disable
// the auto update process. // the auto update process.

View File

@ -7,7 +7,6 @@ import (
"sort" "sort"
"strings" "strings"
"coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/formatter"
gitPkg "coopcloud.tech/abra/pkg/git" gitPkg "coopcloud.tech/abra/pkg/git"
"coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/log"
@ -46,9 +45,6 @@ func (r Recipe) Ensure(ctx EnsureContext) error {
if r.EnvVersion != "" && !ctx.IgnoreEnvVersion { if r.EnvVersion != "" && !ctx.IgnoreEnvVersion {
log.Debugf("ensuring env version %s", r.EnvVersion) log.Debugf("ensuring env version %s", r.EnvVersion)
if strings.Contains(r.EnvVersion, "+U") {
log.Fatalf("can not redeploy chaos version (%s) without --chaos", r.EnvVersion)
}
if _, err := r.EnsureVersion(r.EnvVersion); err != nil { if _, err := r.EnsureVersion(r.EnvVersion); err != nil {
return err return err
@ -278,14 +274,19 @@ func (r Recipe) EnsureUpToDate() error {
return nil return nil
} }
// IsDirty checks whether a recipe is dirty or not. // IsDirty checks whether a recipe is dirty or not. N.B., if you call IsDirty
func (r *Recipe) IsDirty() (bool, error) { // from another Recipe method, you should propagate the pointer reference (*).
func (r *Recipe) IsDirty() error {
isClean, err := gitPkg.IsClean(r.Dir) isClean, err := gitPkg.IsClean(r.Dir)
if err != nil { if err != nil {
return false, err return err
} }
return !isClean, nil if !isClean {
r.Dirty = true
}
return nil
} }
// ChaosVersion constructs a chaos mode recipe version. // ChaosVersion constructs a chaos mode recipe version.
@ -299,12 +300,8 @@ func (r *Recipe) ChaosVersion() (string, error) {
version = formatter.SmallSHA(head.String()) version = formatter.SmallSHA(head.String())
dirty, err := r.IsDirty() if err := r.IsDirty(); err != nil {
if err != nil { return version, err
return "", err
}
if dirty {
return fmt.Sprintf("%s%s", version, config.DIRTY_DEFAULT), nil
} }
return version, nil return version, nil

View File

@ -15,6 +15,10 @@ func TestIsDirty(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
if err := r.IsDirty(); err != nil {
t.Fatal(err)
}
assert.False(t, r.Dirty) assert.False(t, r.Dirty)
fpath := filepath.Join(r.Dir, "foo.txt") fpath := filepath.Join(r.Dir, "foo.txt")
@ -27,10 +31,9 @@ func TestIsDirty(t *testing.T) {
os.Remove(fpath) os.Remove(fpath)
}) })
dirty, err := r.IsDirty() if err := r.IsDirty(); err != nil {
if err != nil {
t.Fatal(err) t.Fatal(err)
} }
assert.True(t, dirty) assert.True(t, r.Dirty)
} }

View File

@ -12,8 +12,6 @@ import (
"strconv" "strconv"
"strings" "strings"
"github.com/go-git/go-git/v5"
"coopcloud.tech/abra/pkg/catalogue" "coopcloud.tech/abra/pkg/catalogue"
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/formatter"
@ -22,6 +20,7 @@ import (
"coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/log"
"coopcloud.tech/abra/pkg/web" "coopcloud.tech/abra/pkg/web"
"coopcloud.tech/tagcmp" "coopcloud.tech/tagcmp"
"github.com/go-git/go-git/v5"
) )
// RecipeCatalogueURL is the only current recipe catalogue available. // RecipeCatalogueURL is the only current recipe catalogue available.
@ -120,9 +119,22 @@ type Features struct {
SSO string `json:"sso"` SSO string `json:"sso"`
} }
func GetEnvVersionRaw(name string) (string, error) {
var version string
if strings.Contains(name, ":") {
split := strings.Split(name, ":")
if len(split) > 2 {
return version, fmt.Errorf("version seems invalid: %s", name)
}
version = split[1]
}
return version, nil
}
func Get(name string) Recipe { func Get(name string) Recipe {
version := "" version := ""
versionRaw := ""
if strings.Contains(name, ":") { if strings.Contains(name, ":") {
split := strings.Split(name, ":") split := strings.Split(name, ":")
if len(split) > 2 { if len(split) > 2 {
@ -131,7 +143,6 @@ func Get(name string) Recipe {
name = split[0] name = split[0]
version = split[1] version = split[1]
versionRaw = version
if strings.HasSuffix(version, config.DIRTY_DEFAULT) { if strings.HasSuffix(version, config.DIRTY_DEFAULT) {
version = strings.Replace(split[1], config.DIRTY_DEFAULT, "", 1) version = strings.Replace(split[1], config.DIRTY_DEFAULT, "", 1)
log.Debugf("removed dirty suffix from .env version: %s -> %s", split[1], version) log.Debugf("removed dirty suffix from .env version: %s -> %s", split[1], version)
@ -156,12 +167,11 @@ func Get(name string) Recipe {
dir := path.Join(config.RECIPES_DIR, escapeRecipeName(name)) dir := path.Join(config.RECIPES_DIR, escapeRecipeName(name))
r := Recipe{ r := Recipe{
Name: name, Name: name,
EnvVersion: version, EnvVersion: version,
EnvVersionRaw: versionRaw, Dir: dir,
Dir: dir, GitURL: gitURL,
GitURL: gitURL, SSHURL: sshURL,
SSHURL: sshURL,
ComposePath: path.Join(dir, "compose.yml"), ComposePath: path.Join(dir, "compose.yml"),
ReadmePath: path.Join(dir, "README.md"), ReadmePath: path.Join(dir, "README.md"),
@ -169,23 +179,20 @@ func Get(name string) Recipe {
AbraShPath: path.Join(dir, "abra.sh"), AbraShPath: path.Join(dir, "abra.sh"),
} }
dirty, err := r.IsDirty() if err := r.IsDirty(); err != nil && !errors.Is(err, git.ErrRepositoryNotExists) {
if err != nil && !errors.Is(err, git.ErrRepositoryNotExists) {
log.Fatalf("failed to check git status of %s: %s", r.Name, err) log.Fatalf("failed to check git status of %s: %s", r.Name, err)
} }
r.Dirty = dirty
return r return r
} }
type Recipe struct { type Recipe struct {
Name string Name string
EnvVersion string EnvVersion string
EnvVersionRaw string Dirty bool // NOTE(d1): git terminology for unstaged changes
Dirty bool // NOTE(d1): git terminology for unstaged changes Dir string
Dir string GitURL string
GitURL string SSHURL string
SSHURL string
ComposePath string ComposePath string
ReadmePath string ReadmePath string

View File

@ -34,7 +34,6 @@ func TestGet(t *testing.T) {
recipe: Recipe{ recipe: Recipe{
Name: "foo", Name: "foo",
EnvVersion: "1.2.3", EnvVersion: "1.2.3",
EnvVersionRaw: "1.2.3",
Dir: path.Join(cfg.GetAbraDir(), "/recipes/foo"), Dir: path.Join(cfg.GetAbraDir(), "/recipes/foo"),
GitURL: "https://git.coopcloud.tech/coop-cloud/foo.git", GitURL: "https://git.coopcloud.tech/coop-cloud/foo.git",
SSHURL: "ssh://git@git.coopcloud.tech:2222/coop-cloud/foo.git", SSHURL: "ssh://git@git.coopcloud.tech:2222/coop-cloud/foo.git",
@ -62,22 +61,6 @@ func TestGet(t *testing.T) {
recipe: Recipe{ recipe: Recipe{
Name: "mygit.org/myorg/cool-recipe", Name: "mygit.org/myorg/cool-recipe",
EnvVersion: "1.2.4", EnvVersion: "1.2.4",
EnvVersionRaw: "1.2.4",
Dir: path.Join(cfg.GetAbraDir(), "/recipes/mygit_org_myorg_cool-recipe"),
GitURL: "https://mygit.org/myorg/cool-recipe.git",
SSHURL: "ssh://git@mygit.org/myorg/cool-recipe.git",
ComposePath: path.Join(cfg.GetAbraDir(), "recipes/mygit_org_myorg_cool-recipe/compose.yml"),
ReadmePath: path.Join(cfg.GetAbraDir(), "recipes/mygit_org_myorg_cool-recipe/README.md"),
SampleEnvPath: path.Join(cfg.GetAbraDir(), "recipes/mygit_org_myorg_cool-recipe/.env.sample"),
AbraShPath: path.Join(cfg.GetAbraDir(), "recipes/mygit_org_myorg_cool-recipe/abra.sh"),
},
},
{
name: "mygit.org/myorg/cool-recipe:1e83340e+U",
recipe: Recipe{
Name: "mygit.org/myorg/cool-recipe",
EnvVersion: "1e83340e",
EnvVersionRaw: "1e83340e+U",
Dir: path.Join(cfg.GetAbraDir(), "/recipes/mygit_org_myorg_cool-recipe"), Dir: path.Join(cfg.GetAbraDir(), "/recipes/mygit_org_myorg_cool-recipe"),
GitURL: "https://mygit.org/myorg/cool-recipe.git", GitURL: "https://mygit.org/myorg/cool-recipe.git",
SSHURL: "ssh://git@mygit.org/myorg/cool-recipe.git", SSHURL: "ssh://git@mygit.org/myorg/cool-recipe.git",
@ -122,3 +105,16 @@ func TestGetVersionLabelLocalDoesNotUseTimeoutLabel(t *testing.T) {
assert.NotEqual(t, label, defaultTimeoutLabel) assert.NotEqual(t, label, defaultTimeoutLabel)
} }
} }
func TestDirtyMarkerRemoved(t *testing.T) {
r := Get("abra-test-recipe:1e83340e+U")
assert.Equal(t, "1e83340e", r.EnvVersion)
}
func TestGetEnvVersionRaw(t *testing.T) {
v, err := GetEnvVersionRaw("abra-test-recipe:1e83340e+U")
if err != nil {
t.Fatal(err)
}
assert.Equal(t, "1e83340e+U", v)
}

View File

@ -22,8 +22,6 @@ setup(){
teardown(){ teardown(){
_reset_recipe _reset_recipe
_undeploy_app _undeploy_app
_undeploy_app2 "gitea.$TEST_SERVER"
_reset_app _reset_app
_reset_tags _reset_tags
@ -224,6 +222,19 @@ teardown(){
run $ABRA app deploy "gitea.$TEST_SERVER" --no-input --no-converge-checks run $ABRA app deploy "gitea.$TEST_SERVER" --no-input --no-converge-checks
assert_success assert_success
assert_output --partial "$latestVersion" assert_output --partial "$latestVersion"
run $ABRA app undeploy "gitea.$TEST_SERVER" --no-input
assert_success
run $ABRA app secret remove "gitea.$TEST_SERVER" --all --no-input
assert_success
run $ABRA app volume remove "gitea.$TEST_SERVER" --no-input
assert_success
run $ABRA app remove "gitea.$TEST_SERVER" --no-input
assert_success
assert_not_exists "$ABRA_DIR/servers/$TEST_SERVER/gitea.$TEST_SERVER.env"
} }
# bats test_tags=slow # bats test_tags=slow

View File

@ -37,10 +37,17 @@ teardown(){
--no-input --no-converge-checks --no-input --no-converge-checks
assert_success assert_success
assert_output --partial 'NEW DEPLOY OVERVIEW' # current deployment
assert_output --partial 'CURRENT DEPLOYMENT N/A' assert_output --regexp 'VERSION.*N/A'
assert_output --partial 'ENV VERSION N/A' assert_output --regexp 'CHAOS.*false'
assert_output --partial "NEW DEPLOYMENT ${latestRelease}"
# new deployment
assert_output --regexp 'VERSION.* ' + "${latestRelease}"
assert_output --regexp 'CHAOS.*false'
# env version
assert_output --regexp 'CURRENT VERSION.*N/A'
assert_output --regexp 'NEW VERSION.*' + "${latestRelease}"
run grep -q "TYPE=$TEST_RECIPE:${latestRelease}" \ run grep -q "TYPE=$TEST_RECIPE:${latestRelease}" \
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
@ -54,10 +61,17 @@ teardown(){
--no-input --no-converge-checks --no-input --no-converge-checks
assert_success assert_success
assert_output --partial 'NEW DEPLOY OVERVIEW' # current deployment
assert_output --partial "CURRENT DEPLOYMENT N/A" assert_output --regexp 'VERSION.*N/A'
assert_output --partial "ENV VERSION ${latestRelease}" assert_output --regexp 'CHAOS.*false'
assert_output --partial "NEW DEPLOYMENT ${latestRelease}"
# new deployment
assert_output --regexp 'VERSION.* ' + "${latestRelease}"
assert_output --regexp 'CHAOS.*false'
# env version
assert_output --regexp 'CURRENT VERSION.*' + "${latestRelease}"
assert_output --regexp 'NEW VERSION.*' + "${latestRelease}"
run grep -q "TYPE=$TEST_RECIPE:${latestRelease}" \ run grep -q "TYPE=$TEST_RECIPE:${latestRelease}" \
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
@ -76,10 +90,17 @@ teardown(){
--no-input --no-converge-checks --no-input --no-converge-checks
assert_success assert_success
assert_output --partial 'NEW DEPLOY OVERVIEW' # current deployment
assert_output --partial "CURRENT DEPLOYMENT N/A" assert_output --regexp 'VERSION.*N/A'
assert_output --partial "ENV VERSION 0.1.1+1.20.2" assert_output --regexp 'CHAOS.*false'
assert_output --partial "NEW DEPLOYMENT 0.1.1+1.20.2"
# new deployment
assert_output --regexp 'VERSION.*' + "0.1.1+1.20.2"
assert_output --regexp 'CHAOS.*false'
# env version
assert_output --regexp 'CURRENT VERSION.*' + "0.1.1+1.20.2"
assert_output --regexp 'NEW VERSION.*' + "0.1.1+1.20.2"
run grep -q "TYPE=$TEST_RECIPE:0.1.1+1.20.2" \ run grep -q "TYPE=$TEST_RECIPE:0.1.1+1.20.2" \
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
@ -99,10 +120,17 @@ teardown(){
--no-input --no-converge-checks --ignore-env-version --no-input --no-converge-checks --ignore-env-version
assert_success assert_success
assert_output --partial 'NEW DEPLOY OVERVIEW' # current deployment
assert_output --partial "CURRENT DEPLOYMENT N/A" assert_output --regexp 'VERSION.*N/A'
assert_output --partial "ENV VERSION 0.1.1+1.20.2" assert_output --regexp 'CHAOS.*false'
assert_output --partial "NEW DEPLOYMENT ${latestRelease}"
# new deployment
assert_output --regexp 'VERSION.*' + "${latestRelease}"
assert_output --regexp 'CHAOS.*false'
# env version
assert_output --regexp 'CURRENT VERSION.*' + "0.1.1+1.20.2"
assert_output --regexp 'NEW VERSION.*' + "${latestRelease}"
run grep -q "TYPE=$TEST_RECIPE:${latestRelease}" \ run grep -q "TYPE=$TEST_RECIPE:${latestRelease}" \
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
@ -125,10 +153,17 @@ teardown(){
--no-input --no-converge-checks --chaos --no-input --no-converge-checks --chaos
assert_success assert_success
assert_output --partial 'CHAOS DEPLOY OVERVIEW' # current deployment
assert_output --partial "CURRENT DEPLOYMENT ${latestRelease}" assert_output --regexp 'VERSION.*' + "${latestRelease}"
assert_output --partial "ENV VERSION ${latestRelease}" assert_output --regexp 'CHAOS.*false'
assert_output --partial "NEW DEPLOYMENT ${headHash:0:8}+U"
# new deployment
assert_output --regexp 'VERSION.*' + "${latestRelease}"
assert_output --regexp 'CHAOS.*' + "${headHash:0:8}+U"
# env version
assert_output --regexp 'CURRENT VERSION.*' + "${latestRelease}"
assert_output --regexp 'NEW VERSION.*' + "${headHash:0:8}+U"
run rm -rf "$ABRA_DIR/recipes/$TEST_RECIPE/foo" run rm -rf "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
assert_not_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo" assert_not_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
@ -138,7 +173,7 @@ teardown(){
assert_success assert_success
} }
@test "can not redeploy chaos version without --chaos" { @test "chaos deploy then force deploy" {
headHash=$(_get_head_hash) headHash=$(_get_head_hash)
latestRelease=$(_latest_release) latestRelease=$(_latest_release)
@ -154,12 +189,27 @@ teardown(){
assert_not_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo" assert_not_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
run $ABRA app deploy "$TEST_APP_DOMAIN" \ run $ABRA app deploy "$TEST_APP_DOMAIN" \
--no-input --no-converge-checks --force --debug --no-input --no-converge-checks --force
assert_failure assert_success
assert_output --regexp 'can not redeploy chaos version .*' + "${headHash:0:8}+U"
# current deployment
assert_output --regexp 'VERSION.*' + "${latestRelease}"
assert_output --regexp 'CHAOS.*' + "${headHash:0:8}+U"
# new deployment
assert_output --regexp 'VERSION.*' + "${latestRelease}"
assert_output --regexp 'CHAOS.*false'
# env version
assert_output --regexp 'CURRENT VERSION.*' + "${headHash:0:8}+U"
assert_output --regexp 'NEW VERSION.*' + "${latestRelease}"
run grep -q "TYPE=$TEST_RECIPE:${latestRelease}" \
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
assert_success
} }
@test "deploy then force commit deploy" { @test "deploy then force chaos commit deploy" {
headHash=$(_get_head_hash) headHash=$(_get_head_hash)
latestRelease=$(_latest_release) latestRelease=$(_latest_release)
@ -175,10 +225,17 @@ teardown(){
--no-input --no-converge-checks --force --no-input --no-converge-checks --force
assert_success assert_success
assert_output --partial 'DEPLOY OVERVIEW' # current deployment
assert_output --partial "CURRENT DEPLOYMENT ${latestRelease}" assert_output --regexp 'VERSION.*' + "${latestRelease}"
assert_output --partial "ENV VERSION ${latestRelease}" assert_output --regexp 'CHAOS.*false'
assert_output --partial "NEW DEPLOYMENT ${headHash:0:8}"
# new deployment
assert_output --regexp 'VERSION.*' + "${latestRelease}"
assert_output --regexp 'CHAOS.*' + "${headHash:0:8}"
# env version
assert_output --regexp 'CURRENT VERSION.*' + "${latestRelease}"
assert_output --regexp 'NEW VERSION.*' + "${headHash:0:8}"
run grep -q "TYPE=$TEST_RECIPE:${headHash:0:8}" \ run grep -q "TYPE=$TEST_RECIPE:${headHash:0:8}" \
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
@ -193,10 +250,17 @@ teardown(){
--no-input --no-converge-checks --chaos --no-input --no-converge-checks --chaos
assert_success assert_success
assert_output --partial 'NEW DEPLOY OVERVIEW' # current deployment
assert_output --partial "CURRENT DEPLOYMENT N/A" assert_output --regexp 'VERSION.*N/A'
assert_output --partial "ENV VERSION ${latestRelease}" assert_output --regexp 'CHAOS.*false'
assert_output --partial "NEW DEPLOYMENT ${headHash:0:8}"
# new deployment
assert_output --regexp 'VERSION.*' + "${latestRelease}"
assert_output --regexp 'CHAOS.*' + "${headHash:0:8}"
# env version
assert_output --regexp 'CURRENT VERSION.*' + "${latestRelease}"
assert_output --regexp 'NEW VERSION.*' + "${headHash:0:8}"
run bash -c 'echo "unstaged changes" >> "$ABRA_DIR/recipes/$TEST_RECIPE/foo"' run bash -c 'echo "unstaged changes" >> "$ABRA_DIR/recipes/$TEST_RECIPE/foo"'
assert_success assert_success
@ -206,28 +270,17 @@ teardown(){
--no-input --no-converge-checks --chaos --no-input --no-converge-checks --chaos
assert_success assert_success
assert_output --partial 'CHAOS DEPLOY OVERVIEW' # current deployment
assert_output --partial "CURRENT DEPLOYMENT ${headHash:0:8}" assert_output --regexp 'VERSION.*' + "${latestRelease}"
assert_output --partial "ENV VERSION ${headHash:0:8}" assert_output --regexp 'CHAOS.*' + "${headHash:0:8}"
assert_output --partial "NEW DEPLOYMENT ${headHash:0:8}+U"
run $ABRA app deploy "$TEST_APP_DOMAIN" \ # new deployment
--no-input --no-converge-checks --chaos assert_output --regexp 'VERSION.*' + "${latestRelease}"
assert_success assert_output --regexp 'CHAOS.*' + "${headHash:0:8}+U"
assert_output --partial 'CHAOS DEPLOY OVERVIEW' # env version
assert_output --partial "CURRENT DEPLOYMENT ${headHash:0:8}+U" assert_output --regexp 'CURRENT VERSION.*' + "${latestRelease}"
assert_output --partial "ENV VERSION ${headHash:0:8}+U" assert_output --regexp 'NEW VERSION.*' + "${headHash:0:8}+U"
assert_output --partial "NEW DEPLOYMENT ${headHash:0:8}+U"
run $ABRA app deploy "$TEST_APP_DOMAIN" \
--no-input --no-converge-checks --chaos
assert_success
assert_output --partial 'CHAOS DEPLOY OVERVIEW'
assert_output --partial "CURRENT DEPLOYMENT ${headHash:0:8}+U"
assert_output --partial "ENV VERSION ${headHash:0:8}+U"
assert_output --partial "NEW DEPLOYMENT ${headHash:0:8}+U"
run grep -q "TYPE=$TEST_RECIPE:${headHash:0:8}" \ run grep -q "TYPE=$TEST_RECIPE:${headHash:0:8}" \
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
@ -249,8 +302,19 @@ teardown(){
--no-input --no-converge-checks --force --no-input --no-converge-checks --force
assert_success assert_success
assert_output --partial 'REDEPLOY OVERVIEW' # current deployment
assert_output --partial "CURRENT DEPLOYMENT ${headHash:0:8}" assert_output --regexp 'VERSION.*' + "${latestRelease}"
assert_output --partial "ENV VERSION ${headHash:0:8}" assert_output --regexp 'CHAOS.*' + "${headHash:0:8}"
assert_output --partial "NEW DEPLOYMENT ${headHash:0:8}"
# new deployment
assert_output --regexp 'VERSION.*' + "${latestRelease}"
assert_output --regexp 'CHAOS.*false'
# env version
assert_output --regexp 'CURRENT VERSION.*' + "${headHash:0:8}"
assert_output --regexp 'NEW VERSION.*' + "${latestRelease}"
run grep -q "TYPE=$TEST_RECIPE:${latestRelease}" \
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
assert_success
} }

View File

@ -56,7 +56,7 @@ teardown(){
assert_success assert_success
} }
@test "create new app with version commit" { @test "create new app with chaos commit" {
tagHash=$(_get_tag_hash "0.3.0+1.21.0") tagHash=$(_get_tag_hash "0.3.0+1.21.0")
run $ABRA app new "$TEST_RECIPE" "$tagHash" \ run $ABRA app new "$TEST_RECIPE" "$tagHash" \
@ -129,10 +129,6 @@ teardown(){
assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo" assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
assert_equal "$(_git_status)" "?? foo" assert_equal "$(_git_status)" "?? foo"
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" status
assert_success
assert_output --partial 'foo'
run rm -rf "$ABRA_DIR/recipes/$TEST_RECIPE/foo" run rm -rf "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
assert_not_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo" assert_not_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
} }
@ -214,7 +210,7 @@ teardown(){
--chaos --chaos
assert_success assert_success
assert_exists "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" assert_exists "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
assert_output --partial "version: ${currentHash:0:8}" assert_output --partial "version: $latestRelease"
assert_output --partial "chaos: ${currentHash:0:8}" assert_output --partial "chaos: ${currentHash:0:8}"
assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo" assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
@ -242,7 +238,7 @@ teardown(){
--chaos --chaos
assert_success assert_success
assert_exists "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" assert_exists "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
assert_output --partial "version: ${currentHash:0:8}" assert_output --partial "version: unknown"
assert_output --partial "chaos: ${currentHash:0:8}" assert_output --partial "chaos: ${currentHash:0:8}"
assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo" assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo"

View File

@ -153,7 +153,7 @@ teardown(){
} }
# bats test_tags=slow # bats test_tags=slow
@test "rollback chaos deployment is not possible" { @test "rollback chaos deployment" {
tagHash=$(_get_tag_hash "0.2.0+1.21.0") tagHash=$(_get_tag_hash "0.2.0+1.21.0")
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" checkout "$tagHash" run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" checkout "$tagHash"
assert_success assert_success
@ -163,8 +163,17 @@ teardown(){
assert_output --partial "${tagHash:0:8}" assert_output --partial "${tagHash:0:8}"
run $ABRA app rollback "$TEST_APP_DOMAIN" "0.1.1+1.20.2" --no-input --no-converge-checks run $ABRA app rollback "$TEST_APP_DOMAIN" "0.1.1+1.20.2" --no-input --no-converge-checks
assert_failure assert_success
assert_output --partial 'current deployment' + "${tagHash:0:8}" + 'is not a known version' assert_output --partial "0.1.1+1.20.2"
assert_output --partial "${tagHash:0:8}"
run $ABRA app rollback "$TEST_APP_DOMAIN" "0.1.0+1.20.0" --no-input --no-converge-checks
assert_success
assert_output --partial "0.1.0+1.20.0"
tagHash=$(_get_tag_hash "0.1.1+1.20.2")
refute_output --partial "${tagHash:0:8}"
assert_output --partial "false"
} }
# bats test_tags=slow # bats test_tags=slow

View File

@ -24,7 +24,7 @@ teardown(){
_reset_recipe _reset_recipe
} }
@test "deploy then rollback" { @test "deploy then rollback" {
run $ABRA app deploy "$TEST_APP_DOMAIN" "0.2.0+1.21.0" \ run $ABRA app deploy "$TEST_APP_DOMAIN" "0.2.0+1.21.0" \
--no-input --no-converge-checks --no-input --no-converge-checks
assert_success assert_success
@ -33,17 +33,23 @@ teardown(){
--no-input --no-converge-checks --no-input --no-converge-checks
assert_success assert_success
assert_output --partial 'DOWNGRADE OVERVIEW' # current deployment
assert_output --partial 'CURRENT DEPLOYMENT 0.2.0+1.21.0' assert_output --regexp 'VERSION.*' + "0.2.0+1.21.0"
assert_output --partial 'ENV VERSION 0.2.0+1.21.0' assert_output --regexp 'CHAOS.*false'
assert_output --partial 'NEW DEPLOYMENT 0.1.0+1.20.0'
# rollback
assert_output --regexp 'VERSION.*' + "0.1.0+1.20.0"
# env version
assert_output --regexp 'CURRENT VERSION.*' + "0.2.0+1.21.0"
assert_output --regexp 'NEW VERSION.*' + "0.1.0+1.20.0"
run grep -q "TYPE=$TEST_RECIPE:0.1.0+1.20.0" \ run grep -q "TYPE=$TEST_RECIPE:0.1.0+1.20.0" \
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
assert_success assert_success
} }
@test "force rollback" { @test "force rollback" {
run $ABRA app deploy "$TEST_APP_DOMAIN" "0.2.0+1.21.0" \ run $ABRA app deploy "$TEST_APP_DOMAIN" "0.2.0+1.21.0" \
--no-input --no-converge-checks --no-input --no-converge-checks
assert_success assert_success
@ -52,10 +58,16 @@ teardown(){
--no-input --no-converge-checks --force --no-input --no-converge-checks --force
assert_success assert_success
assert_output --partial 'REDEPLOY OVERVIEW' # current deployment
assert_output --partial 'CURRENT DEPLOYMENT 0.2.0+1.21.0' assert_output --regexp 'VERSION.*' + "0.2.0+1.21.0"
assert_output --partial 'ENV VERSION 0.2.0+1.21.0' assert_output --regexp 'CHAOS.*false'
assert_output --partial 'NEW DEPLOYMENT 0.2.0+1.21.0'
# rollback
assert_output --regexp 'VERSION.*' + "0.2.0+1.21.0"
# env version
assert_output --regexp 'CURRENT VERSION.*' + "0.2.0+1.21.0"
assert_output --regexp 'NEW VERSION.*' + "0.2.0+1.21.0"
run grep -q "TYPE=$TEST_RECIPE:0.2.0+1.21.0" \ run grep -q "TYPE=$TEST_RECIPE:0.2.0+1.21.0" \
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
@ -73,10 +85,16 @@ teardown(){
--no-input --no-converge-checks --no-input --no-converge-checks
assert_success assert_success
assert_output --partial 'DOWNGRADE OVERVIEW' # current deployment
assert_output --partial 'CURRENT DEPLOYMENT 0.2.0+1.21.0' assert_output --regexp 'VERSION.*' + "0.2.0+1.21.0"
assert_output --partial 'ENV VERSION N/A' assert_output --regexp 'CHAOS.*false'
assert_output --partial 'NEW DEPLOYMENT 0.1.0+1.20.0'
# rollback
assert_output --regexp 'VERSION.*' + "0.1.0+1.20.0"
# env version
assert_output --regexp 'CURRENT VERSION.*N/A'
assert_output --regexp 'NEW VERSION.*' + "0.2.0+1.21.0"
run grep -q "TYPE=$TEST_RECIPE:${latestRelease}" \ run grep -q "TYPE=$TEST_RECIPE:${latestRelease}" \
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"

View File

@ -41,11 +41,6 @@ teardown(){
run $ABRA app secret generate "$TEST_APP_DOMAIN" run $ABRA app secret generate "$TEST_APP_DOMAIN"
assert_failure assert_failure
assert_output --partial 'missing arguments'
run $ABRA app secret generate "$TEST_APP_DOMAIN" test_pass_one
assert_failure
assert_output --partial 'missing arguments'
run $ABRA app secret generate "$TEST_APP_DOMAIN" testSecret testVersion --all run $ABRA app secret generate "$TEST_APP_DOMAIN" testSecret testVersion --all
assert_failure assert_failure

View File

@ -92,6 +92,9 @@ teardown(){
run $ABRA app undeploy "$TEST_APP_DOMAIN" --no-input run $ABRA app undeploy "$TEST_APP_DOMAIN" --no-input
assert_success assert_success
# NOTE(d1): ensure not chaos undeploy
assert_output --partial 'false'
} }
# bats test_tags=slow # bats test_tags=slow

View File

@ -33,10 +33,13 @@ teardown(){
run $ABRA app undeploy "$TEST_APP_DOMAIN" --no-input run $ABRA app undeploy "$TEST_APP_DOMAIN" --no-input
assert_success assert_success
assert_output --partial 'UNDEPLOY OVERVIEW' # current deployment
assert_output --partial 'CURRENT DEPLOYMENT 0.1.0+1.20.0' assert_output --regexp 'VERSION.*' + "0.1.0+1.20.0"
assert_output --partial 'ENV VERSION 0.1.0+1.20.0' assert_output --regexp 'CHAOS.*false'
assert_output --partial 'NEW DEPLOYMENT N/A'
# env version
assert_output --regexp 'CURRENT VERSION.*' + "0.1.0+1.20.0"
assert_output --regexp 'NEW VERSION.*' + "0.1.0+1.20.0"
run grep -q "TYPE=$TEST_RECIPE:0.1.0+1.20.0" \ run grep -q "TYPE=$TEST_RECIPE:0.1.0+1.20.0" \
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
@ -54,10 +57,13 @@ teardown(){
run $ABRA app undeploy "$TEST_APP_DOMAIN" --no-input run $ABRA app undeploy "$TEST_APP_DOMAIN" --no-input
assert_success assert_success
assert_output --partial 'UNDEPLOY OVERVIEW' # current deployment
assert_output --partial "CURRENT DEPLOYMENT ${headHash:0:8}" assert_output --regexp 'VERSION.*' + "${latestRelease}"
assert_output --partial "ENV VERSION ${headHash:0:8}" assert_output --regexp 'CHAOS.*' + "${headHash:0:8}"
assert_output --partial 'NEW DEPLOYMENT N/A'
# env version
assert_output --regexp 'CURRENT VERSION.*' + "${latestRelease}"
assert_output --regexp 'NEW VERSION.*' + "${headHash:0:8}"
run grep -q "TYPE=$TEST_RECIPE:${headHash:0:8}" \ run grep -q "TYPE=$TEST_RECIPE:${headHash:0:8}" \
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
@ -66,6 +72,7 @@ teardown(){
@test "chaos deploy with unstaged commits and undeploy" { @test "chaos deploy with unstaged commits and undeploy" {
headHash=$(_get_head_hash) headHash=$(_get_head_hash)
latestRelease=$(_latest_release)
run bash -c 'echo "unstaged changes" >> "$ABRA_DIR/recipes/$TEST_RECIPE/foo"' run bash -c 'echo "unstaged changes" >> "$ABRA_DIR/recipes/$TEST_RECIPE/foo"'
assert_success assert_success
@ -78,10 +85,13 @@ teardown(){
run $ABRA app undeploy "$TEST_APP_DOMAIN" --no-input run $ABRA app undeploy "$TEST_APP_DOMAIN" --no-input
assert_success assert_success
assert_output --partial 'UNDEPLOY OVERVIEW' # current deployment
assert_output --partial "CURRENT DEPLOYMENT ${headHash:0:8}+U" assert_output --regexp 'VERSION.*' + "${latestRelease}"
assert_output --partial "ENV VERSION ${headHash:0:8}+U" assert_output --regexp 'CHAOS.*' + "${headHash:0:8}+U"
assert_output --partial 'NEW DEPLOYMENT N/A'
# env version
assert_output --regexp 'CURRENT VERSION.*' + "${latestRelease}"
assert_output --regexp 'NEW VERSION.*' + "${headHash:0:8}+U"
run grep -q "TYPE=$TEST_RECIPE:${headHash:0:8}" \ run grep -q "TYPE=$TEST_RECIPE:${headHash:0:8}" \
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"

View File

@ -205,7 +205,7 @@ teardown(){
} }
# bats test_tags=slow # bats test_tags=slow
@test "upgrade commit deployment not possible" { @test "upgrade chaos deployment" {
tagHash=$(_get_tag_hash "0.1.0+1.20.0") tagHash=$(_get_tag_hash "0.1.0+1.20.0")
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" checkout "$tagHash" run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" checkout "$tagHash"
assert_success assert_success
@ -215,8 +215,17 @@ teardown(){
assert_output --partial "${tagHash:0:8}" assert_output --partial "${tagHash:0:8}"
run $ABRA app upgrade "$TEST_APP_DOMAIN" "0.1.1+1.20.2" --no-input --no-converge-checks run $ABRA app upgrade "$TEST_APP_DOMAIN" "0.1.1+1.20.2" --no-input --no-converge-checks
assert_failure assert_success
assert_output --partial "not a known version" assert_output --partial "0.1.1+1.20.2"
assert_output --partial "${tagHash:0:8}"
run $ABRA app upgrade "$TEST_APP_DOMAIN" "0.2.0+1.21.0" --no-input --no-converge-checks
assert_success
assert_output --partial "0.2.0+1.21.0"
tagHash=$(_get_tag_hash "0.1.1+1.20.2")
refute_output --partial "${tagHash:0:8}"
assert_output --partial "false"
} }
@test "chaos commit upgrade not possible" { @test "chaos commit upgrade not possible" {

View File

@ -31,17 +31,24 @@ teardown(){
--no-input --no-converge-checks --no-input --no-converge-checks
assert_success assert_success
assert_output --partial 'UPGRADE OVERVIEW' # current deployment
assert_output --partial 'CURRENT DEPLOYMENT 0.1.0+1.20.0' assert_output --regexp 'VERSION.*' + "0.1.0+1.20.0"
assert_output --partial 'ENV VERSION 0.1.0+1.20.0' assert_output --regexp 'CHAOS.*false'
assert_output --partial 'NEW DEPLOYMENT 0.2.0+1.21.0'
# upgrade
assert_output --regexp 'VERSION.*' + "0.2.0+1.21.0"
assert_output --regexp 'CHAOS.*false'
# env version
assert_output --regexp 'CURRENT VERSION.*' + "0.1.0+1.20.0"
assert_output --regexp 'NEW VERSION.*' + "0.2.0+1.21.0"
run grep -q "TYPE=$TEST_RECIPE:0.2.0+1.21.0" \ run grep -q "TYPE=$TEST_RECIPE:0.2.0+1.21.0" \
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
assert_success assert_success
} }
@test "force upgrade" { @test "force upgrade" {
run $ABRA app deploy "$TEST_APP_DOMAIN" "0.2.0+1.21.0" \ run $ABRA app deploy "$TEST_APP_DOMAIN" "0.2.0+1.21.0" \
--no-input --no-converge-checks --no-input --no-converge-checks
assert_success assert_success
@ -50,10 +57,17 @@ teardown(){
--no-input --no-converge-checks --force --no-input --no-converge-checks --force
assert_success assert_success
assert_output --partial 'REDEPLOY OVERVIEW' # current deployment
assert_output --partial 'CURRENT DEPLOYMENT 0.2.0+1.21.0' assert_output --regexp 'VERSION.*' + "0.2.0+1.21.0"
assert_output --partial 'ENV VERSION 0.2.0+1.21.0' assert_output --regexp 'CHAOS.*false'
assert_output --partial 'NEW DEPLOYMENT 0.2.0+1.21.0'
# upgrade
assert_output --regexp 'VERSION.*' + "0.2.0+1.21.0"
assert_output --regexp 'CHAOS.*false'
# env version
assert_output --regexp 'CURRENT VERSION.*' + "0.2.0+1.21.0"
assert_output --regexp 'NEW VERSION.*' + "0.2.0+1.21.0"
run grep -q "TYPE=$TEST_RECIPE:0.2.0+1.21.0" \ run grep -q "TYPE=$TEST_RECIPE:0.2.0+1.21.0" \
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
@ -73,10 +87,17 @@ teardown(){
--no-input --no-converge-checks --force --no-input --no-converge-checks --force
assert_success assert_success
assert_output --partial 'UPGRADE OVERVIEW' # current deployment
assert_output --partial 'CURRENT DEPLOYMENT 0.2.0+1.21.0' assert_output --regexp 'VERSION.*' + "0.2.0+1.21.0"
assert_output --partial 'ENV VERSION N/A' assert_output --regexp 'CHAOS.*false'
assert_output --partial 'NEW DEPLOYMENT 0.3.1+1.21.0'
# upgrade
assert_output --regexp 'VERSION.*' + "0.2.0+1.21.0"
assert_output --regexp 'CHAOS.*false'
# env version
assert_output --regexp 'CURRENT VERSION.*N/A'
assert_output --regexp 'NEW VERSION.*' + "0.2.0+1.21.0"
run grep -q "TYPE=$TEST_RECIPE:${latestRelease}" \ run grep -q "TYPE=$TEST_RECIPE:${latestRelease}" \
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"

View File

@ -30,15 +30,6 @@ _undeploy_app() {
assert_output --partial 'unknown' assert_output --partial 'unknown'
} }
_undeploy_app2() {
run $ABRA app undeploy "$1" --no-input
run $ABRA app ls --server "$TEST_SERVER" --status
assert_success
assert_output --partial "$1"
assert_output --partial 'unknown'
}
_rm_app() { _rm_app() {
# NOTE(d1): not asserting outcomes on teardown here since some might fail # NOTE(d1): not asserting outcomes on teardown here since some might fail
# depending on what the test created. all commands run through anyway # depending on what the test created. all commands run through anyway

View File

@ -38,8 +38,6 @@ _set_git_author() {
} }
_git_commit() { _git_commit() {
_set_git_author
run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" add . run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" add .
assert_success assert_success