diff --git a/cli/app/deploy.go b/cli/app/deploy.go index 7a17fb8b..e3e6e2c7 100644 --- a/cli/app/deploy.go +++ b/cli/app/deploy.go @@ -59,6 +59,11 @@ EXAMPLE: log.Fatal("cannot use and --chaos together") } + if specificVersion != "" { + log.Debugf("overriding env file version (%s) with %s", app.Recipe.Version, specificVersion) + app.Recipe.Version = specificVersion + } + if specificVersion == "" && app.Recipe.Version != "" { log.Debugf("retrieved %s as version from env file", app.Recipe.Version) specificVersion = app.Recipe.Version diff --git a/cli/app/rollback.go b/cli/app/rollback.go index 5e41f9c9..879af6a0 100644 --- a/cli/app/rollback.go +++ b/cli/app/rollback.go @@ -53,6 +53,12 @@ EXAMPLE: app := internal.ValidateApp(c) stackName := app.StackName() + specificVersion := c.Args().Get(1) + if specificVersion != "" { + log.Debugf("overriding env file version (%s) with %s", app.Recipe.Version, specificVersion) + app.Recipe.Version = specificVersion + } + if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { log.Fatal(err) } @@ -88,8 +94,6 @@ EXAMPLE: warnMessages = append(warnMessages, fmt.Sprintf("failed to determine deployed version of %s", app.Name)) } - specificVersion := c.Args().Get(1) - if specificVersion != "" { parsedDeployedVersion, err := tagcmp.Parse(deployMeta.Version) if err != nil { diff --git a/cli/app/secret.go b/cli/app/secret.go index a6751cca..5d4a09c7 100644 --- a/cli/app/secret.go +++ b/cli/app/secret.go @@ -178,6 +178,9 @@ Example: `, Action: func(c *cli.Context) error { app := internal.ValidateApp(c) + if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { + log.Fatal(err) + } if len(c.Args()) != 4 { internal.ShowSubcommandHelpAndError(c, errors.New("missing arguments?")) diff --git a/cli/app/upgrade.go b/cli/app/upgrade.go index 2e4ff78f..5e36b584 100644 --- a/cli/app/upgrade.go +++ b/cli/app/upgrade.go @@ -53,6 +53,12 @@ EXAMPLE: app := internal.ValidateApp(c) stackName := app.StackName() + specificVersion := c.Args().Get(1) + if specificVersion != "" { + log.Debugf("overriding env file version (%s) with %s", app.Recipe.Version, specificVersion) + app.Recipe.Version = specificVersion + } + if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil { log.Fatal(err) } @@ -88,7 +94,6 @@ EXAMPLE: warnMessages = append(warnMessages, fmt.Sprintf("failed to determine deployed version of %s", app.Name)) } - specificVersion := c.Args().Get(1) if specificVersion != "" { parsedDeployedVersion, err := tagcmp.Parse(deployMeta.Version) if err != nil { diff --git a/pkg/app/app.go b/pkg/app/app.go index 1da87c66..ccd63aae 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -599,5 +599,11 @@ func (a App) WriteRecipeVersion(version string) error { log.Fatal(err) } - return os.WriteFile(a.Path, []byte(strings.Join(lines, "\n")), os.ModePerm) + if err := os.WriteFile(a.Path, []byte(strings.Join(lines, "\n")), os.ModePerm); err != nil { + log.Fatal(err) + } + + log.Infof("version %s saved to %s.env", version, a.Domain) + + return nil } diff --git a/pkg/recipe/git.go b/pkg/recipe/git.go index 60b20c4f..69067ad4 100644 --- a/pkg/recipe/git.go +++ b/pkg/recipe/git.go @@ -32,6 +32,7 @@ func (r Recipe) Ensure(chaos bool, offline bool) error { } } if r.Version != "" { + log.Debugf("ensuring version %s", r.Version) if _, err := r.EnsureVersion(r.Version); err != nil { return err } diff --git a/pkg/recipe/recipe.go b/pkg/recipe/recipe.go index df8134f3..e00662ee 100644 --- a/pkg/recipe/recipe.go +++ b/pkg/recipe/recipe.go @@ -127,6 +127,9 @@ func Get(name string) Recipe { version := "" if strings.Contains(name, ":") { split := strings.Split(name, ":") + if len(split) > 2 { + log.Fatalf("version seems invalid: %s", name) + } name = split[0] version = split[1] } diff --git a/pkg/upstream/stack/stack.go b/pkg/upstream/stack/stack.go index 8576f61f..f38f5e39 100644 --- a/pkg/upstream/stack/stack.go +++ b/pkg/upstream/stack/stack.go @@ -175,6 +175,7 @@ func pruneServices(ctx context.Context, cl *dockerClient.Client, namespace conve pruneServices = append(pruneServices, service) } } + removeServices(ctx, cl, pruneServices) } @@ -255,10 +256,12 @@ func deployCompose(ctx context.Context, cl *dockerClient.Client, opts Deploy, co log.Infof("waiting for %s to deploy... please hold 🤚", appName) - if err := waitOnServices(ctx, cl, serviceIDs, appName); err == nil { - log.Infof("successfully deployed %s", appName) + if err := waitOnServices(ctx, cl, serviceIDs, appName); err != nil { + return err } + log.Infof("successfully deployed %s", appName) + return nil } @@ -395,7 +398,7 @@ func deployServices( ) if service, exists := existingServiceMap[name]; exists { - log.Infof("updating service %s (id: %s)", name, service.ID) + log.Infof("updating %s", name) updateOpts := types.ServiceUpdateOptions{EncodedRegistryAuth: encodedAuth} @@ -430,7 +433,7 @@ func deployServices( response, err := cl.ServiceUpdate(ctx, service.ID, service.Version, serviceSpec, updateOpts) if err != nil { - return nil, errors.Wrapf(err, "failed to update service %s", name) + return nil, errors.Wrapf(err, "failed to update %s", name) } for _, warning := range response.Warnings { @@ -439,7 +442,7 @@ func deployServices( serviceIDs = append(serviceIDs, service.ID) } else { - log.Infof("creating service %s", name) + log.Infof("creating %s", name) createOpts := types.ServiceCreateOptions{EncodedRegistryAuth: encodedAuth} @@ -450,7 +453,7 @@ func deployServices( serviceCreateResponse, err := cl.ServiceCreate(ctx, serviceSpec, createOpts) if err != nil { - return nil, errors.Wrapf(err, "failed to create service %s", name) + return nil, errors.Wrapf(err, "failed to create %s", name) } serviceIDs = append(serviceIDs, serviceCreateResponse.ID) @@ -510,13 +513,14 @@ func WaitOnService(ctx context.Context, cl *dockerClient.Client, serviceID, appN case err := <-errChan: return err case <-sigintChannel: - return fmt.Errorf(fmt.Sprintf(` + return fmt.Errorf(` Not waiting for %s to deploy. The deployment is ongoing... If you want to stop the deployment, try: - abra app undeploy %s`, appName, appName)) + + abra app undeploy %s`, appName, appName) case <-time.After(timeout): - return fmt.Errorf(fmt.Sprintf(` + return fmt.Errorf(` %s has not converged (%s second timeout reached). This does not necessarily mean your deployment has failed, it may just be that @@ -530,7 +534,7 @@ You can track latest deployment status with: And inspect the logs with: abra app logs %s -`, appName, timeout, appName, appName)) +`, appName, timeout, appName, appName) } } @@ -548,7 +552,7 @@ func GetStacks(cl *dockerClient.Client) ([]*formatter.Stack, error) { labels := service.Spec.Labels name, ok := labels[convert.LabelNamespace] if !ok { - return nil, errors.Errorf("cannot get label %s for service %s", + return nil, errors.Errorf("cannot get label %s for %s", convert.LabelNamespace, service.ID) } ztack, ok := m[name] diff --git a/tests/integration/app_check.bats b/tests/integration/app_check.bats index 6d5ea1c9..d1ee7b8d 100644 --- a/tests/integration/app_check.bats +++ b/tests/integration/app_check.bats @@ -118,3 +118,20 @@ teardown(){ assert_success assert_output --partial '❌' } + +# bats test_tags=slow +@test "respects env version" { + tagHash=$(_get_tag_hash "0.1.0+1.20.0") + + run $ABRA app deploy "$TEST_APP_DOMAIN" "0.1.0+1.20.0" --no-input --no-converge-checks + assert_success + + run grep -q "TYPE=$TEST_RECIPE:0.1.0+1.20.0" \ + "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" + assert_success + + run $ABRA app check "$TEST_APP_DOMAIN" + assert_success + + assert_equal $(_get_current_hash) "$tagHash" +} diff --git a/tests/integration/app_cmd.bats b/tests/integration/app_cmd.bats index 1d4abc89..9df0efbc 100644 --- a/tests/integration/app_cmd.bats +++ b/tests/integration/app_cmd.bats @@ -187,6 +187,24 @@ test_cmd_export" assert_output --partial 'baz' } +# bats test_tags=slow +@test "respects env version" { + tagHash=$(_get_tag_hash "0.1.0+1.20.0") + + run $ABRA app deploy "$TEST_APP_DOMAIN" "0.1.0+1.20.0" --no-input + assert_success + + run grep -q "TYPE=$TEST_RECIPE:0.1.0+1.20.0" \ + "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" + assert_success + + run $ABRA app cmd "$TEST_APP_DOMAIN" app test_cmd + assert_success + assert_output --partial 'baz' + + assert_equal $(_get_current_hash) "$tagHash" +} + # bats test_tags=slow @test "error if missing service" { _deploy_app diff --git a/tests/integration/app_deploy.bats b/tests/integration/app_deploy.bats index 8ba05f5d..c9f7c112 100644 --- a/tests/integration/app_deploy.bats +++ b/tests/integration/app_deploy.bats @@ -325,8 +325,6 @@ teardown(){ # bats test_tags=slow @test "deploy specific version with incompatible HEAD" { - skip "https://git.coopcloud.tech/coop-cloud/organising/issues/541" - run sed -i 's/COMPOSE_FILE="compose.yml"/COMPOSE_FILE="compose.yml:compose.extra_secret.yml"/g' \ "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" assert_success @@ -352,6 +350,6 @@ teardown(){ _undeploy_app - run $ABRA app secret rm "$TEST_APP_DOMAIN" --all --chaos + run $ABRA app secret rm "$TEST_APP_DOMAIN" --all assert_success } diff --git a/tests/integration/app_deploy_env_version.bats b/tests/integration/app_deploy_env_version.bats index 63d4d775..0522ea05 100644 --- a/tests/integration/app_deploy_env_version.bats +++ b/tests/integration/app_deploy_env_version.bats @@ -78,3 +78,22 @@ teardown(){ assert_success assert_output --partial '0.1.0+1.20.0' } + +# bats test_tags=slow +@test "specific version overrides env version" { + run $ABRA app deploy "$TEST_APP_DOMAIN" "0.1.0+1.20.0" --no-input --no-converge-checks + assert_success + + run grep -q "TYPE=$TEST_RECIPE:0.1.0+1.20.0" \ + "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" + assert_success + + run $ABRA app deploy "$TEST_APP_DOMAIN" "0.2.0+1.21.0" \ + --no-input --no-converge-checks --force --debug + assert_success + assert_output --partial "overriding env file version" + + run grep -q "TYPE=$TEST_RECIPE:0.2.0+1.21.0" \ + "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" + assert_success +} diff --git a/tests/integration/app_deploy_remote_recipes.bats b/tests/integration/app_deploy_remote_recipes.bats index 56b6ce56..c45819c0 100644 --- a/tests/integration/app_deploy_remote_recipes.bats +++ b/tests/integration/app_deploy_remote_recipes.bats @@ -27,7 +27,7 @@ teardown(){ # bats test_tags=slow @test "deploy remote recipe" { - run sed -i 's/TYPE=abra-test-recipe/TYPE=git.coopcloud.tech\/coop-cloud\/abra-test-recipe/g' \ + run sed -i 's/TYPE=abra-test-recipe:.*/TYPE=git.coopcloud.tech\/coop-cloud\/abra-test-recipe/g' \ "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" assert_success @@ -38,7 +38,7 @@ teardown(){ # bats test_tags=slow @test "deploy remote recipe with version" { - run sed -i 's/TYPE=abra-test-recipe/TYPE=git.coopcloud.tech\/coop-cloud\/abra-test-recipe:0.2.0+1.21.0/g' \ + run sed -i 's/TYPE=abra-test-recipe:.*/TYPE=git.coopcloud.tech\/coop-cloud\/abra-test-recipe:0.2.0+1.21.0/g' \ "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" assert_success @@ -49,7 +49,7 @@ teardown(){ # bats test_tags=slow @test "deploy remote recipe with chaos commit" { - run sed -i 's/TYPE=abra-test-recipe/TYPE=git.coopcloud.tech\/coop-cloud\/abra-test-recipe:1e83340e/g' \ + run sed -i 's/TYPE=abra-test-recipe:.*/TYPE=git.coopcloud.tech\/coop-cloud\/abra-test-recipe:1e83340e/g' \ "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" assert_success @@ -60,7 +60,7 @@ teardown(){ # bats test_tags=slow @test "remote recipe version written to env" { - run sed -i 's/TYPE=abra-test-recipe/TYPE=git.coopcloud.tech\/coop-cloud\/abra-test-recipe/g' \ + run sed -i 's/TYPE=abra-test-recipe:.*/TYPE=git.coopcloud.tech\/coop-cloud\/abra-test-recipe/g' \ "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" assert_success diff --git a/tests/integration/app_env_version.bats b/tests/integration/app_env_version.bats new file mode 100644 index 00000000..90743f65 --- /dev/null +++ b/tests/integration/app_env_version.bats @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +setup_file(){ + load "$PWD/tests/integration/helpers/common" + _common_setup + _add_server + _new_app +} + +teardown_file(){ + _rm_app + _rm_server + _reset_recipe +} + +setup(){ + load "$PWD/tests/integration/helpers/common" + _common_setup + _ensure_catalogue +} + +teardown(){ + _reset_app +} + +@test "badly formatted env version bails out" { + run sed -i 's/TYPE=abra-test-recipe/TYPE=abra-test-recipe:0.2.0+1.21.0/g' \ + "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" + assert_success + + run $ABRA app deploy "$TEST_APP_DOMAIN" --no-input --no-converge-checks + assert_failure + assert_output --partial 'seems invalid' +} + +@test "invalid env version bails out" { + run sed -i 's/TYPE=abra-test-recipe:.*/TYPE=abra-test-recipe:DOESNTEXIST/g' \ + "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" + assert_success + + run $ABRA app deploy "$TEST_APP_DOMAIN" --no-input --no-converge-checks + assert_failure + assert_output --partial 'not found' +} diff --git a/tests/integration/app_rollback_env_version.bats b/tests/integration/app_rollback_env_version.bats index a06d22a4..bdb3ced3 100644 --- a/tests/integration/app_rollback_env_version.bats +++ b/tests/integration/app_rollback_env_version.bats @@ -32,9 +32,11 @@ teardown(){ "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" assert_success - run $ABRA app rollback "$TEST_APP_DOMAIN" "0.1.0+1.20.0" --no-input --no-converge-checks + run $ABRA app rollback "$TEST_APP_DOMAIN" "0.1.0+1.20.0" \ + --no-input --no-converge-checks --debug assert_success assert_output --partial "0.1.0+1.20.0" + assert_output --partial "overriding env file version" run grep -q "TYPE=abra-test-recipe:0.1.0+1.20.0" \ "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" diff --git a/tests/integration/app_secret_env_version.bats b/tests/integration/app_secret_env_version.bats new file mode 100644 index 00000000..de35e040 --- /dev/null +++ b/tests/integration/app_secret_env_version.bats @@ -0,0 +1,92 @@ +#!/usr/bin/env bash + +setup_file(){ + load "$PWD/tests/integration/helpers/common" + _common_setup + _add_server + + # NOTE(d1): create new app without secrets + run $ABRA app new "$TEST_RECIPE" \ + --no-input \ + --server "$TEST_SERVER" \ + --domain "$TEST_APP_DOMAIN" + assert_success + assert_exists "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" +} + +teardown_file(){ + _rm_app + _rm_server + _reset_recipe +} + +setup(){ + load "$PWD/tests/integration/helpers/common" + _common_setup +} + +teardown(){ + _reset_recipe + _reset_app + + run $ABRA app secret rm "$TEST_APP_DOMAIN" --all --no-input +} + +@test "generate: respect env version" { + tagHash=$(_get_tag_hash "0.2.0+1.21.0") + + run sed -i 's/TYPE=abra-test-recipe:.*/TYPE=abra-test-recipe:0.2.0+1.21.0/g' \ + "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" + assert_success + + run $ABRA app secret generate "$TEST_APP_DOMAIN" --all + assert_success + + assert_equal $(_get_current_hash) "$tagHash" +} + +@test "insert: respect env version" { + tagHash=$(_get_tag_hash "0.2.0+1.21.0") + + run sed -i 's/TYPE=abra-test-recipe:.*/TYPE=abra-test-recipe:0.2.0+1.21.0/g' \ + "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" + assert_success + + run $ABRA app secret insert "$TEST_APP_DOMAIN" test_pass_one v1 foo + assert_success + assert_output --partial 'successfully stored on server' + + assert_equal $(_get_current_hash) "$tagHash" +} + +@test "rm: respect env version" { + tagHash=$(_get_tag_hash "0.2.0+1.21.0") + + run sed -i 's/TYPE=abra-test-recipe:.*/TYPE=abra-test-recipe:0.2.0+1.21.0/g' \ + "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" + + assert_success + run $ABRA app secret generate "$TEST_APP_DOMAIN" --all + assert_success + + run $ABRA app secret rm "$TEST_APP_DOMAIN" --all + assert_success + + assert_equal $(_get_current_hash) "$tagHash" +} + +@test "ls: respect env version" { + tagHash=$(_get_tag_hash "0.2.0+1.21.0") + + run sed -i 's/TYPE=abra-test-recipe:.*/TYPE=abra-test-recipe:0.2.0+1.21.0/g' \ + "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" + + run $ABRA app secret generate "$TEST_APP_DOMAIN" --all + assert_success + + run $ABRA app secret ls "$TEST_APP_DOMAIN" + assert_success + assert_output --partial 'true' + + assert_equal $(_get_current_hash) "$tagHash" +} diff --git a/tests/integration/app_upgrade_env_version.bats b/tests/integration/app_upgrade_env_version.bats index b4fa1c46..292a121a 100644 --- a/tests/integration/app_upgrade_env_version.bats +++ b/tests/integration/app_upgrade_env_version.bats @@ -31,9 +31,11 @@ teardown(){ "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" assert_success - run $ABRA app upgrade "$TEST_APP_DOMAIN" "0.2.0+1.21.0" --no-input --no-converge-checks + run $ABRA app upgrade "$TEST_APP_DOMAIN" "0.2.0+1.21.0" \ + --no-input --no-converge-checks --debug assert_success assert_output --partial "0.2.0+1.21.0" + assert_output --partial "overriding env file version" run grep -q "TYPE=abra-test-recipe:0.2.0+1.21.0" \ "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"