fix: version spec & fixups #442

Merged
decentral1se merged 6 commits from version-spec into main 2024-07-17 08:11:03 +00:00
17 changed files with 247 additions and 24 deletions

View File

@ -59,6 +59,11 @@ EXAMPLE:
log.Fatal("cannot use <version> and --chaos together") log.Fatal("cannot use <version> 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 != "" { if specificVersion == "" && app.Recipe.Version != "" {
log.Debugf("retrieved %s as version from env file", app.Recipe.Version) log.Debugf("retrieved %s as version from env file", app.Recipe.Version)
specificVersion = app.Recipe.Version specificVersion = app.Recipe.Version

View File

@ -53,6 +53,12 @@ EXAMPLE:
app := internal.ValidateApp(c) app := internal.ValidateApp(c)
stackName := app.StackName() 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 { if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -88,8 +94,6 @@ EXAMPLE:
warnMessages = append(warnMessages, fmt.Sprintf("failed to determine deployed version of %s", app.Name)) warnMessages = append(warnMessages, fmt.Sprintf("failed to determine deployed version of %s", app.Name))
} }
specificVersion := c.Args().Get(1)
if specificVersion != "" { if specificVersion != "" {
parsedDeployedVersion, err := tagcmp.Parse(deployMeta.Version) parsedDeployedVersion, err := tagcmp.Parse(deployMeta.Version)
if err != nil { if err != nil {

View File

@ -178,6 +178,9 @@ Example:
`, `,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) app := internal.ValidateApp(c)
if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
log.Fatal(err)
}
if len(c.Args()) != 4 { if len(c.Args()) != 4 {
internal.ShowSubcommandHelpAndError(c, errors.New("missing arguments?")) internal.ShowSubcommandHelpAndError(c, errors.New("missing arguments?"))

View File

@ -53,6 +53,12 @@ EXAMPLE:
app := internal.ValidateApp(c) app := internal.ValidateApp(c)
stackName := app.StackName() 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 { if err := app.Recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -88,7 +94,6 @@ EXAMPLE:
warnMessages = append(warnMessages, fmt.Sprintf("failed to determine deployed version of %s", app.Name)) warnMessages = append(warnMessages, fmt.Sprintf("failed to determine deployed version of %s", app.Name))
} }
specificVersion := c.Args().Get(1)
if specificVersion != "" { if specificVersion != "" {
parsedDeployedVersion, err := tagcmp.Parse(deployMeta.Version) parsedDeployedVersion, err := tagcmp.Parse(deployMeta.Version)
if err != nil { if err != nil {

View File

@ -599,5 +599,11 @@ func (a App) WriteRecipeVersion(version string) error {
log.Fatal(err) 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
} }

View File

@ -32,6 +32,7 @@ func (r Recipe) Ensure(chaos bool, offline bool) error {
} }
} }
if r.Version != "" { if r.Version != "" {
log.Debugf("ensuring version %s", r.Version)
if _, err := r.EnsureVersion(r.Version); err != nil { if _, err := r.EnsureVersion(r.Version); err != nil {
return err return err
} }

View File

@ -127,6 +127,9 @@ func Get(name string) Recipe {
version := "" version := ""
if strings.Contains(name, ":") { if strings.Contains(name, ":") {
split := strings.Split(name, ":") split := strings.Split(name, ":")
if len(split) > 2 {
log.Fatalf("version seems invalid: %s", name)
}
name = split[0] name = split[0]
version = split[1] version = split[1]
} }

View File

@ -175,6 +175,7 @@ func pruneServices(ctx context.Context, cl *dockerClient.Client, namespace conve
pruneServices = append(pruneServices, service) pruneServices = append(pruneServices, service)
} }
} }
removeServices(ctx, cl, pruneServices) 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) log.Infof("waiting for %s to deploy... please hold 🤚", appName)
if err := waitOnServices(ctx, cl, serviceIDs, appName); err == nil { if err := waitOnServices(ctx, cl, serviceIDs, appName); err != nil {
log.Infof("successfully deployed %s", appName) return err
} }
log.Infof("successfully deployed %s", appName)
return nil return nil
} }
@ -395,7 +398,7 @@ func deployServices(
) )
if service, exists := existingServiceMap[name]; exists { 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} updateOpts := types.ServiceUpdateOptions{EncodedRegistryAuth: encodedAuth}
@ -430,7 +433,7 @@ func deployServices(
response, err := cl.ServiceUpdate(ctx, service.ID, service.Version, serviceSpec, updateOpts) response, err := cl.ServiceUpdate(ctx, service.ID, service.Version, serviceSpec, updateOpts)
if err != nil { 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 { for _, warning := range response.Warnings {
@ -439,7 +442,7 @@ func deployServices(
serviceIDs = append(serviceIDs, service.ID) serviceIDs = append(serviceIDs, service.ID)
} else { } else {
log.Infof("creating service %s", name) log.Infof("creating %s", name)
createOpts := types.ServiceCreateOptions{EncodedRegistryAuth: encodedAuth} createOpts := types.ServiceCreateOptions{EncodedRegistryAuth: encodedAuth}
@ -450,7 +453,7 @@ func deployServices(
serviceCreateResponse, err := cl.ServiceCreate(ctx, serviceSpec, createOpts) serviceCreateResponse, err := cl.ServiceCreate(ctx, serviceSpec, createOpts)
if err != nil { 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) serviceIDs = append(serviceIDs, serviceCreateResponse.ID)
@ -510,13 +513,14 @@ func WaitOnService(ctx context.Context, cl *dockerClient.Client, serviceID, appN
case err := <-errChan: case err := <-errChan:
return err return err
case <-sigintChannel: case <-sigintChannel:
return fmt.Errorf(fmt.Sprintf(` return fmt.Errorf(`
Not waiting for %s to deploy. The deployment is ongoing... Not waiting for %s to deploy. The deployment is ongoing...
If you want to stop the deployment, try: If you want to stop the deployment, try:
abra app undeploy %s`, appName, appName))
abra app undeploy %s`, appName, appName)
case <-time.After(timeout): case <-time.After(timeout):
return fmt.Errorf(fmt.Sprintf(` return fmt.Errorf(`
%s has not converged (%s second timeout reached). %s has not converged (%s second timeout reached).
This does not necessarily mean your deployment has failed, it may just be that 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: And inspect the logs with:
abra app logs %s 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 labels := service.Spec.Labels
name, ok := labels[convert.LabelNamespace] name, ok := labels[convert.LabelNamespace]
if !ok { 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) convert.LabelNamespace, service.ID)
} }
ztack, ok := m[name] ztack, ok := m[name]

View File

@ -118,3 +118,20 @@ teardown(){
assert_success assert_success
assert_output --partial '❌' 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"
}

View File

@ -187,6 +187,24 @@ test_cmd_export"
assert_output --partial 'baz' 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 # bats test_tags=slow
@test "error if missing service" { @test "error if missing service" {
_deploy_app _deploy_app

View File

@ -325,8 +325,6 @@ teardown(){
# bats test_tags=slow # bats test_tags=slow
@test "deploy specific version with incompatible HEAD" { @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' \ 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" "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
assert_success assert_success
@ -352,6 +350,6 @@ teardown(){
_undeploy_app _undeploy_app
run $ABRA app secret rm "$TEST_APP_DOMAIN" --all --chaos run $ABRA app secret rm "$TEST_APP_DOMAIN" --all
assert_success assert_success
} }

View File

@ -78,3 +78,22 @@ teardown(){
assert_success assert_success
assert_output --partial '0.1.0+1.20.0' 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
}

View File

@ -27,7 +27,7 @@ teardown(){
# bats test_tags=slow # bats test_tags=slow
@test "deploy remote recipe" { @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" "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
assert_success assert_success
@ -38,7 +38,7 @@ teardown(){
# bats test_tags=slow # bats test_tags=slow
@test "deploy remote recipe with version" { @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" "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
assert_success assert_success
@ -49,7 +49,7 @@ teardown(){
# bats test_tags=slow # bats test_tags=slow
@test "deploy remote recipe with chaos commit" { @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" "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
assert_success assert_success
@ -60,7 +60,7 @@ teardown(){
# bats test_tags=slow # bats test_tags=slow
@test "remote recipe version written to env" { @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" "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
assert_success assert_success

View File

@ -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'
}

View File

@ -32,9 +32,11 @@ teardown(){
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
assert_success 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_success
assert_output --partial "0.1.0+1.20.0" 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" \ run grep -q "TYPE=abra-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"

View File

@ -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"
}

View File

@ -31,9 +31,11 @@ teardown(){
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
assert_success 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_success
assert_output --partial "0.2.0+1.21.0" 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" \ run grep -q "TYPE=abra-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"