From 518c5795f4078988b63a9912fd9690afd71612bc Mon Sep 17 00:00:00 2001 From: decentral1se Date: Wed, 24 Jul 2024 16:07:08 +0200 Subject: [PATCH 1/3] fix: avoid overwriting non version env vars See https://git.coopcloud.tech/coop-cloud/organising/issues/630 --- cli/app/deploy.go | 2 +- cli/app/new.go | 2 +- cli/app/rollback.go | 2 +- cli/app/upgrade.go | 2 +- pkg/app/app.go | 12 ++++++--- pkg/envfile/envfile_test.go | 27 ++++++++++++++----- pkg/test/test.go | 5 ++-- .../servers/evil.corp/ecloud.env | 1 + 8 files changed, 36 insertions(+), 17 deletions(-) diff --git a/cli/app/deploy.go b/cli/app/deploy.go index 7802dd0c..8e8867a1 100644 --- a/cli/app/deploy.go +++ b/cli/app/deploy.go @@ -258,7 +258,7 @@ EXAMPLE: app.Recipe.Version = chaosVersion } log.Debugf("choosing %s as version to save to env file", app.Recipe.Version) - if err := app.WriteRecipeVersion(app.Recipe.Version); err != nil { + if err := app.WriteRecipeVersion(app.Recipe.Version, false); err != nil { log.Fatalf("writing new recipe version in env file: %s", err) } diff --git a/cli/app/new.go b/cli/app/new.go index bc2614c9..67d586c7 100644 --- a/cli/app/new.go +++ b/cli/app/new.go @@ -219,7 +219,7 @@ var appNewCommand = cli.Command{ } log.Debugf("choosing %s as version to save to env file", version) - if err := app.WriteRecipeVersion(version); err != nil { + if err := app.WriteRecipeVersion(version, false); err != nil { log.Fatalf("writing new recipe version in env file: %s", err) } diff --git a/cli/app/rollback.go b/cli/app/rollback.go index 879af6a0..bb714993 100644 --- a/cli/app/rollback.go +++ b/cli/app/rollback.go @@ -225,7 +225,7 @@ EXAMPLE: app.Recipe.Version = chosenDowngrade log.Debugf("choosing %s as version to save to env file", app.Recipe.Version) - if err := app.WriteRecipeVersion(app.Recipe.Version); err != nil { + if err := app.WriteRecipeVersion(app.Recipe.Version, false); err != nil { log.Fatalf("writing new recipe version in env file: %s", err) } diff --git a/cli/app/upgrade.go b/cli/app/upgrade.go index 5e36b584..807110af 100644 --- a/cli/app/upgrade.go +++ b/cli/app/upgrade.go @@ -286,7 +286,7 @@ EXAMPLE: app.Recipe.Version = chosenUpgrade log.Debugf("choosing %s as version to save to env file", app.Recipe.Version) - if err := app.WriteRecipeVersion(app.Recipe.Version); err != nil { + if err := app.WriteRecipeVersion(app.Recipe.Version, false); err != nil { log.Fatalf("writing new recipe version in env file: %s", err) } diff --git a/pkg/app/app.go b/pkg/app/app.go index b11047ae..25c00a99 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -569,7 +569,7 @@ func ReadAbraShCmdNames(abraSh string) ([]string, error) { return cmdNames, nil } -func (a App) WriteRecipeVersion(version string) error { +func (a App) WriteRecipeVersion(version string, dryRun bool) error { file, err := os.Open(a.Path) if err != nil { return err @@ -581,7 +581,7 @@ func (a App) WriteRecipeVersion(version string) error { lines := []string{} for scanner.Scan() { line := scanner.Text() - if !strings.Contains(line, "RECIPE=") && !strings.Contains(line, "TYPE") { + if !strings.HasPrefix(line, "RECIPE=") && !strings.HasPrefix(line, "TYPE=") { lines = append(lines, line) continue } @@ -606,8 +606,12 @@ func (a App) WriteRecipeVersion(version string) error { log.Fatal(err) } - if err := os.WriteFile(a.Path, []byte(strings.Join(lines, "\n")), os.ModePerm); err != nil { - log.Fatal(err) + if !dryRun { + if err := os.WriteFile(a.Path, []byte(strings.Join(lines, "\n")), os.ModePerm); err != nil { + log.Fatal(err) + } + } else { + log.Debugf("skipping writing version %s because dry run", version) } if !skipped { diff --git a/pkg/envfile/envfile_test.go b/pkg/envfile/envfile_test.go index ffab3ee4..3fca108e 100644 --- a/pkg/envfile/envfile_test.go +++ b/pkg/envfile/envfile_test.go @@ -11,6 +11,7 @@ import ( "coopcloud.tech/abra/pkg/envfile" "coopcloud.tech/abra/pkg/recipe" testPkg "coopcloud.tech/abra/pkg/test" + "github.com/stretchr/testify/assert" ) func TestGetAllFoldersInDirectory(t *testing.T) { @@ -43,13 +44,7 @@ func TestReadEnv(t *testing.T) { t.Fatal(err) } if !reflect.DeepEqual(env, testPkg.ExpectedAppEnv) { - t.Fatalf( - "did not get expected application settings. Expected: DOMAIN=%s RECIPE=%s; Got: DOMAIN=%s RECIPE=%s", - testPkg.ExpectedAppEnv["DOMAIN"], - testPkg.ExpectedAppEnv["RECIPE"], - env["DOMAIN"], - env["RECIPE"], - ) + t.Fatal("did not get expected application settings") } } @@ -228,3 +223,21 @@ func TestEnvVarModifiersIncluded(t *testing.T) { } } } + +func TestNoOverwriteNonVersionEnvVars(t *testing.T) { + app, err := appPkg.GetApp(testPkg.ExpectedAppFiles, testPkg.AppName) + if err != nil { + t.Fatal(err) + } + + if err := app.WriteRecipeVersion("1.3.12", true); err != nil { + t.Fatal(err) + } + + app, err = appPkg.GetApp(testPkg.ExpectedAppFiles, testPkg.AppName) + if err != nil { + t.Fatal(err) + } + + assert.NotEqual(t, app.Env["SMTP_AUTHTYPE"], "login:1.3.12") +} diff --git a/pkg/test/test.go b/pkg/test/test.go index 1109a5dd..92e88656 100644 --- a/pkg/test/test.go +++ b/pkg/test/test.go @@ -27,8 +27,9 @@ var ( ) var ExpectedAppEnv = envfile.AppEnv{ - "DOMAIN": "ecloud.evil.corp", - "RECIPE": "ecloud", + "DOMAIN": "ecloud.evil.corp", + "RECIPE": "ecloud", + "SMTP_AUTHTYPE": "login", } var ExpectedApp = appPkg.App{ diff --git a/tests/resources/valid_abra_config/servers/evil.corp/ecloud.env b/tests/resources/valid_abra_config/servers/evil.corp/ecloud.env index feb7610c..8c6b5068 100644 --- a/tests/resources/valid_abra_config/servers/evil.corp/ecloud.env +++ b/tests/resources/valid_abra_config/servers/evil.corp/ecloud.env @@ -1,2 +1,3 @@ RECIPE=ecloud DOMAIN=ecloud.evil.corp +SMTP_AUTHTYPE=login -- 2.47.2 From fd8652e26dbc0ef38e1cccfc010f3cd255d1ccb1 Mon Sep 17 00:00:00 2001 From: decentral1se Date: Wed, 24 Jul 2024 16:08:09 +0200 Subject: [PATCH 2/3] fix: --chaos/--offline for `abra app ps` See https://git.coopcloud.tech/coop-cloud/organising/issues/628 See https://git.coopcloud.tech/coop-cloud/organising/issues/629 --- cli/app/ps.go | 11 ++--- tests/integration/app_ps.bats | 78 +++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 7 deletions(-) diff --git a/cli/app/ps.go b/cli/app/ps.go index b094eafd..c8149b2c 100644 --- a/cli/app/ps.go +++ b/cli/app/ps.go @@ -30,12 +30,14 @@ var appPsCommand = cli.Command{ Flags: []cli.Flag{ internal.MachineReadableFlag, internal.DebugFlag, + internal.ChaosFlag, + internal.OfflineFlag, }, Before: internal.SubCommandBefore, BashComplete: autocomplete.AppNameComplete, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) - if err := app.Recipe.Ensure(false, false); err != nil { + if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { log.Fatal(err) } @@ -56,12 +58,7 @@ var appPsCommand = cli.Command{ chaosVersion := config.CHAOS_DEFAULT statuses, err := appPkg.GetAppStatuses([]appPkg.App{app}, true) if statusMeta, ok := statuses[app.StackName()]; ok { - isChaos, exists := statusMeta["chaos"] - if exists && isChaos == "false" { - if _, err := app.Recipe.EnsureVersion(deployMeta.Version); err != nil { - log.Fatal(err) - } - } else { + if isChaos, exists := statusMeta["chaos"]; exists && isChaos == "true" { chaosVersion, err = app.Recipe.ChaosVersion() if err != nil { log.Fatal(err) diff --git a/tests/integration/app_ps.bats b/tests/integration/app_ps.bats index b0f64f51..fad17c78 100644 --- a/tests/integration/app_ps.bats +++ b/tests/integration/app_ps.bats @@ -31,6 +31,84 @@ teardown(){ assert_output --partial 'cannot find app' } +# bats test_tags=slow +@test "retrieve recipe if missing" { + _deploy_app + + run rm -rf "$ABRA_DIR/recipes/$TEST_RECIPE" + assert_success + assert_not_exists "$ABRA_DIR/recipes/$TEST_RECIPE" + + run $ABRA app ps "$TEST_APP_DOMAIN" + assert_success + + assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE" +} + +# bats test_tags=slow +@test "bail if unstaged changes and no --chaos" { + _deploy_app + + run bash -c "echo foo >> $ABRA_DIR/recipes/$TEST_RECIPE/foo" + assert_success + assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo" + + run $ABRA app ps "$TEST_APP_DOMAIN" + assert_failure + assert_output --partial 'locally unstaged changes' + + run rm -rf "$ABRA_DIR/recipes/$TEST_RECIPE/foo" + assert_not_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo" +} + +# bats test_tags=slow +@test "do not bail if unstaged changes and --chaos" { + _deploy_app + + run bash -c "echo foo >> $ABRA_DIR/recipes/$TEST_RECIPE/foo" + assert_success + assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo" + + run $ABRA app ps --chaos "$TEST_APP_DOMAIN" + assert_success + + run rm -rf "$ABRA_DIR/recipes/$TEST_RECIPE/foo" + assert_not_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo" +} + +# bats test_tags=slow +@test "ensure recipe up to date if no --offline" { + _deploy_app + + wantHash=$(_get_n_hash 3) + + run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" reset --hard HEAD~3 + assert_success + + assert_equal $(_get_current_hash) "$wantHash" + + run $ABRA app ps "$TEST_APP_DOMAIN" + assert_success + + assert_equal $(_get_head_hash) $(_get_current_hash) +} + +@test "ensure recipe not up to date if --offline" { + _deploy_app + + _ensure_env_version "0.1.0+1.20.0" + latestRelease=$(_latest_release) + + run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" tag -d "$latestRelease" + assert_success + + run $ABRA app ps --offline "$TEST_APP_DOMAIN" + assert_success + + run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" tag -l + refute_output --partial "$latestRelease" +} + @test "error if not deployed" { run $ABRA app ps "$TEST_APP_DOMAIN" assert_failure -- 2.47.2 From c65be64e7d6b0d4d18a8f5e4b4435af10a4be07e Mon Sep 17 00:00:00 2001 From: decentral1se Date: Wed, 24 Jul 2024 16:08:37 +0200 Subject: [PATCH 3/3] fix: dont checkout version for `abra app undeploy` See https://git.coopcloud.tech/coop-cloud/organising/issues/628 --- cli/app/undeploy.go | 4 +-- tests/integration/app_undeploy.bats | 50 +++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/cli/app/undeploy.go b/cli/app/undeploy.go index 43ea2415..c48b7aad 100644 --- a/cli/app/undeploy.go +++ b/cli/app/undeploy.go @@ -68,6 +68,7 @@ var appUndeployCommand = cli.Command{ Flags: []cli.Flag{ internal.DebugFlag, internal.NoInputFlag, + internal.OfflineFlag, pruneFlag, }, Before: internal.SubCommandBefore, @@ -82,9 +83,6 @@ any previously attached volumes as eligible for pruning once undeployed. Passing "-p/--prune" does not remove those volumes.`, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) - if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { - log.Fatal(err) - } stackName := app.StackName() cl, err := client.New(app.Server) diff --git a/tests/integration/app_undeploy.bats b/tests/integration/app_undeploy.bats index 79fa80bf..6058a59e 100644 --- a/tests/integration/app_undeploy.bats +++ b/tests/integration/app_undeploy.bats @@ -18,6 +18,7 @@ setup(){ } teardown(){ + _reset_recipe _undeploy_app } @@ -31,12 +32,61 @@ teardown(){ assert_output --partial 'cannot find app' } +# bats test_tags=slow +@test "ensure recipe up to date if no --offline" { + _deploy_app + + wantHash=$(_get_n_hash 3) + + run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" reset --hard HEAD~3 + assert_success + + assert_equal $(_get_current_hash) "$wantHash" + + run $ABRA app undeploy "$TEST_APP_DOMAIN" --no-input + assert_success + + assert_equal $(_get_head_hash) $(_get_current_hash) +} + +# bats test_tags=slow +@test "ensure recipe not up to date if --offline" { + _deploy_app + + _ensure_env_version "0.1.0+1.20.0" + latestRelease=$(_latest_release) + + run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" tag -d "$latestRelease" + assert_success + + run $ABRA app undeploy "$TEST_APP_DOMAIN" --no-input --offline + assert_success + + run git -C "$ABRA_DIR/recipes/$TEST_RECIPE" tag -l + refute_output --partial "$latestRelease" +} + @test "error if not deployed" { run $ABRA app undeploy "$TEST_APP_DOMAIN" assert_failure assert_output --partial 'is not deployed' } +# bats test_tags=slow +@test "do not bail if unstaged changes (only query runtime)" { + _deploy_app + + run bash -c "echo foo >> $ABRA_DIR/recipes/$TEST_RECIPE/foo" + assert_success + assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo" + + run $ABRA app undeploy "$TEST_APP_DOMAIN" --no-input + assert_success + + run rm -rf "$ABRA_DIR/recipes/$TEST_RECIPE/foo" + assert_not_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo" +} + # bats test_tags=slow @test "undeploy app" { run $ABRA app deploy "$TEST_APP_DOMAIN" --no-input -- 2.47.2