From 6d634ea4e2331b25d221692bc4c2d5280efaaa97 Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Mon, 1 Sep 2025 13:43:10 -0400 Subject: [PATCH 01/28] WIP: Initial stab at secrets/configs/images --- cli/app/deploy.go | 35 +++++++++++++++++++++++++++++++++++ cli/app/rollback.go | 35 +++++++++++++++++++++++++++++++++++ cli/app/undeploy.go | 3 +++ cli/app/upgrade.go | 34 ++++++++++++++++++++++++++++++++++ cli/internal/deploy.go | 7 +++++++ pkg/secret/secret.go | 4 ++-- 6 files changed, 116 insertions(+), 2 deletions(-) diff --git a/cli/app/deploy.go b/cli/app/deploy.go index 0ff13bd2..4242e24a 100644 --- a/cli/app/deploy.go +++ b/cli/app/deploy.go @@ -22,6 +22,7 @@ import ( "coopcloud.tech/abra/pkg/upstream/stack" dockerClient "github.com/docker/docker/client" "github.com/spf13/cobra" + "github.com/docker/docker/api/types" ) // translators: `abra app deploy` aliases. use a comma separated list of aliases with @@ -194,15 +195,49 @@ checkout as-is. Recipe commit hashes are also supported as values for deployedVersion = deployMeta.Version } + filters, err := app.Filters(false, false) + if err != nil { + log.Fatal(err) + } + + secretList, err := cl.SecretList(context.Background(), types.SecretListOptions{Filters: filters}) + if err != nil { + log.Fatal(err) + } + + var secretStrings []string + for _, cont := range secretList { + secretStrings = append(secretStrings, cont.Spec.Name) + } + + configList, err := cl.ConfigList(context.Background(), types.ConfigListOptions{Filters: filters}) + if err != nil { + log.Fatal(err) + } + + var configStrings []string + for _, config := range configList { + configStrings = append(configStrings, config.Spec.Name) + } + + var imageStrings []string + for _, service := range compose.Services { + imageStrings = append(imageStrings, service.Image) + } + if err := internal.DeployOverview( app, deployedVersion, toDeployVersion, "", deployWarnMessages, + strings.Join(secretStrings, "\n"), + strings.Join(configStrings, "\n"), + strings.Join(imageStrings, "\n"), ); err != nil { log.Fatal(err) } + return stack.WaitTimeout, err = appPkg.GetTimeoutFromLabel(compose, stackName) if err != nil { diff --git a/cli/app/rollback.go b/cli/app/rollback.go index a9575676..d95d8551 100644 --- a/cli/app/rollback.go +++ b/cli/app/rollback.go @@ -1,6 +1,7 @@ package app import ( + "context" "errors" "strings" @@ -19,6 +20,7 @@ import ( "coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/log" "github.com/AlecAivazis/survey/v2" + "github.com/docker/docker/api/types" "github.com/spf13/cobra" ) @@ -190,6 +192,36 @@ beforehand. See "abra app backup" for more.`), } appPkg.SetUpdateLabel(compose, stackName, app.Env) + filters, err := app.Filters(false, false) + if err != nil { + log.Fatal(err) + } + + secretList, err := cl.SecretList(context.Background(), types.SecretListOptions{Filters: filters}) + if err != nil { + log.Fatal(err) + } + + var secretStrings []string + for _, cont := range secretList { + secretStrings = append(secretStrings, cont.Spec.Name) + } + + configList, err := cl.ConfigList(context.Background(), types.ConfigListOptions{Filters: filters}) + if err != nil { + log.Fatal(err) + } + + var configStrings []string + for _, config := range configList { + configStrings = append(configStrings, config.Spec.Name) + } + + var imageStrings []string + for _, service := range compose.Services { + imageStrings = append(imageStrings, service.Image) + } + // NOTE(d1): no release notes implemeneted for rolling back if err := internal.DeployOverview( app, @@ -197,6 +229,9 @@ beforehand. See "abra app backup" for more.`), chosenDowngrade, "", downgradeWarnMessages, + strings.Join(secretStrings, "\n"), + strings.Join(configStrings, "\n"), + strings.Join(imageStrings, "\n"), ); err != nil { log.Fatal(err) } diff --git a/cli/app/undeploy.go b/cli/app/undeploy.go index 021e1f77..29633443 100644 --- a/cli/app/undeploy.go +++ b/cli/app/undeploy.go @@ -71,6 +71,9 @@ Passing "--prune/-p" does not remove those volumes.`), config.NO_DOMAIN_DEFAULT, "", nil, + "", + "", + "", ); err != nil { log.Fatal(err) } diff --git a/cli/app/upgrade.go b/cli/app/upgrade.go index 65611016..839bd026 100644 --- a/cli/app/upgrade.go +++ b/cli/app/upgrade.go @@ -21,6 +21,7 @@ import ( stack "coopcloud.tech/abra/pkg/upstream/stack" "coopcloud.tech/tagcmp" "github.com/AlecAivazis/survey/v2" + "github.com/docker/docker/api/types" dockerClient "github.com/docker/docker/client" "github.com/spf13/cobra" ) @@ -216,6 +217,36 @@ beforehand. See "abra app backup" for more.`), } } + filters, err := app.Filters(false, false) + if err != nil { + log.Fatal(err) + } + + secretList, err := cl.SecretList(context.Background(), types.SecretListOptions{Filters: filters}) + if err != nil { + log.Fatal(err) + } + + var secretStrings []string + for _, cont := range secretList { + secretStrings = append(secretStrings, cont.Spec.Name) + } + + configList, err := cl.ConfigList(context.Background(), types.ConfigListOptions{Filters: filters}) + if err != nil { + log.Fatal(err) + } + + var configStrings []string + for _, config := range configList { + configStrings = append(configStrings, config.Spec.Name) + } + + var imageStrings []string + for _, service := range compose.Services { + imageStrings = append(imageStrings, service.Image) + } + if showReleaseNotes { fmt.Print(upgradeReleaseNotes) return @@ -234,6 +265,9 @@ beforehand. See "abra app backup" for more.`), chosenUpgrade, upgradeReleaseNotes, upgradeWarnMessages, + strings.Join(secretStrings, "\n"), + strings.Join(configStrings, "\n"), + strings.Join(imageStrings, "\n"), ); err != nil { log.Fatal(err) } diff --git a/cli/internal/deploy.go b/cli/internal/deploy.go index 4f816804..c27f4b2a 100644 --- a/cli/internal/deploy.go +++ b/cli/internal/deploy.go @@ -50,6 +50,9 @@ func DeployOverview( toDeployVersion string, releaseNotes string, warnMessages []string, + secrets string, + configs string, + images string, ) error { deployConfig := "compose.yml" if composeFiles, ok := app.Env["COMPOSE_FILE"]; ok { @@ -80,6 +83,10 @@ func DeployOverview( {i18n.G("CURRENT DEPLOYMENT"), formatter.BoldDirtyDefault(deployedVersion)}, {i18n.G("ENV VERSION"), formatter.BoldDirtyDefault(envVersion)}, {i18n.G("NEW DEPLOYMENT"), formatter.BoldDirtyDefault(toDeployVersion)}, + {"", ""}, + {i18n.G("SECRETS"), secrets}, + {i18n.G("CONFIGS"), configs}, + {i18n.G("IMAGES"), images}, } deployType := getDeployType(deployedVersion, toDeployVersion) diff --git a/pkg/secret/secret.go b/pkg/secret/secret.go index ffec2915..e1857ad9 100644 --- a/pkg/secret/secret.go +++ b/pkg/secret/secret.go @@ -280,7 +280,7 @@ type secretStatus struct { type secretStatuses []secretStatus // PollSecretsStatus checks status of secrets by comparing the local recipe -// config and deploymend server state. +// config and deployed server state. func PollSecretsStatus(cl *dockerClient.Client, app appPkg.App) (secretStatuses, error) { var secStats secretStatuses @@ -306,7 +306,7 @@ func PollSecretsStatus(cl *dockerClient.Client, app appPkg.App) (secretStatuses, remoteSecretNames := make(map[string]bool) for _, cont := range secretList { - remoteSecretNames[cont.Spec.Annotations.Name] = true + remoteSecretNames[cont.Spec.Name] = true } for secretName, val := range secretsConfig { -- 2.49.0 From 1df0de2e655c14df5ee580827733ba77980dd881 Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Mon, 1 Sep 2025 14:49:49 -0400 Subject: [PATCH 02/28] WIP: Working secret and config versions during deploy overview --- cli/app/deploy.go | 60 ++++++++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/cli/app/deploy.go b/cli/app/deploy.go index 4242e24a..428bc995 100644 --- a/cli/app/deploy.go +++ b/cli/app/deploy.go @@ -3,6 +3,8 @@ package app import ( "context" "errors" + "fmt" + "sort" "strings" "coopcloud.tech/abra/cli/internal" @@ -22,7 +24,6 @@ import ( "coopcloud.tech/abra/pkg/upstream/stack" dockerClient "github.com/docker/docker/client" "github.com/spf13/cobra" - "github.com/docker/docker/api/types" ) // translators: `abra app deploy` aliases. use a comma separated list of aliases with @@ -195,34 +196,41 @@ checkout as-is. Recipe commit hashes are also supported as values for deployedVersion = deployMeta.Version } - filters, err := app.Filters(false, false) + secStats, err := secret.PollSecretsStatus(cl, app) if err != nil { log.Fatal(err) } - secretList, err := cl.SecretList(context.Background(), types.SecretListOptions{Filters: filters}) + var secretInfo []string + + // Sort secrets to ensure reproducible output + sort.Slice(secStats, func(i, j int) bool { + return secStats[i].LocalName < secStats[j].LocalName + }) + for _, secStat := range secStats { + secretInfo = append(secretInfo, fmt.Sprintf("%s: %s", secStat.LocalName, secStat.Version)) + } + + configFilters, err := app.Filters(false, false) + if err != nil { + log.Fatal(err) + + } + configs, err := client.GetConfigs(cl, context.Background(), app.Server, configFilters) if err != nil { log.Fatal(err) } + configNames := client.GetConfigNames(configs) - var secretStrings []string - for _, cont := range secretList { - secretStrings = append(secretStrings, cont.Spec.Name) + var configInfo []string + for _, config := range configNames { + name, version := extractConfigNameMetadata(config, app.StackName()) + configInfo = append(configInfo, fmt.Sprintf("%s: %s", name, version)) } - configList, err := cl.ConfigList(context.Background(), types.ConfigListOptions{Filters: filters}) - if err != nil { - log.Fatal(err) - } - - var configStrings []string - for _, config := range configList { - configStrings = append(configStrings, config.Spec.Name) - } - - var imageStrings []string + var imageInfo []string for _, service := range compose.Services { - imageStrings = append(imageStrings, service.Image) + imageInfo = append(imageInfo, fmt.Sprintf("%s: %s", service.Name, service.Image)) } if err := internal.DeployOverview( @@ -231,9 +239,9 @@ checkout as-is. Recipe commit hashes are also supported as values for toDeployVersion, "", deployWarnMessages, - strings.Join(secretStrings, "\n"), - strings.Join(configStrings, "\n"), - strings.Join(imageStrings, "\n"), + strings.Join(secretInfo, "\n"), + strings.Join(configInfo, "\n"), + strings.Join(imageInfo, "\n"), ); err != nil { log.Fatal(err) } @@ -370,6 +378,16 @@ func getDeployVersion(cliArgs []string, deployMeta stack.DeployMeta, app app.App return v, nil } +// extractConfigNameMetadata strips the stack name and returns +// Example: "wordpress_db_password_v1" -> "v1" +func extractConfigNameMetadata(fullName string, stackName string) (string, string) { + name := strings.TrimPrefix(fullName, stackName + "_") + if lastUnderscore := strings.LastIndex(name, "_"); lastUnderscore != -1 { + return name[0:lastUnderscore], name[lastUnderscore+1:] + } + return name, "" +} + func init() { AppDeployCommand.Flags().BoolVarP( &internal.Chaos, -- 2.49.0 From 0b7c38c2137c7edaf04b6818871dc6071c8ed509 Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Mon, 1 Sep 2025 14:56:50 -0400 Subject: [PATCH 03/28] refactor: tidy up a little --- cli/app/deploy.go | 16 +++------------- pkg/client/configs.go | 9 +++++++++ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/cli/app/deploy.go b/cli/app/deploy.go index 428bc995..281898fd 100644 --- a/cli/app/deploy.go +++ b/cli/app/deploy.go @@ -216,15 +216,15 @@ checkout as-is. Recipe commit hashes are also supported as values for log.Fatal(err) } - configs, err := client.GetConfigs(cl, context.Background(), app.Server, configFilters) + configList, err := client.GetConfigs(cl, context.Background(), app.Server, configFilters) if err != nil { log.Fatal(err) } - configNames := client.GetConfigNames(configs) + configNames := client.GetConfigNames(configList) var configInfo []string for _, config := range configNames { - name, version := extractConfigNameMetadata(config, app.StackName()) + name, version := client.GetConfigNameAndVersion(config, app.StackName()) configInfo = append(configInfo, fmt.Sprintf("%s: %s", name, version)) } @@ -378,16 +378,6 @@ func getDeployVersion(cliArgs []string, deployMeta stack.DeployMeta, app app.App return v, nil } -// extractConfigNameMetadata strips the stack name and returns -// Example: "wordpress_db_password_v1" -> "v1" -func extractConfigNameMetadata(fullName string, stackName string) (string, string) { - name := strings.TrimPrefix(fullName, stackName + "_") - if lastUnderscore := strings.LastIndex(name, "_"); lastUnderscore != -1 { - return name[0:lastUnderscore], name[lastUnderscore+1:] - } - return name, "" -} - func init() { AppDeployCommand.Flags().BoolVarP( &internal.Chaos, diff --git a/pkg/client/configs.go b/pkg/client/configs.go index 2a2a0eeb..591327b2 100644 --- a/pkg/client/configs.go +++ b/pkg/client/configs.go @@ -3,6 +3,7 @@ package client import ( "context" "errors" + "strings" "coopcloud.tech/abra/pkg/i18n" "github.com/docker/docker/api/types/filters" @@ -37,3 +38,11 @@ func RemoveConfigs(cl *client.Client, ctx context.Context, configNames []string, } return nil } + +func GetConfigNameAndVersion(fullName string, stackName string) (string, string) { + name := strings.TrimPrefix(fullName, stackName + "_") + if lastUnderscore := strings.LastIndex(name, "_"); lastUnderscore != -1 { + return name[0:lastUnderscore], name[lastUnderscore+1:] + } + return name, "" +} -- 2.49.0 From 984bdd8792cad47c01d654e398274caf41771d42 Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Mon, 1 Sep 2025 15:07:26 -0400 Subject: [PATCH 04/28] feat: add some spacing, might delete --- cli/internal/deploy.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cli/internal/deploy.go b/cli/internal/deploy.go index c27f4b2a..33f75572 100644 --- a/cli/internal/deploy.go +++ b/cli/internal/deploy.go @@ -85,7 +85,9 @@ func DeployOverview( {i18n.G("NEW DEPLOYMENT"), formatter.BoldDirtyDefault(toDeployVersion)}, {"", ""}, {i18n.G("SECRETS"), secrets}, + {"", ""}, {i18n.G("CONFIGS"), configs}, + {"", ""}, {i18n.G("IMAGES"), images}, } -- 2.49.0 From 155df518dd71befcf054063a732f40e4fae112a9 Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Mon, 1 Sep 2025 15:22:40 -0400 Subject: [PATCH 05/28] feat: only show remote configs used in deployment --- cli/app/deploy.go | 8 +------- pkg/client/configs.go | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/cli/app/deploy.go b/cli/app/deploy.go index 281898fd..d7ed8869 100644 --- a/cli/app/deploy.go +++ b/cli/app/deploy.go @@ -211,16 +211,10 @@ checkout as-is. Recipe commit hashes are also supported as values for secretInfo = append(secretInfo, fmt.Sprintf("%s: %s", secStat.LocalName, secStat.Version)) } - configFilters, err := app.Filters(false, false) - if err != nil { - log.Fatal(err) - - } - configList, err := client.GetConfigs(cl, context.Background(), app.Server, configFilters) + configNames, err := client.GetConfigNamesForStack(cl, context.Background(), app.StackName()) if err != nil { log.Fatal(err) } - configNames := client.GetConfigNames(configList) var configInfo []string for _, config := range configNames { diff --git a/pkg/client/configs.go b/pkg/client/configs.go index 591327b2..0c8ac187 100644 --- a/pkg/client/configs.go +++ b/pkg/client/configs.go @@ -6,6 +6,7 @@ import ( "strings" "coopcloud.tech/abra/pkg/i18n" + "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/client" @@ -46,3 +47,38 @@ func GetConfigNameAndVersion(fullName string, stackName string) (string, string) } return name, "" } + +// GetConfigNamesForStack retrieves all Docker configs attached to services in a given stack. +func GetConfigNamesForStack(cl *client.Client, ctx context.Context, stackName string) ([]string, error) { + // Create filter to get services for the specific stack + filter := filters.NewArgs() + filter.Add("label", "com.docker.stack.namespace="+stackName) + + // List all services in the stack + services, err := cl.ServiceList(ctx, types.ServiceListOptions{ + Filters: filter, + }) + if err != nil { + return nil, err + } + + // Collect unique config names from all services + configNames := make(map[string]bool) + for _, service := range services { + if service.Spec.TaskTemplate.ContainerSpec != nil { + for _, configRef := range service.Spec.TaskTemplate.ContainerSpec.Configs { + if configRef.ConfigName != "" { + configNames[configRef.ConfigName] = true + } + } + } + } + + // Convert map to slice + result := make([]string, 0, len(configNames)) + for name := range configNames { + result = append(result, name) + } + + return result, nil +} -- 2.49.0 From 7f9f8f9d6aa7e6ee86c5cdc341bae8c8f36eb051 Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Mon, 1 Sep 2025 15:33:56 -0400 Subject: [PATCH 06/28] feat: skip empty sections in deploy overview --- cli/internal/deploy.go | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/cli/internal/deploy.go b/cli/internal/deploy.go index 33f75572..9fa556bb 100644 --- a/cli/internal/deploy.go +++ b/cli/internal/deploy.go @@ -84,13 +84,25 @@ func DeployOverview( {i18n.G("ENV VERSION"), formatter.BoldDirtyDefault(envVersion)}, {i18n.G("NEW DEPLOYMENT"), formatter.BoldDirtyDefault(toDeployVersion)}, {"", ""}, - {i18n.G("SECRETS"), secrets}, - {"", ""}, - {i18n.G("CONFIGS"), configs}, - {"", ""}, {i18n.G("IMAGES"), images}, } + if len(secrets) > 0 { + secretsRows := [][]string{ + {"", ""}, + {i18n.G("SECRETS"), secrets}, + } + rows = append(rows, secretsRows...) + } + + if len(configs) > 0 { + configsRows := [][]string{ + {"", ""}, + {i18n.G("CONFIGS"), configs}, + } + rows = append(rows, configsRows...) + } + deployType := getDeployType(deployedVersion, toDeployVersion) overview := formatter.CreateOverview(i18n.G("%s OVERVIEW", deployType), rows) -- 2.49.0 From 719722a25b0c20a6a7f8794396956476cda01bf6 Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Mon, 1 Sep 2025 16:26:00 -0400 Subject: [PATCH 07/28] feat: working config version comparison --- cli/app/deploy.go | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/cli/app/deploy.go b/cli/app/deploy.go index d7ed8869..fa670577 100644 --- a/cli/app/deploy.go +++ b/cli/app/deploy.go @@ -211,15 +211,44 @@ checkout as-is. Recipe commit hashes are also supported as values for secretInfo = append(secretInfo, fmt.Sprintf("%s: %s", secStat.LocalName, secStat.Version)) } - configNames, err := client.GetConfigNamesForStack(cl, context.Background(), app.StackName()) + // Get current configs from existing deployment + currentConfigNames, err := client.GetConfigNamesForStack(cl, context.Background(), app.StackName()) if err != nil { log.Fatal(err) } + log.Infof("Config names: %v", currentConfigNames) + + // Create map of current config base names to versions + currentConfigs := make(map[string]string) + for _, configName := range currentConfigNames { + baseName, version := client.GetConfigNameAndVersion(configName, app.StackName()) + currentConfigs[baseName] = version + } + + log.Infof("Configs: %v", currentConfigs) + + // Get new configs from the compose specification + newConfigs := compose.Configs + var configInfo []string - for _, config := range configNames { - name, version := client.GetConfigNameAndVersion(config, app.StackName()) - configInfo = append(configInfo, fmt.Sprintf("%s: %s", name, version)) + for configName := range newConfigs { + log.Debugf("Searching for abra.sh version for %s", configName) + versionKey := strings.ToUpper(configName) + "_VERSION" + newVersion, exists := abraShEnv[versionKey] + if !exists { + log.Fatalf("No version found for config %s", configName) + } + + if currentVersion, exists := currentConfigs[configName]; exists { + if currentVersion == newVersion { + configInfo = append(configInfo, fmt.Sprintf("%s: %s (unchanged)", configName, newVersion)) + } else { + configInfo = append(configInfo, fmt.Sprintf("%s: %s → %s", configName, currentVersion, newVersion)) + } + } else { + configInfo = append(configInfo, fmt.Sprintf("%s: %s (new)", configName, newVersion)) + } } var imageInfo []string -- 2.49.0 From f3edfea744fe5d6371b647055a1c3e99f3be9bd6 Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Mon, 1 Sep 2025 21:03:16 -0400 Subject: [PATCH 08/28] feat: warn instead of error on missing config version --- cli/app/deploy.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cli/app/deploy.go b/cli/app/deploy.go index fa670577..7378a4a4 100644 --- a/cli/app/deploy.go +++ b/cli/app/deploy.go @@ -196,6 +196,8 @@ checkout as-is. Recipe commit hashes are also supported as values for deployedVersion = deployMeta.Version } + // Gather secrets + secStats, err := secret.PollSecretsStatus(cl, app) if err != nil { log.Fatal(err) @@ -211,6 +213,8 @@ checkout as-is. Recipe commit hashes are also supported as values for secretInfo = append(secretInfo, fmt.Sprintf("%s: %s", secStat.LocalName, secStat.Version)) } + // Gather configs + // Get current configs from existing deployment currentConfigNames, err := client.GetConfigNamesForStack(cl, context.Background(), app.StackName()) if err != nil { @@ -237,7 +241,9 @@ checkout as-is. Recipe commit hashes are also supported as values for versionKey := strings.ToUpper(configName) + "_VERSION" newVersion, exists := abraShEnv[versionKey] if !exists { - log.Fatalf("No version found for config %s", configName) + log.Warnf("No version found for config %s", configName) + configInfo = append(configInfo, fmt.Sprintf("%s: ? (missing)", configName)) + continue } if currentVersion, exists := currentConfigs[configName]; exists { @@ -268,6 +274,7 @@ checkout as-is. Recipe commit hashes are also supported as values for ); err != nil { log.Fatal(err) } + // FIXME: just for debugging return stack.WaitTimeout, err = appPkg.GetTimeoutFromLabel(compose, stackName) -- 2.49.0 From c2848cb3ecfca5e0138d73304d51f360ff18d122 Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Tue, 2 Sep 2025 11:32:37 -0400 Subject: [PATCH 09/28] feat: add GetSecretNamesForStack, tidy up GetConfigNamesForStack --- cli/app/deploy.go | 8 ++++++-- pkg/client/configs.go | 14 ++++++++------ pkg/client/secret.go | 24 ++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/cli/app/deploy.go b/cli/app/deploy.go index 7378a4a4..d8f71119 100644 --- a/cli/app/deploy.go +++ b/cli/app/deploy.go @@ -216,7 +216,7 @@ checkout as-is. Recipe commit hashes are also supported as values for // Gather configs // Get current configs from existing deployment - currentConfigNames, err := client.GetConfigNamesForStack(cl, context.Background(), app.StackName()) + currentConfigNames, err := client.GetConfigNamesForStack(cl, app) if err != nil { log.Fatal(err) } @@ -237,7 +237,7 @@ checkout as-is. Recipe commit hashes are also supported as values for var configInfo []string for configName := range newConfigs { - log.Debugf("Searching for abra.sh version for %s", configName) + log.Debugf("Searching abra.sh for version for %s", configName) versionKey := strings.ToUpper(configName) + "_VERSION" newVersion, exists := abraShEnv[versionKey] if !exists { @@ -257,11 +257,15 @@ checkout as-is. Recipe commit hashes are also supported as values for } } + // Gather images + var imageInfo []string for _, service := range compose.Services { imageInfo = append(imageInfo, fmt.Sprintf("%s: %s", service.Name, service.Image)) } + // Show deploy overview + if err := internal.DeployOverview( app, deployedVersion, diff --git a/pkg/client/configs.go b/pkg/client/configs.go index 0c8ac187..1b8732c0 100644 --- a/pkg/client/configs.go +++ b/pkg/client/configs.go @@ -6,6 +6,7 @@ import ( "strings" "coopcloud.tech/abra/pkg/i18n" + appPkg "coopcloud.tech/abra/pkg/app" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/swarm" @@ -49,14 +50,15 @@ func GetConfigNameAndVersion(fullName string, stackName string) (string, string) } // GetConfigNamesForStack retrieves all Docker configs attached to services in a given stack. -func GetConfigNamesForStack(cl *client.Client, ctx context.Context, stackName string) ([]string, error) { - // Create filter to get services for the specific stack - filter := filters.NewArgs() - filter.Add("label", "com.docker.stack.namespace="+stackName) +func GetConfigNamesForStack(cl *client.Client, app appPkg.App) ([]string, error) { + filters, err := app.Filters(false, false) + if err != nil { + return nil, err + } // List all services in the stack - services, err := cl.ServiceList(ctx, types.ServiceListOptions{ - Filters: filter, + services, err := cl.ServiceList(context.Background(), types.ServiceListOptions{ + Filters: filters, }) if err != nil { return nil, err diff --git a/pkg/client/secret.go b/pkg/client/secret.go index 1d095467..e2c82298 100644 --- a/pkg/client/secret.go +++ b/pkg/client/secret.go @@ -3,6 +3,8 @@ package client import ( "context" + appPkg "coopcloud.tech/abra/pkg/app" + "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/client" ) @@ -17,3 +19,25 @@ func StoreSecret(cl *client.Client, secretName, secretValue string) error { return nil } + +func GetSecretNamesForStack(cl *client.Client, app appPkg.App) ([]string, error) { + filters, err := app.Filters(false, false) + if err != nil { + return nil, err + } + + secretList, err := cl.SecretList(context.Background(), swarm.SecretListOptions{Filters: filters}) + if err != nil { + return nil, err + } + + return GetSecretNames(secretList), nil +} + +func GetSecretNames(secrets []swarm.Secret) []string { + var secretNames []string + for _, secret := range secrets { + secretNames = append(secretNames, secret.Spec.Name) + } + return secretNames +} -- 2.49.0 From 745651e962995793cb60a395475b0b87f7de8604 Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Tue, 2 Sep 2025 12:00:47 -0400 Subject: [PATCH 10/28] refactor: resolve circular import --- cli/app/deploy.go | 7 ++--- pkg/client/configs.go | 38 --------------------------- pkg/client/secret.go | 16 ------------ pkg/deploy/utils.go | 61 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 57 deletions(-) create mode 100644 pkg/deploy/utils.go diff --git a/cli/app/deploy.go b/cli/app/deploy.go index d8f71119..42b62cd5 100644 --- a/cli/app/deploy.go +++ b/cli/app/deploy.go @@ -16,6 +16,7 @@ import ( appPkg "coopcloud.tech/abra/pkg/app" "coopcloud.tech/abra/pkg/client" + "coopcloud.tech/abra/pkg/deploy" "coopcloud.tech/abra/pkg/dns" "coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/i18n" @@ -216,7 +217,7 @@ checkout as-is. Recipe commit hashes are also supported as values for // Gather configs // Get current configs from existing deployment - currentConfigNames, err := client.GetConfigNamesForStack(cl, app) + currentConfigNames, err := deploy.GetConfigNamesForStack(cl, app) if err != nil { log.Fatal(err) } @@ -242,7 +243,7 @@ checkout as-is. Recipe commit hashes are also supported as values for newVersion, exists := abraShEnv[versionKey] if !exists { log.Warnf("No version found for config %s", configName) - configInfo = append(configInfo, fmt.Sprintf("%s: ? (missing)", configName)) + configInfo = append(configInfo, fmt.Sprintf("%s: ? (missing version)", configName)) continue } @@ -255,7 +256,7 @@ checkout as-is. Recipe commit hashes are also supported as values for } else { configInfo = append(configInfo, fmt.Sprintf("%s: %s (new)", configName, newVersion)) } - } + } // Gather images diff --git a/pkg/client/configs.go b/pkg/client/configs.go index 1b8732c0..591327b2 100644 --- a/pkg/client/configs.go +++ b/pkg/client/configs.go @@ -6,8 +6,6 @@ import ( "strings" "coopcloud.tech/abra/pkg/i18n" - appPkg "coopcloud.tech/abra/pkg/app" - "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/client" @@ -48,39 +46,3 @@ func GetConfigNameAndVersion(fullName string, stackName string) (string, string) } return name, "" } - -// GetConfigNamesForStack retrieves all Docker configs attached to services in a given stack. -func GetConfigNamesForStack(cl *client.Client, app appPkg.App) ([]string, error) { - filters, err := app.Filters(false, false) - if err != nil { - return nil, err - } - - // List all services in the stack - services, err := cl.ServiceList(context.Background(), types.ServiceListOptions{ - Filters: filters, - }) - if err != nil { - return nil, err - } - - // Collect unique config names from all services - configNames := make(map[string]bool) - for _, service := range services { - if service.Spec.TaskTemplate.ContainerSpec != nil { - for _, configRef := range service.Spec.TaskTemplate.ContainerSpec.Configs { - if configRef.ConfigName != "" { - configNames[configRef.ConfigName] = true - } - } - } - } - - // Convert map to slice - result := make([]string, 0, len(configNames)) - for name := range configNames { - result = append(result, name) - } - - return result, nil -} diff --git a/pkg/client/secret.go b/pkg/client/secret.go index e2c82298..f0a19f54 100644 --- a/pkg/client/secret.go +++ b/pkg/client/secret.go @@ -3,8 +3,6 @@ package client import ( "context" - appPkg "coopcloud.tech/abra/pkg/app" - "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/client" ) @@ -20,20 +18,6 @@ func StoreSecret(cl *client.Client, secretName, secretValue string) error { return nil } -func GetSecretNamesForStack(cl *client.Client, app appPkg.App) ([]string, error) { - filters, err := app.Filters(false, false) - if err != nil { - return nil, err - } - - secretList, err := cl.SecretList(context.Background(), swarm.SecretListOptions{Filters: filters}) - if err != nil { - return nil, err - } - - return GetSecretNames(secretList), nil -} - func GetSecretNames(secrets []swarm.Secret) []string { var secretNames []string for _, secret := range secrets { diff --git a/pkg/deploy/utils.go b/pkg/deploy/utils.go new file mode 100644 index 00000000..1491f680 --- /dev/null +++ b/pkg/deploy/utils.go @@ -0,0 +1,61 @@ +package deploy + +import ( + "context" + + appPkg "coopcloud.tech/abra/pkg/app" + + "github.com/docker/docker/client" + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/swarm" +) + +// GetConfigNamesForStack retrieves all Docker configs attached to services in a given stack. +func GetConfigNamesForStack(cl *client.Client, app appPkg.App) ([]string, error) { + filters, err := app.Filters(false, false) + if err != nil { + return nil, err + } + + // List all services in the stack + services, err := cl.ServiceList(context.Background(), types.ServiceListOptions{ + Filters: filters, + }) + if err != nil { + return nil, err + } + + // Collect unique config names from all services + configNames := make(map[string]bool) + for _, service := range services { + if service.Spec.TaskTemplate.ContainerSpec != nil { + for _, configRef := range service.Spec.TaskTemplate.ContainerSpec.Configs { + if configRef.ConfigName != "" { + configNames[configRef.ConfigName] = true + } + } + } + } + + // Convert map to slice + result := make([]string, 0, len(configNames)) + for name := range configNames { + result = append(result, name) + } + + return result, nil +} + +func GetSecretNamesForStack(cl *client.Client, app appPkg.App) ([]swarm.Secret, error) { + filters, err := app.Filters(false, false) + if err != nil { + return nil, err + } + + secretList, err := cl.SecretList(context.Background(), swarm.SecretListOptions{Filters: filters}) + if err != nil { + return nil, err + } + + return secretList, nil +} -- 2.49.0 From 8e8f7715a23b4520351772375f065b21b740fdb9 Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Tue, 2 Sep 2025 12:15:17 -0400 Subject: [PATCH 11/28] refactor: move secret- and config-gathering to separate file --- cli/app/deploy.go | 54 ++-------------------------- pkg/deploy/utils.go | 87 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 74 insertions(+), 67 deletions(-) diff --git a/cli/app/deploy.go b/cli/app/deploy.go index 42b62cd5..a039a70b 100644 --- a/cli/app/deploy.go +++ b/cli/app/deploy.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "sort" "strings" "coopcloud.tech/abra/cli/internal" @@ -198,66 +197,17 @@ checkout as-is. Recipe commit hashes are also supported as values for } // Gather secrets - - secStats, err := secret.PollSecretsStatus(cl, app) + secretInfo, err := deploy.GatherSecretsForDeploy(cl, app) if err != nil { log.Fatal(err) } - var secretInfo []string - - // Sort secrets to ensure reproducible output - sort.Slice(secStats, func(i, j int) bool { - return secStats[i].LocalName < secStats[j].LocalName - }) - for _, secStat := range secStats { - secretInfo = append(secretInfo, fmt.Sprintf("%s: %s", secStat.LocalName, secStat.Version)) - } - // Gather configs - - // Get current configs from existing deployment - currentConfigNames, err := deploy.GetConfigNamesForStack(cl, app) + configInfo, err := deploy.GatherConfigsForDeploy(cl, app, compose, abraShEnv) if err != nil { log.Fatal(err) } - log.Infof("Config names: %v", currentConfigNames) - - // Create map of current config base names to versions - currentConfigs := make(map[string]string) - for _, configName := range currentConfigNames { - baseName, version := client.GetConfigNameAndVersion(configName, app.StackName()) - currentConfigs[baseName] = version - } - - log.Infof("Configs: %v", currentConfigs) - - // Get new configs from the compose specification - newConfigs := compose.Configs - - var configInfo []string - for configName := range newConfigs { - log.Debugf("Searching abra.sh for version for %s", configName) - versionKey := strings.ToUpper(configName) + "_VERSION" - newVersion, exists := abraShEnv[versionKey] - if !exists { - log.Warnf("No version found for config %s", configName) - configInfo = append(configInfo, fmt.Sprintf("%s: ? (missing version)", configName)) - continue - } - - if currentVersion, exists := currentConfigs[configName]; exists { - if currentVersion == newVersion { - configInfo = append(configInfo, fmt.Sprintf("%s: %s (unchanged)", configName, newVersion)) - } else { - configInfo = append(configInfo, fmt.Sprintf("%s: %s → %s", configName, currentVersion, newVersion)) - } - } else { - configInfo = append(configInfo, fmt.Sprintf("%s: %s (new)", configName, newVersion)) - } - } - // Gather images var imageInfo []string diff --git a/pkg/deploy/utils.go b/pkg/deploy/utils.go index 1491f680..72692024 100644 --- a/pkg/deploy/utils.go +++ b/pkg/deploy/utils.go @@ -2,23 +2,29 @@ package deploy import ( "context" + "fmt" + "sort" + "strings" appPkg "coopcloud.tech/abra/pkg/app" + "coopcloud.tech/abra/pkg/client" + "coopcloud.tech/abra/pkg/log" + "coopcloud.tech/abra/pkg/secret" - "github.com/docker/docker/client" - "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/swarm" + composetypes "github.com/docker/cli/cli/compose/types" + dockerClient "github.com/docker/docker/client" ) // GetConfigNamesForStack retrieves all Docker configs attached to services in a given stack. -func GetConfigNamesForStack(cl *client.Client, app appPkg.App) ([]string, error) { +func GetConfigNamesForStack(cl *dockerClient.Client, app appPkg.App) ([]string, error) { filters, err := app.Filters(false, false) if err != nil { return nil, err } // List all services in the stack - services, err := cl.ServiceList(context.Background(), types.ServiceListOptions{ + services, err := cl.ServiceList(context.Background(), swarm.ServiceListOptions{ Filters: filters, }) if err != nil { @@ -46,16 +52,67 @@ func GetConfigNamesForStack(cl *client.Client, app appPkg.App) ([]string, error) return result, nil } -func GetSecretNamesForStack(cl *client.Client, app appPkg.App) ([]swarm.Secret, error) { - filters, err := app.Filters(false, false) - if err != nil { - return nil, err - } +func GatherSecretsForDeploy(cl *dockerClient.Client, app appPkg.App) ([]string, error) { - secretList, err := cl.SecretList(context.Background(), swarm.SecretListOptions{Filters: filters}) - if err != nil { - return nil, err - } - - return secretList, nil + secStats, err := secret.PollSecretsStatus(cl, app) + if err != nil { + return nil, err + } + + var secretInfo []string + + // Sort secrets to ensure reproducible output + sort.Slice(secStats, func(i, j int) bool { + return secStats[i].LocalName < secStats[j].LocalName + }) + for _, secStat := range secStats { + secretInfo = append(secretInfo, fmt.Sprintf("%s: %s", secStat.LocalName, secStat.Version)) + } + return secretInfo, nil +} + +func GatherConfigsForDeploy(cl *dockerClient.Client, app appPkg.App, compose *composetypes.Config, abraShEnv map[string]string) ([]string, error) { + // Get current configs from existing deployment + currentConfigNames, err := GetConfigNamesForStack(cl, app) + if err != nil { + return nil, err + } + + log.Infof("Config names: %v", currentConfigNames) + + // Create map of current config base names to versions + currentConfigs := make(map[string]string) + for _, configName := range currentConfigNames { + baseName, version := client.GetConfigNameAndVersion(configName, app.StackName()) + currentConfigs[baseName] = version + } + + log.Infof("Configs: %v", currentConfigs) + + // Get new configs from the compose specification + newConfigs := compose.Configs + + var configInfo []string + for configName := range newConfigs { + log.Debugf("Searching abra.sh for version for %s", configName) + versionKey := strings.ToUpper(configName) + "_VERSION" + newVersion, exists := abraShEnv[versionKey] + if !exists { + log.Warnf("No version found for config %s", configName) + configInfo = append(configInfo, fmt.Sprintf("%s: ? (missing version)", configName)) + continue + } + + if currentVersion, exists := currentConfigs[configName]; exists { + if currentVersion == newVersion { + configInfo = append(configInfo, fmt.Sprintf("%s: %s (unchanged)", configName, newVersion)) + } else { + configInfo = append(configInfo, fmt.Sprintf("%s: %s → %s", configName, currentVersion, newVersion)) + } + } else { + configInfo = append(configInfo, fmt.Sprintf("%s: %s (new)", configName, newVersion)) + } + } + + return configInfo, nil } -- 2.49.0 From 14d3f1f6693516521595b886170f349d47a9f4e2 Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Tue, 2 Sep 2025 13:48:09 -0400 Subject: [PATCH 12/28] feat: show image differences in pre-deploy overview --- cli/app/deploy.go | 8 +-- pkg/client/configs.go | 7 +- pkg/deploy/utils.go | 152 ++++++++++++++++++++++++++++++++++++------ 3 files changed, 137 insertions(+), 30 deletions(-) diff --git a/cli/app/deploy.go b/cli/app/deploy.go index a039a70b..d296cf7e 100644 --- a/cli/app/deploy.go +++ b/cli/app/deploy.go @@ -3,7 +3,6 @@ package app import ( "context" "errors" - "fmt" "strings" "coopcloud.tech/abra/cli/internal" @@ -209,10 +208,9 @@ checkout as-is. Recipe commit hashes are also supported as values for } // Gather images - - var imageInfo []string - for _, service := range compose.Services { - imageInfo = append(imageInfo, fmt.Sprintf("%s: %s", service.Name, service.Image)) + imageInfo, err := deploy.GatherImagesForDeploy(cl, app, compose) + if err != nil { + log.Fatal(err) } // Show deploy overview diff --git a/pkg/client/configs.go b/pkg/client/configs.go index 591327b2..22c693c8 100644 --- a/pkg/client/configs.go +++ b/pkg/client/configs.go @@ -39,10 +39,11 @@ func RemoveConfigs(cl *client.Client, ctx context.Context, configNames []string, return nil } -func GetConfigNameAndVersion(fullName string, stackName string) (string, string) { +func GetConfigNameAndVersion(fullName string, stackName string) (string, string, error) { name := strings.TrimPrefix(fullName, stackName + "_") if lastUnderscore := strings.LastIndex(name, "_"); lastUnderscore != -1 { - return name[0:lastUnderscore], name[lastUnderscore+1:] + return name[0:lastUnderscore], name[lastUnderscore+1:], nil + } else { + return "", "", errors.New(i18n.G("can't parse version from config '%s'", fullName)) } - return name, "" } diff --git a/pkg/deploy/utils.go b/pkg/deploy/utils.go index 72692024..f447e4ec 100644 --- a/pkg/deploy/utils.go +++ b/pkg/deploy/utils.go @@ -2,7 +2,9 @@ package deploy import ( "context" + "errors" "fmt" + "regexp" "sort" "strings" @@ -16,8 +18,8 @@ import ( dockerClient "github.com/docker/docker/client" ) -// GetConfigNamesForStack retrieves all Docker configs attached to services in a given stack. -func GetConfigNamesForStack(cl *dockerClient.Client, app appPkg.App) ([]string, error) { +// GetConfigsForStack retrieves all Docker configs attached to services in a given stack. +func GetConfigsForStack(cl *dockerClient.Client, app appPkg.App) (map[string]string, error) { filters, err := app.Filters(false, false) if err != nil { return nil, err @@ -31,25 +33,92 @@ func GetConfigNamesForStack(cl *dockerClient.Client, app appPkg.App) ([]string, return nil, err } - // Collect unique config names from all services - configNames := make(map[string]bool) + // Collect unique config names with versions + configs := make(map[string]string) for _, service := range services { if service.Spec.TaskTemplate.ContainerSpec != nil { for _, configRef := range service.Spec.TaskTemplate.ContainerSpec.Configs { - if configRef.ConfigName != "" { - configNames[configRef.ConfigName] = true + configName := configRef.ConfigName + if configName == "" { + continue + } + configBaseName, configVersion, err := client.GetConfigNameAndVersion(configName, app.StackName()) + if err != nil { + log.Warn(err) + continue + } + + existingConfigVersion, ok := configs[configBaseName] + if !ok { + // First time seeing this, add to map + configs[configBaseName] = configVersion + } else { + // Just make sure the versions are the same.. + if existingConfigVersion != configVersion { + log.Warnf("different versions for config '%s', '%s' and %s'", configBaseName, existingConfigVersion, configVersion) + } } } } } - // Convert map to slice - result := make([]string, 0, len(configNames)) - for name := range configNames { - result = append(result, name) + return configs, nil +} + +func GetImageNameAndTag(imageName string) (string, string, error) { + imageParts := regexp.MustCompile("^([^:]*):([^@]*)@?").FindSubmatch([]byte(imageName)) + + if len(imageParts) == 0 { + return "", "", errors.New("can't determine image version for image '%s'") + } + + imageBaseName := string(imageParts[1]) + imageTag := string(imageParts[2]) + + return imageBaseName, imageTag, nil +} + +// GetImagesForStack retrieves all Docker images for services in a given stack. +func GetImagesForStack(cl *dockerClient.Client, app appPkg.App) (map[string]string, error) { + filters, err := app.Filters(false, false) + if err != nil { + return nil, err } - return result, nil + // List all services in the stack + services, err := cl.ServiceList(context.Background(), swarm.ServiceListOptions{ + Filters: filters, + }) + if err != nil { + return nil, err + } + + // Collect unique image names with versions + images := make(map[string]string) + for _, service := range services { + if service.Spec.TaskTemplate.ContainerSpec != nil { + imageName := service.Spec.TaskTemplate.ContainerSpec.Image + + imageBaseName, imageTag, err := GetImageNameAndTag(imageName) + if err != nil { + log.Warn(err) + continue + } + + existingImageVersion, ok := images[imageBaseName] + if !ok { + // First time seeing this, add to map + images[imageBaseName] = imageTag + } else { + // Just make sure the versions are the same.. + if existingImageVersion != imageTag { + log.Warnf("different versions for image '%s', '%s' and %s'", imageBaseName, existingImageVersion, imageTag) + } + } + } + } + + return images, nil } func GatherSecretsForDeploy(cl *dockerClient.Client, app appPkg.App) ([]string, error) { @@ -73,21 +142,12 @@ func GatherSecretsForDeploy(cl *dockerClient.Client, app appPkg.App) ([]string, func GatherConfigsForDeploy(cl *dockerClient.Client, app appPkg.App, compose *composetypes.Config, abraShEnv map[string]string) ([]string, error) { // Get current configs from existing deployment - currentConfigNames, err := GetConfigNamesForStack(cl, app) + currentConfigs, err := GetConfigsForStack(cl, app) if err != nil { return nil, err } - log.Infof("Config names: %v", currentConfigNames) - - // Create map of current config base names to versions - currentConfigs := make(map[string]string) - for _, configName := range currentConfigNames { - baseName, version := client.GetConfigNameAndVersion(configName, app.StackName()) - currentConfigs[baseName] = version - } - - log.Infof("Configs: %v", currentConfigs) + log.Debugf("Deployed config names: %v", currentConfigs) // Get new configs from the compose specification newConfigs := compose.Configs @@ -116,3 +176,51 @@ func GatherConfigsForDeploy(cl *dockerClient.Client, app appPkg.App, compose *co return configInfo, nil } + +func GatherImagesForDeploy(cl *dockerClient.Client, app appPkg.App, compose *composetypes.Config) ([]string, error){ + + // Get current images from existing deployment + currentImages, err := GetImagesForStack(cl, app) + if err != nil { + return nil, err + } + + log.Infof("Deployed images: %v", currentImages) + + // Proposed new images from the compose files + newImages := make(map[string]string) + + for _, service := range compose.Services { + imageBaseName, imageTag, err := GetImageNameAndTag(service.Image) + if err != nil { + log.Warn(err) + continue + } + existingImageVersion, ok := newImages[imageBaseName] + if !ok { + // First time seeing this, add to map + newImages[imageBaseName] = imageTag + } else { + // Just make sure the versions are the same.. + if existingImageVersion != imageTag { + log.Warnf("different versions for image '%s', '%s' and %s'", imageBaseName, existingImageVersion, imageTag) + } + } + } + log.Infof("Proposed images: %v", newImages) + + var imageInfo []string + for newImageName, newImageVersion := range newImages { + if currentVersion, exists := currentImages[newImageName]; exists { + if currentVersion == newImageVersion { + imageInfo = append(imageInfo, fmt.Sprintf("%s: %s (unchanged)", newImageName, newImageVersion)) + } else { + imageInfo = append(imageInfo, fmt.Sprintf("%s: %s → %s", newImageName, currentVersion, newImageVersion)) + } + } else { + imageInfo = append(imageInfo, fmt.Sprintf("%s: %s (new)", newImageName, newImageVersion)) + } + } + + return imageInfo, nil +} -- 2.49.0 From 40b5c5cd6345956ce27c24736975045547db38fb Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Tue, 2 Sep 2025 13:58:45 -0400 Subject: [PATCH 13/28] feat: roll out pre-deploy changes to rollback and upgrade --- cli/app/deploy.go | 2 -- cli/app/rollback.go | 33 ++++++++++----------------------- cli/app/upgrade.go | 40 ++++++++++++++-------------------------- 3 files changed, 24 insertions(+), 51 deletions(-) diff --git a/cli/app/deploy.go b/cli/app/deploy.go index d296cf7e..03b33dc4 100644 --- a/cli/app/deploy.go +++ b/cli/app/deploy.go @@ -227,8 +227,6 @@ checkout as-is. Recipe commit hashes are also supported as values for ); err != nil { log.Fatal(err) } - // FIXME: just for debugging - return stack.WaitTimeout, err = appPkg.GetTimeoutFromLabel(compose, stackName) if err != nil { diff --git a/cli/app/rollback.go b/cli/app/rollback.go index d95d8551..8ac92f22 100644 --- a/cli/app/rollback.go +++ b/cli/app/rollback.go @@ -1,7 +1,6 @@ package app import ( - "context" "errors" "strings" @@ -9,6 +8,7 @@ import ( appPkg "coopcloud.tech/abra/pkg/app" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/config" + "coopcloud.tech/abra/pkg/deploy" "coopcloud.tech/abra/pkg/envfile" "coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/i18n" @@ -20,7 +20,6 @@ import ( "coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/log" "github.com/AlecAivazis/survey/v2" - "github.com/docker/docker/api/types" "github.com/spf13/cobra" ) @@ -192,36 +191,24 @@ beforehand. See "abra app backup" for more.`), } appPkg.SetUpdateLabel(compose, stackName, app.Env) - filters, err := app.Filters(false, false) + // Gather secrets + secretInfo, err := deploy.GatherSecretsForDeploy(cl, app) if err != nil { log.Fatal(err) } - secretList, err := cl.SecretList(context.Background(), types.SecretListOptions{Filters: filters}) + // Gather configs + configInfo, err := deploy.GatherConfigsForDeploy(cl, app, compose, abraShEnv) if err != nil { log.Fatal(err) } - var secretStrings []string - for _, cont := range secretList { - secretStrings = append(secretStrings, cont.Spec.Name) - } - - configList, err := cl.ConfigList(context.Background(), types.ConfigListOptions{Filters: filters}) + // Gather images + imageInfo, err := deploy.GatherImagesForDeploy(cl, app, compose) if err != nil { log.Fatal(err) } - var configStrings []string - for _, config := range configList { - configStrings = append(configStrings, config.Spec.Name) - } - - var imageStrings []string - for _, service := range compose.Services { - imageStrings = append(imageStrings, service.Image) - } - // NOTE(d1): no release notes implemeneted for rolling back if err := internal.DeployOverview( app, @@ -229,9 +216,9 @@ beforehand. See "abra app backup" for more.`), chosenDowngrade, "", downgradeWarnMessages, - strings.Join(secretStrings, "\n"), - strings.Join(configStrings, "\n"), - strings.Join(imageStrings, "\n"), + strings.Join(secretInfo, "\n"), + strings.Join(configInfo, "\n"), + strings.Join(imageInfo, "\n"), ); err != nil { log.Fatal(err) } diff --git a/cli/app/upgrade.go b/cli/app/upgrade.go index 839bd026..9b1a05f3 100644 --- a/cli/app/upgrade.go +++ b/cli/app/upgrade.go @@ -7,11 +7,11 @@ import ( "strings" "coopcloud.tech/abra/cli/internal" - "coopcloud.tech/abra/pkg/app" appPkg "coopcloud.tech/abra/pkg/app" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/config" + "coopcloud.tech/abra/pkg/deploy" "coopcloud.tech/abra/pkg/envfile" "coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/i18n" @@ -21,7 +21,6 @@ import ( stack "coopcloud.tech/abra/pkg/upstream/stack" "coopcloud.tech/tagcmp" "github.com/AlecAivazis/survey/v2" - "github.com/docker/docker/api/types" dockerClient "github.com/docker/docker/client" "github.com/spf13/cobra" ) @@ -217,35 +216,24 @@ beforehand. See "abra app backup" for more.`), } } - filters, err := app.Filters(false, false) + // Gather secrets + secretInfo, err := deploy.GatherSecretsForDeploy(cl, app) if err != nil { log.Fatal(err) } - secretList, err := cl.SecretList(context.Background(), types.SecretListOptions{Filters: filters}) + // Gather configs + configInfo, err := deploy.GatherConfigsForDeploy(cl, app, compose, abraShEnv) if err != nil { log.Fatal(err) } - var secretStrings []string - for _, cont := range secretList { - secretStrings = append(secretStrings, cont.Spec.Name) - } - - configList, err := cl.ConfigList(context.Background(), types.ConfigListOptions{Filters: filters}) + // Gather images + imageInfo, err := deploy.GatherImagesForDeploy(cl, app, compose) if err != nil { log.Fatal(err) } - var configStrings []string - for _, config := range configList { - configStrings = append(configStrings, config.Spec.Name) - } - - var imageStrings []string - for _, service := range compose.Services { - imageStrings = append(imageStrings, service.Image) - } if showReleaseNotes { fmt.Print(upgradeReleaseNotes) @@ -265,9 +253,9 @@ beforehand. See "abra app backup" for more.`), chosenUpgrade, upgradeReleaseNotes, upgradeWarnMessages, - strings.Join(secretStrings, "\n"), - strings.Join(configStrings, "\n"), - strings.Join(imageStrings, "\n"), + strings.Join(secretInfo, "\n"), + strings.Join(configInfo, "\n"), + strings.Join(imageInfo, "\n"), ); err != nil { log.Fatal(err) } @@ -345,7 +333,7 @@ func chooseUpgrade( } func getReleaseNotes( - app app.App, + app appPkg.App, versions []string, chosenUpgrade string, deployMeta stack.DeployMeta, @@ -390,7 +378,7 @@ func getReleaseNotes( // ensureUpgradesAvailable ensures that there are available upgrades. func ensureUpgradesAvailable( - app app.App, + app appPkg.App, versions []string, availableUpgrades *[]string, deployMeta stack.DeployMeta, @@ -422,7 +410,7 @@ func ensureUpgradesAvailable( // validateUpgradeVersionArg validates the specific version. func validateUpgradeVersionArg( specificVersion string, - app app.App, + app appPkg.App, deployMeta stack.DeployMeta, ) error { parsedSpecificVersion, err := tagcmp.Parse(specificVersion) @@ -449,7 +437,7 @@ func validateUpgradeVersionArg( // ensureDeployed ensures the app is deployed and if so, returns deployment // meta info. -func ensureDeployed(cl *dockerClient.Client, app app.App) (stack.DeployMeta, error) { +func ensureDeployed(cl *dockerClient.Client, app appPkg.App) (stack.DeployMeta, error) { log.Debug(i18n.G("checking whether %s is already deployed", app.StackName())) deployMeta, err := stack.IsDeployed(context.Background(), cl, app.StackName()) -- 2.49.0 From bf68ec56a32a25fcc56906a53317d8c00a5dbaf4 Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Tue, 2 Sep 2025 13:59:30 -0400 Subject: [PATCH 14/28] style: 4matting --- cli/app/upgrade.go | 1 - pkg/client/configs.go | 4 +- pkg/deploy/utils.go | 102 +++++++++++++++++++++--------------------- 3 files changed, 53 insertions(+), 54 deletions(-) diff --git a/cli/app/upgrade.go b/cli/app/upgrade.go index 9b1a05f3..9cf5cfdd 100644 --- a/cli/app/upgrade.go +++ b/cli/app/upgrade.go @@ -234,7 +234,6 @@ beforehand. See "abra app backup" for more.`), log.Fatal(err) } - if showReleaseNotes { fmt.Print(upgradeReleaseNotes) return diff --git a/pkg/client/configs.go b/pkg/client/configs.go index 22c693c8..f102467f 100644 --- a/pkg/client/configs.go +++ b/pkg/client/configs.go @@ -40,10 +40,10 @@ func RemoveConfigs(cl *client.Client, ctx context.Context, configNames []string, } func GetConfigNameAndVersion(fullName string, stackName string) (string, string, error) { - name := strings.TrimPrefix(fullName, stackName + "_") + name := strings.TrimPrefix(fullName, stackName+"_") if lastUnderscore := strings.LastIndex(name, "_"); lastUnderscore != -1 { return name[0:lastUnderscore], name[lastUnderscore+1:], nil } else { - return "", "", errors.New(i18n.G("can't parse version from config '%s'", fullName)) + return "", "", errors.New(i18n.G("can't parse version from config '%s'", fullName)) } } diff --git a/pkg/deploy/utils.go b/pkg/deploy/utils.go index f447e4ec..bd7a803a 100644 --- a/pkg/deploy/utils.go +++ b/pkg/deploy/utils.go @@ -13,8 +13,8 @@ import ( "coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/secret" - "github.com/docker/docker/api/types/swarm" composetypes "github.com/docker/cli/cli/compose/types" + "github.com/docker/docker/api/types/swarm" dockerClient "github.com/docker/docker/client" ) @@ -56,7 +56,7 @@ func GetConfigsForStack(cl *dockerClient.Client, app appPkg.App) (map[string]str // Just make sure the versions are the same.. if existingConfigVersion != configVersion { log.Warnf("different versions for config '%s', '%s' and %s'", configBaseName, existingConfigVersion, configVersion) - } + } } } } @@ -66,14 +66,14 @@ func GetConfigsForStack(cl *dockerClient.Client, app appPkg.App) (map[string]str } func GetImageNameAndTag(imageName string) (string, string, error) { - imageParts := regexp.MustCompile("^([^:]*):([^@]*)@?").FindSubmatch([]byte(imageName)) + imageParts := regexp.MustCompile("^([^:]*):([^@]*)@?").FindSubmatch([]byte(imageName)) - if len(imageParts) == 0 { - return "", "", errors.New("can't determine image version for image '%s'") - } + if len(imageParts) == 0 { + return "", "", errors.New("can't determine image version for image '%s'") + } - imageBaseName := string(imageParts[1]) - imageTag := string(imageParts[2]) + imageBaseName := string(imageParts[1]) + imageTag := string(imageParts[2]) return imageBaseName, imageTag, nil } @@ -113,7 +113,7 @@ func GetImagesForStack(cl *dockerClient.Client, app appPkg.App) (map[string]stri // Just make sure the versions are the same.. if existingImageVersion != imageTag { log.Warnf("different versions for image '%s', '%s' and %s'", imageBaseName, existingImageVersion, imageTag) - } + } } } } @@ -123,61 +123,61 @@ func GetImagesForStack(cl *dockerClient.Client, app appPkg.App) (map[string]stri func GatherSecretsForDeploy(cl *dockerClient.Client, app appPkg.App) ([]string, error) { - secStats, err := secret.PollSecretsStatus(cl, app) - if err != nil { - return nil, err - } + secStats, err := secret.PollSecretsStatus(cl, app) + if err != nil { + return nil, err + } - var secretInfo []string + var secretInfo []string - // Sort secrets to ensure reproducible output - sort.Slice(secStats, func(i, j int) bool { - return secStats[i].LocalName < secStats[j].LocalName - }) - for _, secStat := range secStats { - secretInfo = append(secretInfo, fmt.Sprintf("%s: %s", secStat.LocalName, secStat.Version)) - } + // Sort secrets to ensure reproducible output + sort.Slice(secStats, func(i, j int) bool { + return secStats[i].LocalName < secStats[j].LocalName + }) + for _, secStat := range secStats { + secretInfo = append(secretInfo, fmt.Sprintf("%s: %s", secStat.LocalName, secStat.Version)) + } return secretInfo, nil } func GatherConfigsForDeploy(cl *dockerClient.Client, app appPkg.App, compose *composetypes.Config, abraShEnv map[string]string) ([]string, error) { - // Get current configs from existing deployment - currentConfigs, err := GetConfigsForStack(cl, app) - if err != nil { - return nil, err + // Get current configs from existing deployment + currentConfigs, err := GetConfigsForStack(cl, app) + if err != nil { + return nil, err + } + + log.Debugf("Deployed config names: %v", currentConfigs) + + // Get new configs from the compose specification + newConfigs := compose.Configs + + var configInfo []string + for configName := range newConfigs { + log.Debugf("Searching abra.sh for version for %s", configName) + versionKey := strings.ToUpper(configName) + "_VERSION" + newVersion, exists := abraShEnv[versionKey] + if !exists { + log.Warnf("No version found for config %s", configName) + configInfo = append(configInfo, fmt.Sprintf("%s: ? (missing version)", configName)) + continue } - log.Debugf("Deployed config names: %v", currentConfigs) - - // Get new configs from the compose specification - newConfigs := compose.Configs - - var configInfo []string - for configName := range newConfigs { - log.Debugf("Searching abra.sh for version for %s", configName) - versionKey := strings.ToUpper(configName) + "_VERSION" - newVersion, exists := abraShEnv[versionKey] - if !exists { - log.Warnf("No version found for config %s", configName) - configInfo = append(configInfo, fmt.Sprintf("%s: ? (missing version)", configName)) - continue - } - - if currentVersion, exists := currentConfigs[configName]; exists { - if currentVersion == newVersion { - configInfo = append(configInfo, fmt.Sprintf("%s: %s (unchanged)", configName, newVersion)) - } else { - configInfo = append(configInfo, fmt.Sprintf("%s: %s → %s", configName, currentVersion, newVersion)) - } + if currentVersion, exists := currentConfigs[configName]; exists { + if currentVersion == newVersion { + configInfo = append(configInfo, fmt.Sprintf("%s: %s (unchanged)", configName, newVersion)) } else { - configInfo = append(configInfo, fmt.Sprintf("%s: %s (new)", configName, newVersion)) + configInfo = append(configInfo, fmt.Sprintf("%s: %s → %s", configName, currentVersion, newVersion)) } - } + } else { + configInfo = append(configInfo, fmt.Sprintf("%s: %s (new)", configName, newVersion)) + } + } return configInfo, nil } -func GatherImagesForDeploy(cl *dockerClient.Client, app appPkg.App, compose *composetypes.Config) ([]string, error){ +func GatherImagesForDeploy(cl *dockerClient.Client, app appPkg.App, compose *composetypes.Config) ([]string, error) { // Get current images from existing deployment currentImages, err := GetImagesForStack(cl, app) @@ -204,7 +204,7 @@ func GatherImagesForDeploy(cl *dockerClient.Client, app appPkg.App, compose *com // Just make sure the versions are the same.. if existingImageVersion != imageTag { log.Warnf("different versions for image '%s', '%s' and %s'", imageBaseName, existingImageVersion, imageTag) - } + } } } log.Infof("Proposed images: %v", newImages) -- 2.49.0 From 7e217f8892f979e2a31290a0f940b9f94a33094e Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Tue, 2 Sep 2025 14:00:40 -0400 Subject: [PATCH 15/28] chore: regen POT --- pkg/i18n/locales/abra.pot | 221 ++++++++++++++++++++------------------ 1 file changed, 117 insertions(+), 104 deletions(-) diff --git a/pkg/i18n/locales/abra.pot b/pkg/i18n/locales/abra.pot index 84f27786..00e0fb90 100644 --- a/pkg/i18n/locales/abra.pot +++ b/pkg/i18n/locales/abra.pot @@ -7,7 +7,7 @@ msgid "" msgstr "Project-Id-Version: \n" "Report-Msgid-Bugs-To: EMAIL\n" - "POT-Creation-Date: 2025-09-06 08:28+0200\n" + "POT-Creation-Date: 2025-09-08 22:06-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -111,7 +111,7 @@ msgid " # run with args/flags\n" " abra app run 1312.net app --user nobody -- ls -lha" msgstr "" -#: ./cli/app/deploy.go:42 +#: ./cli/app/deploy.go:43 msgid " # standard deployment\n" " abra app deploy 1312.net\n" "\n" @@ -149,7 +149,7 @@ msgstr "" msgid " abra upgrade --rc" msgstr "" -#: ./cli/app/rollback.go:49 +#: ./cli/app/rollback.go:50 msgid " # standard rollback\n" " abra app rollback 1312.net\n" "\n" @@ -196,7 +196,7 @@ msgstr "" msgid "%s (created %v)" msgstr "" -#: ./cli/internal/deploy.go:86 +#: ./cli/internal/deploy.go:107 #, c-format msgid "%s OVERVIEW" msgstr "" @@ -226,7 +226,7 @@ msgstr "" msgid "%s does not exist for %s, use /bin/sh as fallback" msgstr "" -#: ./cli/app/cmd.go:114 ./cli/internal/deploy.go:214 +#: ./cli/app/cmd.go:114 ./cli/internal/deploy.go:235 #, c-format msgid "%s does not exist for %s?" msgstr "" @@ -311,7 +311,7 @@ msgstr "" msgid "%s inserted into pass store" msgstr "" -#: ./cli/app/deploy.go:102 +#: ./cli/app/deploy.go:103 #, c-format msgid "%s is already deployed" msgstr "" @@ -336,17 +336,17 @@ msgstr "" msgid "%s is missing the TYPE env var?" msgstr "" -#: ./cli/app/rollback.go:285 ./cli/app/rollback.go:289 +#: ./cli/app/rollback.go:307 ./cli/app/rollback.go:311 #, c-format msgid "%s is not a downgrade for %s?" msgstr "" -#: ./cli/app/upgrade.go:406 ./cli/app/upgrade.go:410 +#: ./cli/app/upgrade.go:427 ./cli/app/upgrade.go:431 #, c-format msgid "%s is not an upgrade for %s?" msgstr "" -#: ./cli/app/logs.go:65 ./cli/app/ps.go:62 ./cli/app/restart.go:100 ./cli/app/services.go:55 ./cli/app/undeploy.go:65 ./cli/app/upgrade.go:427 ./cli/updater/updater.go:259 +#: ./cli/app/logs.go:65 ./cli/app/ps.go:62 ./cli/app/restart.go:100 ./cli/app/services.go:55 ./cli/app/undeploy.go:65 ./cli/app/upgrade.go:448 ./cli/updater/updater.go:259 #, c-format msgid "%s is not deployed?" msgstr "" @@ -361,7 +361,7 @@ msgstr "" msgid "%s is still deployed. Run \"abra app undeploy %s\"" msgstr "" -#: ./cli/app/deploy.go:175 ./cli/app/upgrade.go:214 +#: ./cli/app/deploy.go:176 ./cli/app/upgrade.go:214 #, c-format msgid "%s missing from %s.env" msgstr "" @@ -506,12 +506,12 @@ msgstr "" msgid "%s: waiting %d seconds before next retry" msgstr "" -#: ./cli/app/upgrade.go:401 +#: ./cli/app/upgrade.go:422 #, c-format msgid "'%s' is not a known version" msgstr "" -#: ./cli/app/rollback.go:280 ./cli/app/upgrade.go:396 +#: ./cli/app/rollback.go:302 ./cli/app/upgrade.go:417 #, c-format msgid "'%s' is not a known version for %s" msgstr "" @@ -582,7 +582,7 @@ msgstr "" msgid "Both local recipe and live deployment labels are shown." msgstr "" -#: ./cli/app/backup.go:319 ./cli/app/backup.go:335 ./cli/app/check.go:95 ./cli/app/cmd.go:285 ./cli/app/cp.go:385 ./cli/app/deploy.go:342 ./cli/app/labels.go:143 ./cli/app/new.go:377 ./cli/app/ps.go:213 ./cli/app/restart.go:162 ./cli/app/restore.go:138 ./cli/app/secret.go:569 ./cli/app/secret.go:609 ./cli/app/secret.go:633 ./cli/app/secret.go:641 ./cli/catalogue/catalogue.go:318 ./cli/recipe/lint.go:137 ./cli/updater/updater.go:552 +#: ./cli/app/backup.go:319 ./cli/app/backup.go:335 ./cli/app/check.go:95 ./cli/app/cmd.go:285 ./cli/app/cp.go:385 ./cli/app/deploy.go:366 ./cli/app/labels.go:143 ./cli/app/new.go:377 ./cli/app/ps.go:213 ./cli/app/restart.go:162 ./cli/app/restore.go:138 ./cli/app/secret.go:569 ./cli/app/secret.go:609 ./cli/app/secret.go:633 ./cli/app/secret.go:641 ./cli/catalogue/catalogue.go:318 ./cli/recipe/lint.go:137 ./cli/updater/updater.go:552 msgid "C" msgstr "" @@ -590,7 +590,7 @@ msgstr "" msgid "CHAOS" msgstr "" -#: ./cli/internal/deploy.go:120 +#: ./cli/internal/deploy.go:141 msgid "CHAOS DEPLOY" msgstr "" @@ -609,15 +609,19 @@ msgstr "" msgid "COMPOSE_FILE detected, loading %s" msgstr "" -#: ./cli/internal/deploy.go:78 +#: ./cli/internal/deploy.go:81 msgid "CONFIG" msgstr "" +#: ./cli/internal/deploy.go:101 +msgid "CONFIGS" +msgstr "" + #: ./cli/app/secret.go:481 msgid "CREATED ON SERVER" msgstr "" -#: ./cli/internal/deploy.go:80 +#: ./cli/internal/deploy.go:83 msgid "CURRENT DEPLOYMENT" msgstr "" @@ -724,11 +728,11 @@ msgid "Creates a new app from a default recipe.\n" "on your $PATH." msgstr "" -#: ./cli/app/deploy.go:358 ./cli/app/new.go:353 ./cli/app/rollback.go:337 ./cli/app/upgrade.go:447 +#: ./cli/app/deploy.go:382 ./cli/app/new.go:353 ./cli/app/rollback.go:359 ./cli/app/upgrade.go:468 msgid "D" msgstr "" -#: ./cli/internal/deploy.go:133 ./cli/internal/deploy.go:137 +#: ./cli/internal/deploy.go:154 ./cli/internal/deploy.go:158 msgid "DEPLOY" msgstr "" @@ -736,20 +740,20 @@ msgstr "" msgid "DEPLOYED LABELS" msgstr "" -#: ./cli/app/list.go:222 ./cli/internal/deploy.go:75 ./cli/internal/deploy.go:173 +#: ./cli/app/list.go:222 ./cli/internal/deploy.go:78 ./cli/internal/deploy.go:194 msgid "DOMAIN" msgstr "" -#: ./cli/internal/deploy.go:142 +#: ./cli/internal/deploy.go:163 msgid "DOWNGRADE" msgstr "" #. translators: Short description for `app deploy` command -#: ./cli/app/deploy.go:36 +#: ./cli/app/deploy.go:37 msgid "Deploy an app" msgstr "" -#: ./cli/app/deploy.go:37 +#: ./cli/app/deploy.go:38 msgid "Deploy an app.\n" "\n" "This command supports chaos operations. Use \"--chaos/-C\" to deploy your recipe\n" @@ -778,7 +782,7 @@ msgstr "" msgid "ENV OVERVIEW" msgstr "" -#: ./cli/internal/deploy.go:81 +#: ./cli/internal/deploy.go:84 msgid "ENV VERSION" msgstr "" @@ -901,6 +905,10 @@ msgstr "" msgid "IMAGE" msgstr "" +#: ./cli/internal/deploy.go:87 +msgid "IMAGES" +msgstr "" + #. translators: Short description for `app secret insert` command #: ./cli/app/secret.go:162 msgid "Insert secret" @@ -960,7 +968,7 @@ msgstr "" msgid "List volumes associated with an app" msgstr "" -#: ./cli/internal/deploy.go:181 +#: ./cli/internal/deploy.go:202 msgid "MOVE OVERVIEW" msgstr "" @@ -1031,15 +1039,15 @@ msgstr "" msgid "NAME" msgstr "" -#: ./cli/internal/deploy.go:129 +#: ./cli/internal/deploy.go:150 msgid "NEW DEPLOY" msgstr "" -#: ./cli/internal/deploy.go:82 +#: ./cli/internal/deploy.go:85 msgid "NEW DEPLOYMENT" msgstr "" -#: ./cli/internal/deploy.go:176 +#: ./cli/internal/deploy.go:197 msgid "NEW SERVER" msgstr "" @@ -1059,7 +1067,7 @@ msgid "Notify on new versions for deployed apps.\n" "Use \"--major/-m\" to include new major versions." msgstr "" -#: ./cli/internal/deploy.go:175 +#: ./cli/internal/deploy.go:196 msgid "OLD SERVER" msgstr "" @@ -1087,7 +1095,7 @@ msgstr "" msgid "README.md metadata filled in" msgstr "" -#: ./cli/app/list.go:222 ./cli/internal/deploy.go:76 ./cli/internal/deploy.go:174 +#: ./cli/app/list.go:222 ./cli/internal/deploy.go:79 ./cli/internal/deploy.go:195 msgid "RECIPE" msgstr "" @@ -1176,7 +1184,7 @@ msgid "Restore a snapshot" msgstr "" #. translators: Short description for `app rollback` command -#: ./cli/app/rollback.go:34 +#: ./cli/app/rollback.go:35 msgid "Roll an app back to a previous version" msgstr "" @@ -1207,7 +1215,7 @@ msgstr "" msgid "S" msgstr "" -#: ./cli/internal/deploy.go:177 +#: ./cli/internal/deploy.go:93 ./cli/internal/deploy.go:198 msgid "SECRETS" msgstr "" @@ -1215,7 +1223,7 @@ msgstr "" msgid "SECRETS OVERVIEW" msgstr "" -#: ./cli/app/list.go:222 ./cli/internal/deploy.go:77 +#: ./cli/app/list.go:222 ./cli/internal/deploy.go:80 msgid "SERVER" msgstr "" @@ -1359,7 +1367,7 @@ msgid "This command restarts services within a deployed app.\n" "Pass \"--all-services/-a\" to restart all services." msgstr "" -#: ./cli/app/rollback.go:35 +#: ./cli/app/rollback.go:36 msgid "This command rolls an app back to a previous version.\n" "\n" "Unlike \"abra app deploy\", chaos operations are not supported here. Only recipe\n" @@ -1423,15 +1431,15 @@ msgid "To load completions:\n" " # and source this file from your PowerShell profile." msgstr "" -#: ./cli/internal/deploy.go:123 +#: ./cli/internal/deploy.go:144 msgid "UNCHAOS DEPLOY" msgstr "" -#: ./cli/internal/deploy.go:117 +#: ./cli/internal/deploy.go:138 msgid "UNDEPLOY" msgstr "" -#: ./cli/app/list.go:228 ./cli/internal/deploy.go:140 +#: ./cli/app/list.go:228 ./cli/internal/deploy.go:161 msgid "UPGRADE" msgstr "" @@ -1557,7 +1565,7 @@ msgstr "" msgid "VERSION" msgstr "" -#: ./cli/internal/deploy.go:178 +#: ./cli/internal/deploy.go:199 msgid "VOLUMES" msgstr "" @@ -1773,7 +1781,7 @@ msgstr "" msgid "attempting to run %s" msgstr "" -#: ./cli/app/deploy.go:238 ./cli/app/upgrade.go:273 +#: ./cli/app/deploy.go:262 ./cli/app/upgrade.go:294 #, c-format msgid "attempting to run post deploy commands, saw: %s" msgstr "" @@ -1798,7 +1806,7 @@ msgstr "" msgid "autocomplete [bash|zsh|fish|powershell]" msgstr "" -#: ./cli/app/deploy.go:65 ./cli/app/logs.go:39 ./cli/app/rollback.go:65 ./cli/app/secret.go:49 ./cli/app/secret.go:191 ./cli/app/secret.go:360 ./cli/app/upgrade.go:64 ./pkg/autocomplete/autocomplete.go:18 ./pkg/autocomplete/autocomplete.go:33 ./pkg/autocomplete/autocomplete.go:44 ./pkg/autocomplete/autocomplete.go:50 ./pkg/autocomplete/autocomplete.go:70 ./pkg/autocomplete/autocomplete.go:88 ./pkg/autocomplete/autocomplete.go:104 ./pkg/autocomplete/autocomplete.go:110 ./pkg/autocomplete/autocomplete.go:125 +#: ./cli/app/deploy.go:66 ./cli/app/logs.go:39 ./cli/app/rollback.go:66 ./cli/app/secret.go:49 ./cli/app/secret.go:191 ./cli/app/secret.go:360 ./cli/app/upgrade.go:64 ./pkg/autocomplete/autocomplete.go:18 ./pkg/autocomplete/autocomplete.go:33 ./pkg/autocomplete/autocomplete.go:44 ./pkg/autocomplete/autocomplete.go:50 ./pkg/autocomplete/autocomplete.go:70 ./pkg/autocomplete/autocomplete.go:88 ./pkg/autocomplete/autocomplete.go:104 ./pkg/autocomplete/autocomplete.go:110 ./pkg/autocomplete/autocomplete.go:125 #, c-format msgid "autocomplete failed: %s" msgstr "" @@ -1863,7 +1871,7 @@ msgstr "" #. no spaces in between #. translators: `abra app cp` aliases. use a comma separated list of aliases with #. no spaces in between -#: ./cli/app/backup.go:148 ./cli/app/cp.go:30 ./cli/app/deploy.go:366 ./cli/app/rollback.go:345 ./cli/app/upgrade.go:455 +#: ./cli/app/backup.go:148 ./cli/app/cp.go:30 ./cli/app/deploy.go:390 ./cli/app/rollback.go:367 ./cli/app/upgrade.go:476 msgid "c" msgstr "" @@ -1885,6 +1893,11 @@ msgstr "" msgid "can't copy dir to file" msgstr "" +#: ./pkg/client/configs.go:47 +#, c-format +msgid "can't parse version from config '%s'" +msgstr "" + #: ./cli/internal/validate.go:35 #, c-format msgid "can't read local recipes: %s" @@ -1895,7 +1908,7 @@ msgstr "" msgid "can't separate key from value: %s (this variable is probably unset)" msgstr "" -#: ./cli/internal/deploy.go:202 +#: ./cli/internal/deploy.go:223 msgid "cancelled" msgstr "" @@ -1932,7 +1945,7 @@ msgstr "" msgid "cannot use '[secret] [version]' and '--all' together" msgstr "" -#: ./cli/app/deploy.go:277 +#: ./cli/app/deploy.go:301 msgid "cannot use --chaos and --latest together" msgstr "" @@ -1956,11 +1969,11 @@ msgstr "" msgid "cannot use [service] and --all-services/-a together" msgstr "" -#: ./cli/app/deploy.go:269 ./cli/app/new.go:76 +#: ./cli/app/deploy.go:293 ./cli/app/new.go:76 msgid "cannot use [version] and --chaos together" msgstr "" -#: ./cli/app/deploy.go:273 +#: ./cli/app/deploy.go:297 msgid "cannot use [version] and --latest together" msgstr "" @@ -1992,7 +2005,7 @@ msgstr "" msgid "cfg" msgstr "" -#: ./cli/app/backup.go:318 ./cli/app/backup.go:334 ./cli/app/check.go:94 ./cli/app/cmd.go:284 ./cli/app/cp.go:384 ./cli/app/deploy.go:341 ./cli/app/labels.go:142 ./cli/app/new.go:376 ./cli/app/ps.go:212 ./cli/app/restart.go:161 ./cli/app/restore.go:137 ./cli/app/secret.go:568 ./cli/app/secret.go:608 ./cli/app/secret.go:632 ./cli/app/secret.go:640 ./cli/catalogue/catalogue.go:317 ./cli/recipe/lint.go:136 ./cli/updater/updater.go:551 +#: ./cli/app/backup.go:318 ./cli/app/backup.go:334 ./cli/app/check.go:94 ./cli/app/cmd.go:284 ./cli/app/cp.go:384 ./cli/app/deploy.go:365 ./cli/app/labels.go:142 ./cli/app/new.go:376 ./cli/app/ps.go:212 ./cli/app/restart.go:161 ./cli/app/restore.go:137 ./cli/app/secret.go:568 ./cli/app/secret.go:608 ./cli/app/secret.go:632 ./cli/app/secret.go:640 ./cli/catalogue/catalogue.go:317 ./cli/recipe/lint.go:136 ./cli/updater/updater.go:551 msgid "chaos" msgstr "" @@ -2005,7 +2018,7 @@ msgstr "" msgid "check for major updates" msgstr "" -#: ./cli/app/deploy.go:94 ./cli/app/undeploy.go:57 ./cli/app/upgrade.go:419 +#: ./cli/app/deploy.go:95 ./cli/app/undeploy.go:57 ./cli/app/upgrade.go:440 #, c-format msgid "checking whether %s is already deployed" msgstr "" @@ -2026,7 +2039,7 @@ msgstr "" msgid "choosing %s as new version for %s" msgstr "" -#: ./cli/app/rollback.go:152 +#: ./cli/app/rollback.go:153 #, c-format msgid "choosing %s as version to rollback" msgstr "" @@ -2117,7 +2130,7 @@ msgstr "" msgid "compose: %s, " msgstr "" -#: ./pkg/client/configs.go:35 +#: ./pkg/client/configs.go:36 #, c-format msgid "conf %s: %s" msgstr "" @@ -2156,7 +2169,7 @@ msgstr "" msgid "considering %s config(s) for tag update" msgstr "" -#: ./cli/app/undeploy.go:132 ./cli/server/prune.go:53 +#: ./cli/app/undeploy.go:135 ./cli/server/prune.go:53 #, c-format msgid "containers pruned: %d; space reclaimed: %s" msgstr "" @@ -2287,7 +2300,7 @@ msgstr "" msgid "critical errors present in %s config" msgstr "" -#: ./cli/app/rollback.go:275 +#: ./cli/app/rollback.go:297 #, c-format msgid "current deployment '%s' is not a known version for %s" msgstr "" @@ -2303,7 +2316,7 @@ msgstr "" #. no spaces in between #. translators: `abra recipe diff` aliases. use a comma separated list of aliases #. with no spaces in between -#: ./cli/app/backup.go:73 ./cli/app/deploy.go:29 ./cli/recipe/diff.go:16 ./cli/updater/updater.go:505 +#: ./cli/app/backup.go:73 ./cli/app/deploy.go:30 ./cli/recipe/diff.go:16 ./cli/updater/updater.go:505 msgid "d" msgstr "" @@ -2322,7 +2335,7 @@ msgid "deleted %s successfully from server" msgstr "" #. translators: `app deploy` command -#: ./cli/app/deploy.go:33 +#: ./cli/app/deploy.go:34 msgid "deploy [version] [flags]" msgstr "" @@ -2338,7 +2351,7 @@ msgstr "" msgid "deploy labels stanza present" msgstr "" -#: ./cli/app/deploy.go:376 +#: ./cli/app/deploy.go:400 msgid "deploy latest recipe version" msgstr "" @@ -2350,7 +2363,7 @@ msgstr "" msgid "deploy timed out 🟠" msgstr "" -#: ./cli/internal/deploy.go:109 +#: ./cli/internal/deploy.go:130 msgid "deployment cancelled" msgstr "" @@ -2415,11 +2428,11 @@ msgstr "" msgid "dirty: %v, " msgstr "" -#: ./cli/app/deploy.go:368 ./cli/app/rollback.go:347 ./cli/app/upgrade.go:457 +#: ./cli/app/deploy.go:392 ./cli/app/rollback.go:369 ./cli/app/upgrade.go:478 msgid "disable converge logic checks" msgstr "" -#: ./cli/app/deploy.go:360 ./cli/app/rollback.go:339 ./cli/app/upgrade.go:449 +#: ./cli/app/deploy.go:384 ./cli/app/rollback.go:361 ./cli/app/upgrade.go:470 msgid "disable public DNS checks" msgstr "" @@ -2477,7 +2490,7 @@ msgstr "" msgid "download [flags]" msgstr "" -#: ./cli/internal/deploy.go:192 +#: ./cli/internal/deploy.go:213 msgid "dry run" msgstr "" @@ -2564,7 +2577,7 @@ msgstr "" msgid "ensure \"image: ...\" set on all services" msgstr "" -#: ./cli/app/deploy.go:113 +#: ./cli/app/deploy.go:114 #, c-format msgid "ensure recipe: %s" msgstr "" @@ -2657,7 +2670,7 @@ msgstr "" #. translators: `abra recipe fetch` aliases. use a comma separated list of aliases #. with no spaces in between -#: ./cli/app/deploy.go:350 ./cli/app/remove.go:163 ./cli/app/rollback.go:329 ./cli/app/secret.go:593 ./cli/app/upgrade.go:439 ./cli/app/volume.go:217 ./cli/recipe/fetch.go:20 ./cli/recipe/fetch.go:138 +#: ./cli/app/deploy.go:374 ./cli/app/remove.go:163 ./cli/app/rollback.go:351 ./cli/app/secret.go:593 ./cli/app/upgrade.go:460 ./cli/app/volume.go:217 ./cli/recipe/fetch.go:20 ./cli/recipe/fetch.go:138 msgid "f" msgstr "" @@ -2893,7 +2906,7 @@ msgstr "" msgid "for %s read env %s with value: %s from docker service" msgstr "" -#: ./cli/app/deploy.go:349 ./cli/app/remove.go:162 ./cli/app/rollback.go:328 ./cli/app/upgrade.go:438 ./cli/app/volume.go:216 ./cli/recipe/fetch.go:137 +#: ./cli/app/deploy.go:373 ./cli/app/remove.go:162 ./cli/app/rollback.go:350 ./cli/app/upgrade.go:459 ./cli/app/volume.go:216 ./cli/recipe/fetch.go:137 msgid "force" msgstr "" @@ -2952,7 +2965,7 @@ msgstr "" msgid "generated secrets %s shown again, please take note of them %s" msgstr "" -#: ./cli/app/deploy.go:107 +#: ./cli/app/deploy.go:108 #, c-format msgid "get deploy version: %s" msgstr "" @@ -3112,11 +3125,11 @@ msgstr "" msgid "id: %s, " msgstr "" -#: ./cli/app/backup.go:321 ./cli/app/backup.go:337 ./cli/app/check.go:97 ./cli/app/cmd.go:287 ./cli/app/cp.go:387 ./cli/app/deploy.go:344 ./cli/app/labels.go:145 ./cli/app/new.go:379 ./cli/app/ps.go:215 ./cli/app/restart.go:164 ./cli/app/restore.go:140 ./cli/app/secret.go:571 ./cli/app/secret.go:611 ./cli/app/secret.go:635 ./cli/app/secret.go:643 ./cli/catalogue/catalogue.go:320 ./cli/recipe/lint.go:139 ./cli/updater/updater.go:554 +#: ./cli/app/backup.go:321 ./cli/app/backup.go:337 ./cli/app/check.go:97 ./cli/app/cmd.go:287 ./cli/app/cp.go:387 ./cli/app/deploy.go:368 ./cli/app/labels.go:145 ./cli/app/new.go:379 ./cli/app/ps.go:215 ./cli/app/restart.go:164 ./cli/app/restore.go:140 ./cli/app/secret.go:571 ./cli/app/secret.go:611 ./cli/app/secret.go:635 ./cli/app/secret.go:643 ./cli/catalogue/catalogue.go:320 ./cli/recipe/lint.go:139 ./cli/updater/updater.go:554 msgid "ignore uncommitted recipes changes" msgstr "" -#: ./cli/app/undeploy.go:147 ./cli/server/prune.go:74 +#: ./cli/app/undeploy.go:150 ./cli/server/prune.go:74 #, c-format msgid "images pruned: %d; space reclaimed: %s" msgstr "" @@ -3305,7 +3318,7 @@ msgstr "" #. no spaces in between #. translators: `abra recipe lint` aliases. use a comma separated list of #. aliases with no spaces in between -#: ./cli/app/cmd.go:261 ./cli/app/deploy.go:374 ./cli/app/logs.go:20 ./cli/recipe/lint.go:17 ./cli/server/add.go:207 +#: ./cli/app/cmd.go:261 ./cli/app/deploy.go:398 ./cli/app/logs.go:20 ./cli/recipe/lint.go:17 ./cli/server/add.go:207 msgid "l" msgstr "" @@ -3314,7 +3327,7 @@ msgstr "" msgid "labels [flags]" msgstr "" -#: ./cli/app/deploy.go:373 ./cli/app/list.go:183 +#: ./cli/app/deploy.go:397 ./cli/app/list.go:183 msgid "latest" msgstr "" @@ -3554,7 +3567,7 @@ msgstr "" msgid "network %q is declared as external, but it is not in the right scope: %q instead of \"swarm\"" msgstr "" -#: ./cli/app/undeploy.go:139 ./cli/server/prune.go:60 +#: ./cli/app/undeploy.go:142 ./cli/server/prune.go:60 #, c-format msgid "networks pruned: %d" msgstr "" @@ -3617,7 +3630,7 @@ msgstr "" msgid "no app provided" msgstr "" -#: ./cli/app/rollback.go:127 +#: ./cli/app/rollback.go:128 msgid "no available downgrades" msgstr "" @@ -3767,11 +3780,11 @@ msgstr "" msgid "no volumes to remove" msgstr "" -#: ./cli/app/deploy.go:365 ./cli/app/rollback.go:344 ./cli/app/upgrade.go:454 +#: ./cli/app/deploy.go:389 ./cli/app/rollback.go:366 ./cli/app/upgrade.go:475 msgid "no-converge-checks" msgstr "" -#: ./cli/app/deploy.go:357 ./cli/app/rollback.go:336 ./cli/app/upgrade.go:446 +#: ./cli/app/deploy.go:381 ./cli/app/rollback.go:358 ./cli/app/upgrade.go:467 msgid "no-domain-checks" msgstr "" @@ -3783,7 +3796,7 @@ msgstr "" msgid "no-tty" msgstr "" -#: ./cli/internal/deploy.go:222 +#: ./cli/internal/deploy.go:243 #, c-format msgid "not enough arguments: %s" msgstr "" @@ -3836,7 +3849,7 @@ msgstr "" msgid "only show errors" msgstr "" -#: ./cli/app/upgrade.go:465 +#: ./cli/app/upgrade.go:486 msgid "only show release notes" msgstr "" @@ -3848,7 +3861,7 @@ msgstr "" #. with no spaces in between #. translators: `abra server prune` aliases. use a comma separated list of #. aliases with no spaces in between -#: ./cli/app/backup.go:295 ./cli/app/new.go:361 ./cli/app/ps.go:29 ./cli/app/secret.go:561 ./cli/app/secret.go:585 ./cli/app/secret.go:625 ./cli/app/undeploy.go:160 ./cli/catalogue/catalogue.go:294 ./cli/recipe/list.go:112 ./cli/recipe/release.go:672 ./cli/server/prune.go:18 +#: ./cli/app/backup.go:295 ./cli/app/new.go:361 ./cli/app/ps.go:29 ./cli/app/secret.go:561 ./cli/app/secret.go:585 ./cli/app/secret.go:625 ./cli/app/undeploy.go:163 ./cli/catalogue/catalogue.go:294 ./cli/recipe/list.go:112 ./cli/recipe/release.go:672 ./cli/server/prune.go:18 msgid "p" msgstr "" @@ -3867,22 +3880,22 @@ msgstr "" msgid "parsed following command arguments: %s" msgstr "" -#: ./cli/app/upgrade.go:322 +#: ./cli/app/upgrade.go:343 #, c-format msgid "parsing chosen upgrade version failed: %s" msgstr "" -#: ./cli/app/upgrade.go:366 +#: ./cli/app/upgrade.go:387 #, c-format msgid "parsing deployed version failed: %s" msgstr "" -#: ./cli/app/upgrade.go:327 +#: ./cli/app/upgrade.go:348 #, c-format msgid "parsing deployment version failed: %s" msgstr "" -#: ./cli/app/upgrade.go:333 ./cli/app/upgrade.go:372 +#: ./cli/app/upgrade.go:354 ./cli/app/upgrade.go:393 #, c-format msgid "parsing recipe version failed: %s" msgstr "" @@ -3907,7 +3920,7 @@ msgstr "" msgid "pattern" msgstr "" -#: ./cli/app/deploy.go:352 ./cli/app/remove.go:165 ./cli/app/rollback.go:331 ./cli/app/upgrade.go:441 ./cli/app/volume.go:219 +#: ./cli/app/deploy.go:376 ./cli/app/remove.go:165 ./cli/app/rollback.go:353 ./cli/app/upgrade.go:462 ./cli/app/volume.go:219 msgid "perform action without further prompt" msgstr "" @@ -3916,22 +3929,22 @@ msgstr "" msgid "please fix your synced label for %s and re-run this command" msgstr "" -#: ./cli/app/rollback.go:243 +#: ./cli/app/rollback.go:265 #, c-format msgid "please select a downgrade (version: %s):" msgstr "" -#: ./cli/app/rollback.go:248 +#: ./cli/app/rollback.go:270 #, c-format msgid "please select a downgrade (version: %s, chaos: %s):" msgstr "" -#: ./cli/app/upgrade.go:289 +#: ./cli/app/upgrade.go:310 #, c-format msgid "please select an upgrade (version: %s):" msgstr "" -#: ./cli/app/upgrade.go:294 +#: ./cli/app/upgrade.go:315 #, c-format msgid "please select an upgrade (version: %s, chaos: %s):" msgstr "" @@ -3956,7 +3969,7 @@ msgstr "" msgid "print machine-readable output" msgstr "" -#: ./cli/internal/deploy.go:196 +#: ./cli/internal/deploy.go:217 msgid "proceed?" msgstr "" @@ -3965,7 +3978,7 @@ msgstr "" msgid "processing %s for %s" msgstr "" -#: ./cli/app/undeploy.go:159 +#: ./cli/app/undeploy.go:162 msgid "prune" msgstr "" @@ -3974,7 +3987,7 @@ msgstr "" msgid "prune [flags]" msgstr "" -#: ./cli/app/undeploy.go:162 +#: ./cli/app/undeploy.go:165 msgid "prune unused containers, networks, and dangling images" msgstr "" @@ -4007,7 +4020,7 @@ msgstr "" #. with no spaces in between #. translators: `abra recipe` aliases. use a comma separated list of aliases #. with no spaces in between -#: ./cli/app/backup.go:327 ./cli/app/list.go:303 ./cli/app/move.go:346 ./cli/app/run.go:23 ./cli/app/upgrade.go:463 ./cli/catalogue/catalogue.go:302 ./cli/recipe/recipe.go:12 ./cli/recipe/release.go:640 ./cli/recipe/sync.go:270 +#: ./cli/app/backup.go:327 ./cli/app/list.go:303 ./cli/app/move.go:346 ./cli/app/run.go:23 ./cli/app/upgrade.go:484 ./cli/catalogue/catalogue.go:302 ./cli/recipe/recipe.go:12 ./cli/recipe/release.go:640 ./cli/recipe/sync.go:270 msgid "r" msgstr "" @@ -4118,7 +4131,7 @@ msgstr "" msgid "release [version] [flags]" msgstr "" -#: ./cli/app/upgrade.go:462 +#: ./cli/app/upgrade.go:483 msgid "releasenotes" msgstr "" @@ -4362,7 +4375,7 @@ msgstr "" #. aliases with no spaces in between #. translators: `abra recipe release` aliases. use a comma separated list of #. aliases with no spaces in between -#: ./cli/app/rollback.go:27 ./cli/recipe/release.go:28 +#: ./cli/app/rollback.go:28 ./cli/recipe/release.go:28 msgid "rl" msgstr "" @@ -4379,7 +4392,7 @@ msgid "rm" msgstr "" #. translators: `app rollback` command -#: ./cli/app/rollback.go:31 +#: ./cli/app/rollback.go:32 msgid "rollback [version] [flags]" msgstr "" @@ -4422,7 +4435,7 @@ msgstr "" msgid "run command locally" msgstr "" -#: ./cli/app/deploy.go:236 ./cli/app/upgrade.go:270 +#: ./cli/app/deploy.go:260 ./cli/app/upgrade.go:291 #, c-format msgid "run the following post-deploy commands: %s" msgstr "" @@ -4432,7 +4445,7 @@ msgstr "" msgid "running backup %s on %s with exec config %v" msgstr "" -#: ./cli/internal/deploy.go:252 +#: ./cli/internal/deploy.go:273 #, c-format msgid "running command %s %s within the context of %s_%s" msgstr "" @@ -4452,7 +4465,7 @@ msgstr "" msgid "running command: %s" msgstr "" -#: ./cli/internal/deploy.go:230 +#: ./cli/internal/deploy.go:251 #, c-format msgid "running post-command '%s %s' in container %s" msgstr "" @@ -4502,7 +4515,7 @@ msgstr "" msgid "secret not found: %s" msgstr "" -#: ./cli/app/deploy.go:291 +#: ./cli/app/deploy.go:315 #, c-format msgid "secret not generated: %s" msgstr "" @@ -4686,11 +4699,11 @@ msgstr "" msgid "skipping converge logic checks" msgstr "" -#: ./cli/app/deploy.go:189 +#: ./cli/app/deploy.go:190 msgid "skipping domain checks" msgstr "" -#: ./cli/app/deploy.go:186 +#: ./cli/app/deploy.go:187 msgid "skipping domain checks, no DOMAIN=... configured" msgstr "" @@ -5212,7 +5225,7 @@ msgstr "" msgid "undeploy [flags]" msgstr "" -#: ./cli/app/undeploy.go:108 +#: ./cli/app/undeploy.go:111 msgid "undeploy succeeded 🟢" msgstr "" @@ -5245,7 +5258,7 @@ msgstr "" msgid "unknown" msgstr "" -#: ./cli/app/rollback.go:149 +#: ./cli/app/rollback.go:150 msgid "unknown deployed version, unable to downgrade" msgstr "" @@ -5411,7 +5424,7 @@ msgstr "" msgid "version %s saved to %s.env" msgstr "" -#: ./cli/app/deploy.go:116 +#: ./cli/app/deploy.go:117 #, c-format msgid "version '%s' appears to be a chaos commit, but --chaos/-C was not provided" msgstr "" @@ -5435,32 +5448,32 @@ msgstr "" msgid "version wiped from %s.env" msgstr "" -#: ./cli/app/deploy.go:318 +#: ./cli/app/deploy.go:342 #, c-format msgid "version: can not redeploy chaos version %s" msgstr "" -#: ./cli/app/deploy.go:305 +#: ./cli/app/deploy.go:329 #, c-format msgid "version: taking chaos version: %s" msgstr "" -#: ./cli/app/deploy.go:326 +#: ./cli/app/deploy.go:350 #, c-format msgid "version: taking deployed version: %s" msgstr "" -#: ./cli/app/deploy.go:331 +#: ./cli/app/deploy.go:355 #, c-format msgid "version: taking new recipe version: %s" msgstr "" -#: ./cli/app/deploy.go:320 +#: ./cli/app/deploy.go:344 #, c-format msgid "version: taking version from .env file: %s" msgstr "" -#: ./cli/app/deploy.go:311 +#: ./cli/app/deploy.go:335 #, c-format msgid "version: taking version from cli arg: %s" msgstr "" @@ -5583,7 +5596,7 @@ msgstr "" msgid "writer: %v, " msgstr "" -#: ./cli/app/deploy.go:243 ./cli/app/new.go:221 ./cli/app/rollback.go:232 ./cli/app/undeploy.go:111 ./cli/app/upgrade.go:278 +#: ./cli/app/deploy.go:267 ./cli/app/new.go:221 ./cli/app/rollback.go:254 ./cli/app/undeploy.go:114 ./cli/app/upgrade.go:299 #, c-format msgid "writing recipe version failed: %s" msgstr "" -- 2.49.0 From 90e9e9b5aad3ca310246b1147301c99bbc98e244 Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Wed, 3 Sep 2025 13:32:30 -0400 Subject: [PATCH 16/28] refactor: move MergeAbraShEnv to shared method Re #638 --- cli/app/deploy.go | 16 +++++----------- cli/app/rollback.go | 12 +++--------- cli/app/upgrade.go | 9 ++------- cli/updater/updater.go | 18 ++---------------- pkg/deploy/utils.go | 22 ++++++++++++++++++++-- 5 files changed, 32 insertions(+), 45 deletions(-) diff --git a/cli/app/deploy.go b/cli/app/deploy.go index 03b33dc4..b01faba3 100644 --- a/cli/app/deploy.go +++ b/cli/app/deploy.go @@ -6,10 +6,8 @@ import ( "strings" "coopcloud.tech/abra/cli/internal" - "coopcloud.tech/abra/pkg/app" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/config" - "coopcloud.tech/abra/pkg/envfile" "coopcloud.tech/abra/pkg/secret" appPkg "coopcloud.tech/abra/pkg/app" @@ -130,13 +128,9 @@ checkout as-is. Recipe commit hashes are also supported as values for log.Fatal(err) } - abraShEnv, err := envfile.ReadAbraShEnvVars(app.Recipe.AbraShPath) - if err != nil { + if err := deploy.MergeAbraShEnv(app.Recipe, app.Env); err != nil { log.Fatal(err) } - for k, v := range abraShEnv { - app.Env[k] = v - } composeFiles, err := app.Recipe.GetComposeFiles(app.Env) if err != nil { @@ -202,7 +196,7 @@ checkout as-is. Recipe commit hashes are also supported as values for } // Gather configs - configInfo, err := deploy.GatherConfigsForDeploy(cl, app, compose, abraShEnv) + configInfo, err := deploy.GatherConfigsForDeploy(cl, app, compose, app.Env) if err != nil { log.Fatal(err) } @@ -269,7 +263,7 @@ checkout as-is. Recipe commit hashes are also supported as values for }, } -func getLatestVersionOrCommit(app app.App) (string, error) { +func getLatestVersionOrCommit(app appPkg.App) (string, error) { versions, err := app.Recipe.Tags() if err != nil { return "", err @@ -304,7 +298,7 @@ func validateArgsAndFlags(args []string) error { return nil } -func validateSecrets(cl *dockerClient.Client, app app.App) error { +func validateSecrets(cl *dockerClient.Client, app appPkg.App) error { secStats, err := secret.PollSecretsStatus(cl, app) if err != nil { return err @@ -319,7 +313,7 @@ func validateSecrets(cl *dockerClient.Client, app app.App) error { return nil } -func getDeployVersion(cliArgs []string, deployMeta stack.DeployMeta, app app.App) (string, error) { +func getDeployVersion(cliArgs []string, deployMeta stack.DeployMeta, app appPkg.App) (string, error) { // Chaos mode overrides everything if internal.Chaos { v, err := app.Recipe.ChaosVersion() diff --git a/cli/app/rollback.go b/cli/app/rollback.go index 8ac92f22..1c4b46f8 100644 --- a/cli/app/rollback.go +++ b/cli/app/rollback.go @@ -4,12 +4,10 @@ import ( "errors" "strings" - "coopcloud.tech/abra/pkg/app" appPkg "coopcloud.tech/abra/pkg/app" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/deploy" - "coopcloud.tech/abra/pkg/envfile" "coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/lint" @@ -156,13 +154,9 @@ beforehand. See "abra app backup" for more.`), log.Fatal(err) } - abraShEnv, err := envfile.ReadAbraShEnvVars(app.Recipe.AbraShPath) - if err != nil { + if err := deploy.MergeAbraShEnv(app.Recipe, app.Env); err != nil { log.Fatal(err) } - for k, v := range abraShEnv { - app.Env[k] = v - } composeFiles, err := app.Recipe.GetComposeFiles(app.Env) if err != nil { @@ -198,7 +192,7 @@ beforehand. See "abra app backup" for more.`), } // Gather configs - configInfo, err := deploy.GatherConfigsForDeploy(cl, app, compose, abraShEnv) + configInfo, err := deploy.GatherConfigsForDeploy(cl, app, compose, app.Env) if err != nil { log.Fatal(err) } @@ -289,7 +283,7 @@ func chooseDowngrade( // validateDownpgradeVersionArg validates the specific version. func validateDowngradeVersionArg( specificVersion string, - app app.App, + app appPkg.App, deployMeta stack.DeployMeta, ) error { parsedDeployedVersion, err := tagcmp.Parse(deployMeta.Version) diff --git a/cli/app/upgrade.go b/cli/app/upgrade.go index 9cf5cfdd..d04504fb 100644 --- a/cli/app/upgrade.go +++ b/cli/app/upgrade.go @@ -12,7 +12,6 @@ import ( "coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/deploy" - "coopcloud.tech/abra/pkg/envfile" "coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/lint" @@ -168,13 +167,9 @@ beforehand. See "abra app backup" for more.`), log.Fatal(err) } - abraShEnv, err := envfile.ReadAbraShEnvVars(app.Recipe.AbraShPath) - if err != nil { + if err := deploy.MergeAbraShEnv(app.Recipe, app.Env); err != nil { log.Fatal(err) } - for k, v := range abraShEnv { - app.Env[k] = v - } composeFiles, err := app.Recipe.GetComposeFiles(app.Env) if err != nil { @@ -223,7 +218,7 @@ beforehand. See "abra app backup" for more.`), } // Gather configs - configInfo, err := deploy.GatherConfigsForDeploy(cl, app, compose, abraShEnv) + configInfo, err := deploy.GatherConfigsForDeploy(cl, app, compose, app.Env) if err != nil { log.Fatal(err) } diff --git a/cli/updater/updater.go b/cli/updater/updater.go index 18332754..6f28216e 100644 --- a/cli/updater/updater.go +++ b/cli/updater/updater.go @@ -11,6 +11,7 @@ import ( "coopcloud.tech/abra/cli/internal" appPkg "coopcloud.tech/abra/pkg/app" "coopcloud.tech/abra/pkg/client" + "coopcloud.tech/abra/pkg/deploy" "coopcloud.tech/abra/pkg/envfile" "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/lint" @@ -335,21 +336,6 @@ func processRecipeRepoVersion(r recipe.Recipe, version string) error { return nil } -// mergeAbraShEnv merges abra.sh env vars into the app env vars. -func mergeAbraShEnv(recipe recipe.Recipe, env envfile.AppEnv) error { - abraShEnv, err := envfile.ReadAbraShEnvVars(recipe.AbraShPath) - if err != nil { - return err - } - - for k, v := range abraShEnv { - log.Debugf("read v:%s k: %s", v, k) - env[k] = v - } - - return nil -} - // createDeployConfig merges and enriches the compose config for the deployment. func createDeployConfig(r recipe.Recipe, stackName string, env envfile.AppEnv) (*composetypes.Config, stack.Deploy, error) { env["STACK_NAME"] = stackName @@ -444,7 +430,7 @@ func upgrade(cl *dockerclient.Client, stackName, recipeName, upgradeVersion stri return err } - if err = mergeAbraShEnv(app.Recipe, app.Env); err != nil { + if err = deploy.MergeAbraShEnv(app.Recipe, app.Env); err != nil { return err } diff --git a/pkg/deploy/utils.go b/pkg/deploy/utils.go index bd7a803a..f5fd43c7 100644 --- a/pkg/deploy/utils.go +++ b/pkg/deploy/utils.go @@ -10,7 +10,9 @@ import ( appPkg "coopcloud.tech/abra/pkg/app" "coopcloud.tech/abra/pkg/client" + "coopcloud.tech/abra/pkg/envfile" "coopcloud.tech/abra/pkg/log" + "coopcloud.tech/abra/pkg/recipe" "coopcloud.tech/abra/pkg/secret" composetypes "github.com/docker/cli/cli/compose/types" @@ -18,6 +20,22 @@ import ( dockerClient "github.com/docker/docker/client" ) +// MergeAbraShEnv merges abra.sh env vars into the app env vars. +func MergeAbraShEnv(recipe recipe.Recipe, env envfile.AppEnv) error { + abraShEnv, err := envfile.ReadAbraShEnvVars(recipe.AbraShPath) + if err != nil { + return err + } + + for k, v := range abraShEnv { + log.Debugf("read v:%s k: %s", v, k) + env[k] = v + } + + return nil +} + + // GetConfigsForStack retrieves all Docker configs attached to services in a given stack. func GetConfigsForStack(cl *dockerClient.Client, app appPkg.App) (map[string]string, error) { filters, err := app.Filters(false, false) @@ -185,7 +203,7 @@ func GatherImagesForDeploy(cl *dockerClient.Client, app appPkg.App, compose *com return nil, err } - log.Infof("Deployed images: %v", currentImages) + log.Debugf("Deployed images: %v", currentImages) // Proposed new images from the compose files newImages := make(map[string]string) @@ -207,7 +225,7 @@ func GatherImagesForDeploy(cl *dockerClient.Client, app appPkg.App, compose *com } } } - log.Infof("Proposed images: %v", newImages) + log.Debugf("Proposed images: %v", newImages) var imageInfo []string for newImageName, newImageVersion := range newImages { -- 2.49.0 From 117f64a9d67b8be49c4e051c4b30bf5ddfb48ca4 Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Wed, 3 Sep 2025 13:33:06 -0400 Subject: [PATCH 17/28] test: add some basic unit tests for new utility methods --- pkg/client/configs_test.go | 89 ++++++++++++++++++++++++++++++++++++++ pkg/client/secret_test.go | 58 +++++++++++++++++++++++++ pkg/deploy/utils_test.go | 88 +++++++++++++++++++++++++++++++++++++ 3 files changed, 235 insertions(+) create mode 100644 pkg/client/configs_test.go create mode 100644 pkg/client/secret_test.go create mode 100644 pkg/deploy/utils_test.go diff --git a/pkg/client/configs_test.go b/pkg/client/configs_test.go new file mode 100644 index 00000000..a247586f --- /dev/null +++ b/pkg/client/configs_test.go @@ -0,0 +1,89 @@ +package client + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetConfigNameAndVersion(t *testing.T) { + tests := []struct { + name string + fullName string + stackName string + expected string + expectedVer string + expectError bool + }{ + { + name: "valid config with version", + fullName: "myapp_database_v2", + stackName: "myapp", + expected: "database", + expectedVer: "v2", + expectError: false, + }, + { + name: "valid config with numeric version", + fullName: "myapp_redis_1", + stackName: "myapp", + expected: "redis", + expectedVer: "1", + expectError: false, + }, + { + name: "config without underscore in name", + fullName: "myapp_db_v1", + stackName: "myapp", + expected: "db", + expectedVer: "v1", + expectError: false, + }, + { + name: "config with multiple underscores", + fullName: "myapp_my_database_v3", + stackName: "myapp", + expected: "my_database", + expectedVer: "v3", + expectError: false, + }, + { + name: "invalid config - no version", + fullName: "myapp_database", + stackName: "myapp", + expectError: true, + }, + { + name: "empty config name", + fullName: "myapp__v1", + stackName: "myapp", + expected: "", + expectedVer: "v1", + expectError: false, + }, + { + name: "wrong stack prefix", + fullName: "otherapp_database_v1", + stackName: "myapp", + expected: "otherapp_database", + expectedVer: "v1", + expectError: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + name, version, err := GetConfigNameAndVersion(tt.fullName, tt.stackName) + + if tt.expectError { + assert.Error(t, err) + assert.Empty(t, name) + assert.Empty(t, version) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.expected, name) + assert.Equal(t, tt.expectedVer, version) + } + }) + } +} \ No newline at end of file diff --git a/pkg/client/secret_test.go b/pkg/client/secret_test.go new file mode 100644 index 00000000..b466d151 --- /dev/null +++ b/pkg/client/secret_test.go @@ -0,0 +1,58 @@ +package client + +import ( + "testing" + + "github.com/docker/docker/api/types/swarm" + "github.com/stretchr/testify/assert" +) + +func TestGetSecretNames(t *testing.T) { + tests := []struct { + name string + secrets []swarm.Secret + expected []string + description string + }{ + { + name: "empty secrets list", + secrets: []swarm.Secret{}, + expected: nil, + description: "should return nil for empty input", + }, + { + name: "single secret", + secrets: []swarm.Secret{ + {Spec: swarm.SecretSpec{Annotations: swarm.Annotations{Name: "database_password"}}}, + }, + expected: []string{"database_password"}, + description: "should return single secret name", + }, + { + name: "multiple secrets", + secrets: []swarm.Secret{ + {Spec: swarm.SecretSpec{Annotations: swarm.Annotations{Name: "db_password"}}}, + {Spec: swarm.SecretSpec{Annotations: swarm.Annotations{Name: "api_key"}}}, + {Spec: swarm.SecretSpec{Annotations: swarm.Annotations{Name: "ssl_cert"}}}, + }, + expected: []string{"db_password", "api_key", "ssl_cert"}, + description: "should return all secret names in order", + }, + { + name: "secrets with empty names", + secrets: []swarm.Secret{ + {Spec: swarm.SecretSpec{Annotations: swarm.Annotations{Name: ""}}}, + {Spec: swarm.SecretSpec{Annotations: swarm.Annotations{Name: "valid_name"}}}, + }, + expected: []string{"", "valid_name"}, + description: "should include empty names if present", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := GetSecretNames(tt.secrets) + assert.Equal(t, tt.expected, result, tt.description) + }) + } +} \ No newline at end of file diff --git a/pkg/deploy/utils_test.go b/pkg/deploy/utils_test.go new file mode 100644 index 00000000..f9e80c55 --- /dev/null +++ b/pkg/deploy/utils_test.go @@ -0,0 +1,88 @@ +package deploy + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetImageNameAndTag(t *testing.T) { + tests := []struct { + name string + imageName string + expectedName string + expectedTag string + expectError bool + description string + }{ + { + name: "standard image with tag", + imageName: "nginx:1.23", + expectedName: "nginx", + expectedTag: "1.23", + expectError: false, + description: "should parse standard image name with tag", + }, + { + name: "image with digest", + imageName: "nginx:1.23@sha256:abc123", + expectedName: "nginx", + expectedTag: "1.23", + expectError: false, + description: "should parse image with digest, ignoring digest part", + }, + { + name: "image with latest tag", + imageName: "redis:latest", + expectedName: "redis", + expectedTag: "latest", + expectError: false, + description: "should parse image with latest tag", + }, + { + name: "image with numeric tag", + imageName: "postgres:14", + expectedName: "postgres", + expectedTag: "14", + expectError: false, + description: "should parse image with numeric tag", + }, + { + name: "image with complex name", + imageName: "registry.example.com/myapp/api:v1.2.3", + expectedName: "registry.example.com/myapp/api", + expectedTag: "v1.2.3", + expectError: false, + description: "should parse image with registry prefix and complex name", + }, + { + name: "image without tag", + imageName: "nginx", + expectError: true, + description: "should error when no tag present", + }, + { + name: "empty image name", + imageName: "", + expectError: true, + description: "should error on empty image name", + }, + + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + name, tag, err := GetImageNameAndTag(tt.imageName) + + if tt.expectError { + assert.Error(t, err) + assert.Empty(t, name) + assert.Empty(t, tag) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.expectedName, name) + assert.Equal(t, tt.expectedTag, tag) + } + }) + } +} \ No newline at end of file -- 2.49.0 From d9f1f82923d75b2cdff835df058dbc72d0c7976f Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Wed, 3 Sep 2025 13:33:23 -0400 Subject: [PATCH 18/28] style: 4matting --- pkg/client/configs_test.go | 4 ++-- pkg/client/secret_test.go | 2 +- pkg/deploy/utils.go | 1 - pkg/deploy/utils_test.go | 17 ++++++++--------- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/pkg/client/configs_test.go b/pkg/client/configs_test.go index a247586f..51e8a6b5 100644 --- a/pkg/client/configs_test.go +++ b/pkg/client/configs_test.go @@ -74,7 +74,7 @@ func TestGetConfigNameAndVersion(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { name, version, err := GetConfigNameAndVersion(tt.fullName, tt.stackName) - + if tt.expectError { assert.Error(t, err) assert.Empty(t, name) @@ -86,4 +86,4 @@ func TestGetConfigNameAndVersion(t *testing.T) { } }) } -} \ No newline at end of file +} diff --git a/pkg/client/secret_test.go b/pkg/client/secret_test.go index b466d151..4636a2d3 100644 --- a/pkg/client/secret_test.go +++ b/pkg/client/secret_test.go @@ -55,4 +55,4 @@ func TestGetSecretNames(t *testing.T) { assert.Equal(t, tt.expected, result, tt.description) }) } -} \ No newline at end of file +} diff --git a/pkg/deploy/utils.go b/pkg/deploy/utils.go index f5fd43c7..30ce4c77 100644 --- a/pkg/deploy/utils.go +++ b/pkg/deploy/utils.go @@ -35,7 +35,6 @@ func MergeAbraShEnv(recipe recipe.Recipe, env envfile.AppEnv) error { return nil } - // GetConfigsForStack retrieves all Docker configs attached to services in a given stack. func GetConfigsForStack(cl *dockerClient.Client, app appPkg.App) (map[string]string, error) { filters, err := app.Filters(false, false) diff --git a/pkg/deploy/utils_test.go b/pkg/deploy/utils_test.go index f9e80c55..a0735d14 100644 --- a/pkg/deploy/utils_test.go +++ b/pkg/deploy/utils_test.go @@ -8,12 +8,12 @@ import ( func TestGetImageNameAndTag(t *testing.T) { tests := []struct { - name string - imageName string - expectedName string - expectedTag string - expectError bool - description string + name string + imageName string + expectedName string + expectedTag string + expectError bool + description string }{ { name: "standard image with tag", @@ -67,13 +67,12 @@ func TestGetImageNameAndTag(t *testing.T) { expectError: true, description: "should error on empty image name", }, - } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { name, tag, err := GetImageNameAndTag(tt.imageName) - + if tt.expectError { assert.Error(t, err) assert.Empty(t, name) @@ -85,4 +84,4 @@ func TestGetImageNameAndTag(t *testing.T) { } }) } -} \ No newline at end of file +} -- 2.49.0 From 5c659bae5f36cf7aac82674625565f0dbfaf9ae3 Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Wed, 3 Sep 2025 13:34:15 -0400 Subject: [PATCH 19/28] chore: update POT --- pkg/i18n/locales/abra.pot | 222 +++++++++++++++++++------------------- 1 file changed, 111 insertions(+), 111 deletions(-) diff --git a/pkg/i18n/locales/abra.pot b/pkg/i18n/locales/abra.pot index 00e0fb90..14dff346 100644 --- a/pkg/i18n/locales/abra.pot +++ b/pkg/i18n/locales/abra.pot @@ -111,7 +111,7 @@ msgid " # run with args/flags\n" " abra app run 1312.net app --user nobody -- ls -lha" msgstr "" -#: ./cli/app/deploy.go:43 +#: ./cli/app/deploy.go:41 msgid " # standard deployment\n" " abra app deploy 1312.net\n" "\n" @@ -149,7 +149,7 @@ msgstr "" msgid " abra upgrade --rc" msgstr "" -#: ./cli/app/rollback.go:50 +#: ./cli/app/rollback.go:48 msgid " # standard rollback\n" " abra app rollback 1312.net\n" "\n" @@ -181,7 +181,7 @@ msgstr "" msgid "%d volumes removed successfully" msgstr "" -#: ./cli/updater/updater.go:243 +#: ./cli/updater/updater.go:244 #, c-format msgid "%s (%s) can be upgraded from version %s to %s" msgstr "" @@ -311,7 +311,7 @@ msgstr "" msgid "%s inserted into pass store" msgstr "" -#: ./cli/app/deploy.go:103 +#: ./cli/app/deploy.go:101 #, c-format msgid "%s is already deployed" msgstr "" @@ -336,17 +336,17 @@ msgstr "" msgid "%s is missing the TYPE env var?" msgstr "" -#: ./cli/app/rollback.go:307 ./cli/app/rollback.go:311 +#: ./cli/app/rollback.go:301 ./cli/app/rollback.go:305 #, c-format msgid "%s is not a downgrade for %s?" msgstr "" -#: ./cli/app/upgrade.go:427 ./cli/app/upgrade.go:431 +#: ./cli/app/upgrade.go:422 ./cli/app/upgrade.go:426 #, c-format msgid "%s is not an upgrade for %s?" msgstr "" -#: ./cli/app/logs.go:65 ./cli/app/ps.go:62 ./cli/app/restart.go:100 ./cli/app/services.go:55 ./cli/app/undeploy.go:65 ./cli/app/upgrade.go:448 ./cli/updater/updater.go:259 +#: ./cli/app/logs.go:65 ./cli/app/ps.go:62 ./cli/app/restart.go:100 ./cli/app/services.go:55 ./cli/app/undeploy.go:65 ./cli/app/upgrade.go:443 ./cli/updater/updater.go:260 #, c-format msgid "%s is not deployed?" msgstr "" @@ -361,7 +361,7 @@ msgstr "" msgid "%s is still deployed. Run \"abra app undeploy %s\"" msgstr "" -#: ./cli/app/deploy.go:176 ./cli/app/upgrade.go:214 +#: ./cli/app/deploy.go:170 ./cli/app/upgrade.go:209 #, c-format msgid "%s missing from %s.env" msgstr "" @@ -506,12 +506,12 @@ msgstr "" msgid "%s: waiting %d seconds before next retry" msgstr "" -#: ./cli/app/upgrade.go:422 +#: ./cli/app/upgrade.go:417 #, c-format msgid "'%s' is not a known version" msgstr "" -#: ./cli/app/rollback.go:302 ./cli/app/upgrade.go:417 +#: ./cli/app/rollback.go:296 ./cli/app/upgrade.go:412 #, c-format msgid "'%s' is not a known version for %s" msgstr "" @@ -582,7 +582,7 @@ msgstr "" msgid "Both local recipe and live deployment labels are shown." msgstr "" -#: ./cli/app/backup.go:319 ./cli/app/backup.go:335 ./cli/app/check.go:95 ./cli/app/cmd.go:285 ./cli/app/cp.go:385 ./cli/app/deploy.go:366 ./cli/app/labels.go:143 ./cli/app/new.go:377 ./cli/app/ps.go:213 ./cli/app/restart.go:162 ./cli/app/restore.go:138 ./cli/app/secret.go:569 ./cli/app/secret.go:609 ./cli/app/secret.go:633 ./cli/app/secret.go:641 ./cli/catalogue/catalogue.go:318 ./cli/recipe/lint.go:137 ./cli/updater/updater.go:552 +#: ./cli/app/backup.go:319 ./cli/app/backup.go:335 ./cli/app/check.go:95 ./cli/app/cmd.go:285 ./cli/app/cp.go:385 ./cli/app/deploy.go:360 ./cli/app/labels.go:143 ./cli/app/new.go:377 ./cli/app/ps.go:213 ./cli/app/restart.go:162 ./cli/app/restore.go:138 ./cli/app/secret.go:569 ./cli/app/secret.go:609 ./cli/app/secret.go:633 ./cli/app/secret.go:641 ./cli/catalogue/catalogue.go:318 ./cli/recipe/lint.go:137 ./cli/updater/updater.go:538 msgid "C" msgstr "" @@ -631,7 +631,7 @@ msgid "Check app deployment status" msgstr "" #. translators: Short description for `notify` command -#: ./cli/updater/updater.go:43 +#: ./cli/updater/updater.go:44 msgid "Check for available upgrades" msgstr "" @@ -728,7 +728,7 @@ msgid "Creates a new app from a default recipe.\n" "on your $PATH." msgstr "" -#: ./cli/app/deploy.go:382 ./cli/app/new.go:353 ./cli/app/rollback.go:359 ./cli/app/upgrade.go:468 +#: ./cli/app/deploy.go:376 ./cli/app/new.go:353 ./cli/app/rollback.go:353 ./cli/app/upgrade.go:463 msgid "D" msgstr "" @@ -749,11 +749,11 @@ msgid "DOWNGRADE" msgstr "" #. translators: Short description for `app deploy` command -#: ./cli/app/deploy.go:37 +#: ./cli/app/deploy.go:35 msgid "Deploy an app" msgstr "" -#: ./cli/app/deploy.go:38 +#: ./cli/app/deploy.go:36 msgid "Deploy an app.\n" "\n" "This command supports chaos operations. Use \"--chaos/-C\" to deploy your recipe\n" @@ -1059,7 +1059,7 @@ msgstr "" msgid "NOW" msgstr "" -#: ./cli/updater/updater.go:44 +#: ./cli/updater/updater.go:45 msgid "Notify on new versions for deployed apps.\n" "\n" "If a new patch/minor version is available, a notification is printed.\n" @@ -1184,7 +1184,7 @@ msgid "Restore a snapshot" msgstr "" #. translators: Short description for `app rollback` command -#: ./cli/app/rollback.go:35 +#: ./cli/app/rollback.go:33 msgid "Roll an app back to a previous version" msgstr "" @@ -1317,7 +1317,7 @@ msgid "Tail app logs" msgstr "" #. translators: Short description for `kababra` binary -#: ./cli/updater/updater.go:487 +#: ./cli/updater/updater.go:473 msgid "The Co-op Cloud auto-updater 🤖 🚀" msgstr "" @@ -1367,7 +1367,7 @@ msgid "This command restarts services within a deployed app.\n" "Pass \"--all-services/-a\" to restart all services." msgstr "" -#: ./cli/app/rollback.go:36 +#: ./cli/app/rollback.go:34 msgid "This command rolls an app back to a previous version.\n" "\n" "Unlike \"abra app deploy\", chaos operations are not supported here. Only recipe\n" @@ -1475,11 +1475,11 @@ msgid "Upgrade abra in-place with the latest stable or release candidate.\n" msgstr "" #. translators: Short description for `app upgrade` command -#: ./cli/app/upgrade.go:37 +#: ./cli/app/upgrade.go:36 msgid "Upgrade an app" msgstr "" -#: ./cli/updater/updater.go:89 +#: ./cli/updater/updater.go:90 msgid "Upgrade an app by specifying stack name and recipe. \n" "\n" "Use \"--all\" to upgrade every deployed app.\n" @@ -1494,7 +1494,7 @@ msgid "Upgrade an app by specifying stack name and recipe. \n" "with care." msgstr "" -#: ./cli/app/upgrade.go:38 +#: ./cli/app/upgrade.go:37 msgid "Upgrade an app.\n" "\n" "Unlike \"abra app deploy\", chaos operations are not supported here. Only recipe\n" @@ -1512,7 +1512,7 @@ msgid "Upgrade an app.\n" msgstr "" #. translators: Short description for `app upgrade` command -#: ./cli/updater/updater.go:88 +#: ./cli/updater/updater.go:89 msgid "Upgrade apps" msgstr "" @@ -1646,7 +1646,7 @@ msgstr "" #. no spaces in between #. translators: `abra server add` aliases. use a comma separated list of #. aliases with no spaces in between -#: ./cli/app/app.go:12 ./cli/app/backup.go:271 ./cli/app/restart.go:169 ./cli/app/secret.go:577 ./cli/app/secret.go:617 ./cli/recipe/fetch.go:122 ./cli/recipe/upgrade.go:384 ./cli/server/add.go:23 ./cli/server/prune.go:99 ./cli/updater/updater.go:568 +#: ./cli/app/app.go:12 ./cli/app/backup.go:271 ./cli/app/restart.go:169 ./cli/app/secret.go:577 ./cli/app/secret.go:617 ./cli/recipe/fetch.go:122 ./cli/recipe/upgrade.go:384 ./cli/server/add.go:23 ./cli/server/prune.go:99 ./cli/updater/updater.go:554 msgid "a" msgstr "" @@ -1702,7 +1702,7 @@ msgstr "" msgid "adding env vars to %s service config" msgstr "" -#: ./cli/app/backup.go:270 ./cli/app/secret.go:576 ./cli/app/secret.go:616 ./cli/recipe/fetch.go:121 ./cli/server/prune.go:98 ./cli/updater/updater.go:567 +#: ./cli/app/backup.go:270 ./cli/app/secret.go:576 ./cli/app/secret.go:616 ./cli/recipe/fetch.go:121 ./cli/server/prune.go:98 ./cli/updater/updater.go:553 msgid "all" msgstr "" @@ -1781,7 +1781,7 @@ msgstr "" msgid "attempting to run %s" msgstr "" -#: ./cli/app/deploy.go:262 ./cli/app/upgrade.go:294 +#: ./cli/app/deploy.go:256 ./cli/app/upgrade.go:289 #, c-format msgid "attempting to run post deploy commands, saw: %s" msgstr "" @@ -1806,7 +1806,7 @@ msgstr "" msgid "autocomplete [bash|zsh|fish|powershell]" msgstr "" -#: ./cli/app/deploy.go:66 ./cli/app/logs.go:39 ./cli/app/rollback.go:66 ./cli/app/secret.go:49 ./cli/app/secret.go:191 ./cli/app/secret.go:360 ./cli/app/upgrade.go:64 ./pkg/autocomplete/autocomplete.go:18 ./pkg/autocomplete/autocomplete.go:33 ./pkg/autocomplete/autocomplete.go:44 ./pkg/autocomplete/autocomplete.go:50 ./pkg/autocomplete/autocomplete.go:70 ./pkg/autocomplete/autocomplete.go:88 ./pkg/autocomplete/autocomplete.go:104 ./pkg/autocomplete/autocomplete.go:110 ./pkg/autocomplete/autocomplete.go:125 +#: ./cli/app/deploy.go:64 ./cli/app/logs.go:39 ./cli/app/rollback.go:64 ./cli/app/secret.go:49 ./cli/app/secret.go:191 ./cli/app/secret.go:360 ./cli/app/upgrade.go:63 ./pkg/autocomplete/autocomplete.go:18 ./pkg/autocomplete/autocomplete.go:33 ./pkg/autocomplete/autocomplete.go:44 ./pkg/autocomplete/autocomplete.go:50 ./pkg/autocomplete/autocomplete.go:70 ./pkg/autocomplete/autocomplete.go:88 ./pkg/autocomplete/autocomplete.go:104 ./pkg/autocomplete/autocomplete.go:110 ./pkg/autocomplete/autocomplete.go:125 #, c-format msgid "autocomplete failed: %s" msgstr "" @@ -1819,7 +1819,7 @@ msgstr "" msgid "automatically set ssh remote" msgstr "" -#: ./cli/updater/updater.go:311 +#: ./cli/updater/updater.go:312 #, c-format msgid "available updates for %s: %s" msgstr "" @@ -1857,7 +1857,7 @@ msgstr "" msgid "bind options are incompatible with type volume" msgstr "" -#: ./cli/updater/updater.go:188 +#: ./cli/updater/updater.go:189 #, c-format msgid "boolean label %s could not be found for %s, set default to false." msgstr "" @@ -1871,7 +1871,7 @@ msgstr "" #. no spaces in between #. translators: `abra app cp` aliases. use a comma separated list of aliases with #. no spaces in between -#: ./cli/app/backup.go:148 ./cli/app/cp.go:30 ./cli/app/deploy.go:390 ./cli/app/rollback.go:367 ./cli/app/upgrade.go:476 +#: ./cli/app/backup.go:148 ./cli/app/cp.go:30 ./cli/app/deploy.go:384 ./cli/app/rollback.go:361 ./cli/app/upgrade.go:471 msgid "c" msgstr "" @@ -1903,7 +1903,7 @@ msgstr "" msgid "can't read local recipes: %s" msgstr "" -#: ./cli/updater/updater.go:209 +#: ./cli/updater/updater.go:210 #, c-format msgid "can't separate key from value: %s (this variable is probably unset)" msgstr "" @@ -1945,7 +1945,7 @@ msgstr "" msgid "cannot use '[secret] [version]' and '--all' together" msgstr "" -#: ./cli/app/deploy.go:301 +#: ./cli/app/deploy.go:295 msgid "cannot use --chaos and --latest together" msgstr "" @@ -1969,11 +1969,11 @@ msgstr "" msgid "cannot use [service] and --all-services/-a together" msgstr "" -#: ./cli/app/deploy.go:293 ./cli/app/new.go:76 +#: ./cli/app/deploy.go:287 ./cli/app/new.go:76 msgid "cannot use [version] and --chaos together" msgstr "" -#: ./cli/app/deploy.go:297 +#: ./cli/app/deploy.go:291 msgid "cannot use [version] and --latest together" msgstr "" @@ -2005,7 +2005,7 @@ msgstr "" msgid "cfg" msgstr "" -#: ./cli/app/backup.go:318 ./cli/app/backup.go:334 ./cli/app/check.go:94 ./cli/app/cmd.go:284 ./cli/app/cp.go:384 ./cli/app/deploy.go:365 ./cli/app/labels.go:142 ./cli/app/new.go:376 ./cli/app/ps.go:212 ./cli/app/restart.go:161 ./cli/app/restore.go:137 ./cli/app/secret.go:568 ./cli/app/secret.go:608 ./cli/app/secret.go:632 ./cli/app/secret.go:640 ./cli/catalogue/catalogue.go:317 ./cli/recipe/lint.go:136 ./cli/updater/updater.go:551 +#: ./cli/app/backup.go:318 ./cli/app/backup.go:334 ./cli/app/check.go:94 ./cli/app/cmd.go:284 ./cli/app/cp.go:384 ./cli/app/deploy.go:359 ./cli/app/labels.go:142 ./cli/app/new.go:376 ./cli/app/ps.go:212 ./cli/app/restart.go:161 ./cli/app/restore.go:137 ./cli/app/secret.go:568 ./cli/app/secret.go:608 ./cli/app/secret.go:632 ./cli/app/secret.go:640 ./cli/catalogue/catalogue.go:317 ./cli/recipe/lint.go:136 ./cli/updater/updater.go:537 msgid "chaos" msgstr "" @@ -2014,11 +2014,11 @@ msgstr "" msgid "check [flags]" msgstr "" -#: ./cli/updater/updater.go:562 +#: ./cli/updater/updater.go:548 msgid "check for major updates" msgstr "" -#: ./cli/app/deploy.go:95 ./cli/app/undeploy.go:57 ./cli/app/upgrade.go:440 +#: ./cli/app/deploy.go:93 ./cli/app/undeploy.go:57 ./cli/app/upgrade.go:435 #, c-format msgid "checking whether %s is already deployed" msgstr "" @@ -2039,12 +2039,12 @@ msgstr "" msgid "choosing %s as new version for %s" msgstr "" -#: ./cli/app/rollback.go:153 +#: ./cli/app/rollback.go:151 #, c-format msgid "choosing %s as version to rollback" msgstr "" -#: ./cli/app/upgrade.go:158 +#: ./cli/app/upgrade.go:157 #, c-format msgid "choosing %s as version to upgrade" msgstr "" @@ -2300,7 +2300,7 @@ msgstr "" msgid "critical errors present in %s config" msgstr "" -#: ./cli/app/rollback.go:297 +#: ./cli/app/rollback.go:291 #, c-format msgid "current deployment '%s' is not a known version for %s" msgstr "" @@ -2316,11 +2316,11 @@ msgstr "" #. no spaces in between #. translators: `abra recipe diff` aliases. use a comma separated list of aliases #. with no spaces in between -#: ./cli/app/backup.go:73 ./cli/app/deploy.go:30 ./cli/recipe/diff.go:16 ./cli/updater/updater.go:505 +#: ./cli/app/backup.go:73 ./cli/app/deploy.go:28 ./cli/recipe/diff.go:16 ./cli/updater/updater.go:491 msgid "d" msgstr "" -#: ./cli/updater/updater.go:504 +#: ./cli/updater/updater.go:490 msgid "debug" msgstr "" @@ -2335,7 +2335,7 @@ msgid "deleted %s successfully from server" msgstr "" #. translators: `app deploy` command -#: ./cli/app/deploy.go:34 +#: ./cli/app/deploy.go:32 msgid "deploy [version] [flags]" msgstr "" @@ -2351,7 +2351,7 @@ msgstr "" msgid "deploy labels stanza present" msgstr "" -#: ./cli/app/deploy.go:400 +#: ./cli/app/deploy.go:394 msgid "deploy latest recipe version" msgstr "" @@ -2428,11 +2428,11 @@ msgstr "" msgid "dirty: %v, " msgstr "" -#: ./cli/app/deploy.go:392 ./cli/app/rollback.go:369 ./cli/app/upgrade.go:478 +#: ./cli/app/deploy.go:386 ./cli/app/rollback.go:363 ./cli/app/upgrade.go:473 msgid "disable converge logic checks" msgstr "" -#: ./cli/app/deploy.go:384 ./cli/app/rollback.go:361 ./cli/app/upgrade.go:470 +#: ./cli/app/deploy.go:378 ./cli/app/rollback.go:355 ./cli/app/upgrade.go:465 msgid "disable public DNS checks" msgstr "" @@ -2465,22 +2465,22 @@ msgstr "" msgid "don't forget to run 'sudo mandb'" msgstr "" -#: ./cli/updater/updater.go:398 +#: ./cli/updater/updater.go:384 #, c-format msgid "don't update %s due to chaos deployment" msgstr "" -#: ./cli/updater/updater.go:408 +#: ./cli/updater/updater.go:394 #, c-format msgid "don't update %s due to disabled auto updates or missing ENABLE_AUTO_UPDATE env" msgstr "" -#: ./cli/updater/updater.go:388 +#: ./cli/updater/updater.go:374 #, c-format msgid "don't update %s due to missing recipe name" msgstr "" -#: ./cli/updater/updater.go:418 +#: ./cli/updater/updater.go:404 #, c-format msgid "don't update %s due to no new version" msgstr "" @@ -2577,7 +2577,7 @@ msgstr "" msgid "ensure \"image: ...\" set on all services" msgstr "" -#: ./cli/app/deploy.go:114 +#: ./cli/app/deploy.go:112 #, c-format msgid "ensure recipe: %s" msgstr "" @@ -2670,7 +2670,7 @@ msgstr "" #. translators: `abra recipe fetch` aliases. use a comma separated list of aliases #. with no spaces in between -#: ./cli/app/deploy.go:374 ./cli/app/remove.go:163 ./cli/app/rollback.go:351 ./cli/app/secret.go:593 ./cli/app/upgrade.go:460 ./cli/app/volume.go:217 ./cli/recipe/fetch.go:20 ./cli/recipe/fetch.go:138 +#: ./cli/app/deploy.go:368 ./cli/app/remove.go:163 ./cli/app/rollback.go:345 ./cli/app/secret.go:593 ./cli/app/upgrade.go:455 ./cli/app/volume.go:217 ./cli/recipe/fetch.go:20 ./cli/recipe/fetch.go:138 msgid "f" msgstr "" @@ -2729,7 +2729,7 @@ msgstr "" msgid "failed to create volume %s on %s: %s" msgstr "" -#: ./cli/updater/updater.go:263 +#: ./cli/updater/updater.go:264 #, c-format msgid "failed to determine deployed version of %s" msgstr "" @@ -2901,12 +2901,12 @@ msgstr "" msgid "filter by recipe" msgstr "" -#: ./cli/updater/updater.go:214 +#: ./cli/updater/updater.go:215 #, c-format msgid "for %s read env %s with value: %s from docker service" msgstr "" -#: ./cli/app/deploy.go:373 ./cli/app/remove.go:162 ./cli/app/rollback.go:350 ./cli/app/upgrade.go:459 ./cli/app/volume.go:216 ./cli/recipe/fetch.go:137 +#: ./cli/app/deploy.go:367 ./cli/app/remove.go:162 ./cli/app/rollback.go:344 ./cli/app/upgrade.go:454 ./cli/app/volume.go:216 ./cli/recipe/fetch.go:137 msgid "force" msgstr "" @@ -2965,7 +2965,7 @@ msgstr "" msgid "generated secrets %s shown again, please take note of them %s" msgstr "" -#: ./cli/app/deploy.go:108 +#: ./cli/app/deploy.go:106 #, c-format msgid "get deploy version: %s" msgstr "" @@ -3125,7 +3125,7 @@ msgstr "" msgid "id: %s, " msgstr "" -#: ./cli/app/backup.go:321 ./cli/app/backup.go:337 ./cli/app/check.go:97 ./cli/app/cmd.go:287 ./cli/app/cp.go:387 ./cli/app/deploy.go:368 ./cli/app/labels.go:145 ./cli/app/new.go:379 ./cli/app/ps.go:215 ./cli/app/restart.go:164 ./cli/app/restore.go:140 ./cli/app/secret.go:571 ./cli/app/secret.go:611 ./cli/app/secret.go:635 ./cli/app/secret.go:643 ./cli/catalogue/catalogue.go:320 ./cli/recipe/lint.go:139 ./cli/updater/updater.go:554 +#: ./cli/app/backup.go:321 ./cli/app/backup.go:337 ./cli/app/check.go:97 ./cli/app/cmd.go:287 ./cli/app/cp.go:387 ./cli/app/deploy.go:362 ./cli/app/labels.go:145 ./cli/app/new.go:379 ./cli/app/ps.go:215 ./cli/app/restart.go:164 ./cli/app/restore.go:140 ./cli/app/secret.go:571 ./cli/app/secret.go:611 ./cli/app/secret.go:635 ./cli/app/secret.go:643 ./cli/catalogue/catalogue.go:320 ./cli/recipe/lint.go:139 ./cli/updater/updater.go:540 msgid "ignore uncommitted recipes changes" msgstr "" @@ -3305,11 +3305,11 @@ msgid "invalid version %s specified" msgstr "" #. translators: `kadabra` binary name -#: ./cli/updater/updater.go:484 +#: ./cli/updater/updater.go:470 msgid "kadabra [cmd] [flags]" msgstr "" -#: ./cli/updater/updater.go:498 +#: ./cli/updater/updater.go:484 #, c-format msgid "kadabra version %s, commit %s" msgstr "" @@ -3318,7 +3318,7 @@ msgstr "" #. no spaces in between #. translators: `abra recipe lint` aliases. use a comma separated list of #. aliases with no spaces in between -#: ./cli/app/cmd.go:261 ./cli/app/deploy.go:398 ./cli/app/logs.go:20 ./cli/recipe/lint.go:17 ./cli/server/add.go:207 +#: ./cli/app/cmd.go:261 ./cli/app/deploy.go:392 ./cli/app/logs.go:20 ./cli/recipe/lint.go:17 ./cli/server/add.go:207 msgid "l" msgstr "" @@ -3327,7 +3327,7 @@ msgstr "" msgid "labels [flags]" msgstr "" -#: ./cli/app/deploy.go:397 ./cli/app/list.go:183 +#: ./cli/app/deploy.go:391 ./cli/app/list.go:183 msgid "latest" msgstr "" @@ -3450,7 +3450,7 @@ msgstr "" #. with no spaces in between #. translators: `abra man` aliases. use a comma separated list of aliases #. with no spaces in between -#: ./cli/app/list.go:318 ./cli/app/move.go:34 ./cli/app/ps.go:205 ./cli/app/secret.go:553 ./cli/app/secret.go:649 ./cli/recipe/list.go:104 ./cli/recipe/upgrade.go:376 ./cli/recipe/version.go:139 ./cli/run.go:152 ./cli/server/list.go:106 ./cli/updater/updater.go:560 +#: ./cli/app/list.go:318 ./cli/app/move.go:34 ./cli/app/ps.go:205 ./cli/app/secret.go:553 ./cli/app/secret.go:649 ./cli/recipe/list.go:104 ./cli/recipe/upgrade.go:376 ./cli/recipe/version.go:139 ./cli/run.go:152 ./cli/server/list.go:106 ./cli/updater/updater.go:546 msgid "m" msgstr "" @@ -3463,7 +3463,7 @@ msgstr "" msgid "main app service version for %s is empty?" msgstr "" -#: ./cli/internal/recipe.go:48 ./cli/internal/recipe.go:66 ./cli/internal/recipe.go:80 ./cli/recipe/release.go:647 ./cli/recipe/sync.go:277 ./cli/recipe/upgrade.go:351 ./cli/updater/updater.go:559 +#: ./cli/internal/recipe.go:48 ./cli/internal/recipe.go:66 ./cli/internal/recipe.go:80 ./cli/recipe/release.go:647 ./cli/recipe/sync.go:277 ./cli/recipe/upgrade.go:351 ./cli/updater/updater.go:545 msgid "major" msgstr "" @@ -3507,7 +3507,7 @@ msgstr "" msgid "missing arguments [secret]/[version] or '--all'" msgstr "" -#: ./cli/updater/updater.go:115 +#: ./cli/updater/updater.go:116 msgid "missing arguments or --all/-a flag" msgstr "" @@ -3536,7 +3536,7 @@ msgstr "" #. aliases with no spaces in between #. translators: `kadabra notify` aliases. use a comma separated list of aliases #. with no spaces in between -#: ./cli/app/new.go:48 ./cli/recipe/new.go:36 ./cli/updater/updater.go:35 ./cli/updater/updater.go:513 +#: ./cli/app/new.go:48 ./cli/recipe/new.go:36 ./cli/updater/updater.go:36 ./cli/updater/updater.go:499 msgid "n" msgstr "" @@ -3607,7 +3607,7 @@ msgstr "" msgid "no %s exists, skipping reading gitignore paths" msgstr "" -#: ./cli/updater/updater.go:167 ./pkg/app/compose.go:87 +#: ./cli/updater/updater.go:168 ./pkg/app/compose.go:87 #, c-format msgid "no %s label found for %s" msgstr "" @@ -3630,15 +3630,15 @@ msgstr "" msgid "no app provided" msgstr "" -#: ./cli/app/rollback.go:128 +#: ./cli/app/rollback.go:126 msgid "no available downgrades" msgstr "" -#: ./cli/app/upgrade.go:133 +#: ./cli/app/upgrade.go:132 msgid "no available upgrades" msgstr "" -#: ./cli/updater/updater.go:236 +#: ./cli/updater/updater.go:237 #, c-format msgid "no available upgrades for %s" msgstr "" @@ -3687,7 +3687,7 @@ msgstr "" msgid "no new versions available for %s, assuming %s is the latest (use -a/--all-tags to see all anyway)" msgstr "" -#: ./cli/updater/updater.go:285 +#: ./cli/updater/updater.go:286 #, c-format msgid "no published releases for %s in the recipe catalogue?" msgstr "" @@ -3780,15 +3780,15 @@ msgstr "" msgid "no volumes to remove" msgstr "" -#: ./cli/app/deploy.go:389 ./cli/app/rollback.go:366 ./cli/app/upgrade.go:475 +#: ./cli/app/deploy.go:383 ./cli/app/rollback.go:360 ./cli/app/upgrade.go:470 msgid "no-converge-checks" msgstr "" -#: ./cli/app/deploy.go:381 ./cli/app/rollback.go:358 ./cli/app/upgrade.go:467 +#: ./cli/app/deploy.go:375 ./cli/app/rollback.go:352 ./cli/app/upgrade.go:462 msgid "no-domain-checks" msgstr "" -#: ./cli/updater/updater.go:512 +#: ./cli/updater/updater.go:498 msgid "no-input" msgstr "" @@ -3825,7 +3825,7 @@ msgid "nothing found in stack: %s" msgstr "" #. translators: `notify` command -#: ./cli/updater/updater.go:40 +#: ./cli/updater/updater.go:41 msgid "notify [flags]" msgstr "" @@ -3849,7 +3849,7 @@ msgstr "" msgid "only show errors" msgstr "" -#: ./cli/app/upgrade.go:486 +#: ./cli/app/upgrade.go:481 msgid "only show release notes" msgstr "" @@ -3880,22 +3880,22 @@ msgstr "" msgid "parsed following command arguments: %s" msgstr "" -#: ./cli/app/upgrade.go:343 +#: ./cli/app/upgrade.go:338 #, c-format msgid "parsing chosen upgrade version failed: %s" msgstr "" -#: ./cli/app/upgrade.go:387 +#: ./cli/app/upgrade.go:382 #, c-format msgid "parsing deployed version failed: %s" msgstr "" -#: ./cli/app/upgrade.go:348 +#: ./cli/app/upgrade.go:343 #, c-format msgid "parsing deployment version failed: %s" msgstr "" -#: ./cli/app/upgrade.go:354 ./cli/app/upgrade.go:393 +#: ./cli/app/upgrade.go:349 ./cli/app/upgrade.go:388 #, c-format msgid "parsing recipe version failed: %s" msgstr "" @@ -3920,7 +3920,7 @@ msgstr "" msgid "pattern" msgstr "" -#: ./cli/app/deploy.go:376 ./cli/app/remove.go:165 ./cli/app/rollback.go:353 ./cli/app/upgrade.go:462 ./cli/app/volume.go:219 +#: ./cli/app/deploy.go:370 ./cli/app/remove.go:165 ./cli/app/rollback.go:347 ./cli/app/upgrade.go:457 ./cli/app/volume.go:219 msgid "perform action without further prompt" msgstr "" @@ -3929,22 +3929,22 @@ msgstr "" msgid "please fix your synced label for %s and re-run this command" msgstr "" -#: ./cli/app/rollback.go:265 +#: ./cli/app/rollback.go:259 #, c-format msgid "please select a downgrade (version: %s):" msgstr "" -#: ./cli/app/rollback.go:270 +#: ./cli/app/rollback.go:264 #, c-format msgid "please select a downgrade (version: %s, chaos: %s):" msgstr "" -#: ./cli/app/upgrade.go:310 +#: ./cli/app/upgrade.go:305 #, c-format msgid "please select an upgrade (version: %s):" msgstr "" -#: ./cli/app/upgrade.go:315 +#: ./cli/app/upgrade.go:310 #, c-format msgid "please select an upgrade (version: %s, chaos: %s):" msgstr "" @@ -4020,7 +4020,7 @@ msgstr "" #. with no spaces in between #. translators: `abra recipe` aliases. use a comma separated list of aliases #. with no spaces in between -#: ./cli/app/backup.go:327 ./cli/app/list.go:303 ./cli/app/move.go:346 ./cli/app/run.go:23 ./cli/app/upgrade.go:484 ./cli/catalogue/catalogue.go:302 ./cli/recipe/recipe.go:12 ./cli/recipe/release.go:640 ./cli/recipe/sync.go:270 +#: ./cli/app/backup.go:327 ./cli/app/list.go:303 ./cli/app/move.go:346 ./cli/app/run.go:23 ./cli/app/upgrade.go:479 ./cli/catalogue/catalogue.go:302 ./cli/recipe/recipe.go:12 ./cli/recipe/release.go:640 ./cli/recipe/sync.go:270 msgid "r" msgstr "" @@ -4131,7 +4131,7 @@ msgstr "" msgid "release [version] [flags]" msgstr "" -#: ./cli/app/upgrade.go:483 +#: ./cli/app/upgrade.go:478 msgid "releasenotes" msgstr "" @@ -4318,7 +4318,7 @@ msgstr "" msgid "retries" msgstr "" -#: ./cli/updater/updater.go:251 +#: ./cli/updater/updater.go:252 #, c-format msgid "retrieve deployed version whether %s is already deployed" msgstr "" @@ -4375,7 +4375,7 @@ msgstr "" #. aliases with no spaces in between #. translators: `abra recipe release` aliases. use a comma separated list of #. aliases with no spaces in between -#: ./cli/app/rollback.go:28 ./cli/recipe/release.go:28 +#: ./cli/app/rollback.go:26 ./cli/recipe/release.go:28 msgid "rl" msgstr "" @@ -4392,7 +4392,7 @@ msgid "rm" msgstr "" #. translators: `app rollback` command -#: ./cli/app/rollback.go:32 +#: ./cli/app/rollback.go:30 msgid "rollback [version] [flags]" msgstr "" @@ -4435,7 +4435,7 @@ msgstr "" msgid "run command locally" msgstr "" -#: ./cli/app/deploy.go:260 ./cli/app/upgrade.go:291 +#: ./cli/app/deploy.go:254 ./cli/app/upgrade.go:286 #, c-format msgid "run the following post-deploy commands: %s" msgstr "" @@ -4515,7 +4515,7 @@ msgstr "" msgid "secret not found: %s" msgstr "" -#: ./cli/app/deploy.go:315 +#: ./cli/app/deploy.go:309 #, c-format msgid "secret not generated: %s" msgstr "" @@ -4651,7 +4651,7 @@ msgstr "" msgid "show apps of a specific server" msgstr "" -#: ./cli/run.go:193 ./cli/updater/updater.go:507 +#: ./cli/run.go:193 ./cli/updater/updater.go:493 msgid "show debug messages" msgstr "" @@ -4699,11 +4699,11 @@ msgstr "" msgid "skipping converge logic checks" msgstr "" -#: ./cli/app/deploy.go:190 +#: ./cli/app/deploy.go:184 msgid "skipping domain checks" msgstr "" -#: ./cli/app/deploy.go:187 +#: ./cli/app/deploy.go:181 msgid "skipping domain checks, no DOMAIN=... configured" msgstr "" @@ -4932,7 +4932,7 @@ msgstr "" msgid "tmpfs options are incompatible with type volume" msgstr "" -#: ./cli/run.go:201 ./cli/updater/updater.go:515 +#: ./cli/run.go:201 ./cli/updater/updater.go:501 msgid "toggle non-interactive mode" msgstr "" @@ -4967,7 +4967,7 @@ msgstr "" #. no spaces in between #. translators: `abra upgrade` aliases. use a comma separated list of aliases with #. no spaces in between -#: ./cli/app/cmd.go:269 ./cli/app/run.go:118 ./cli/recipe/upgrade.go:42 ./cli/updater/updater.go:80 ./cli/upgrade.go:17 +#: ./cli/app/cmd.go:269 ./cli/app/run.go:118 ./cli/recipe/upgrade.go:42 ./cli/updater/updater.go:81 ./cli/upgrade.go:17 msgid "u" msgstr "" @@ -5258,11 +5258,11 @@ msgstr "" msgid "unknown" msgstr "" -#: ./cli/app/rollback.go:150 +#: ./cli/app/rollback.go:148 msgid "unknown deployed version, unable to downgrade" msgstr "" -#: ./cli/app/upgrade.go:155 +#: ./cli/app/upgrade.go:154 msgid "unknown deployed version, unable to upgrade" msgstr "" @@ -5293,11 +5293,11 @@ msgstr "" #. translators: `abra app upgrade` aliases. use a comma separated list of aliases with #. no spaces in between -#: ./cli/app/upgrade.go:30 +#: ./cli/app/upgrade.go:29 msgid "up" msgstr "" -#: ./cli/updater/updater.go:570 +#: ./cli/updater/updater.go:556 msgid "update all deployed apps" msgstr "" @@ -5316,13 +5316,13 @@ msgstr "" msgid "upgrade" msgstr "" -#: ./cli/updater/updater.go:456 +#: ./cli/updater/updater.go:442 #, c-format msgid "upgrade %s (%s) to version %s" msgstr "" #. translators: `app upgrade` command -#: ./cli/app/upgrade.go:34 +#: ./cli/app/upgrade.go:33 msgid "upgrade [version] [flags]" msgstr "" @@ -5332,7 +5332,7 @@ msgid "upgrade [flags]" msgstr "" #. translators: `app upgrade` command -#: ./cli/updater/updater.go:85 +#: ./cli/updater/updater.go:86 msgid "upgrade [[stack] [recipe] | --all] [flags]" msgstr "" @@ -5424,7 +5424,7 @@ msgstr "" msgid "version %s saved to %s.env" msgstr "" -#: ./cli/app/deploy.go:117 +#: ./cli/app/deploy.go:115 #, c-format msgid "version '%s' appears to be a chaos commit, but --chaos/-C was not provided" msgstr "" @@ -5448,32 +5448,32 @@ msgstr "" msgid "version wiped from %s.env" msgstr "" -#: ./cli/app/deploy.go:342 +#: ./cli/app/deploy.go:336 #, c-format msgid "version: can not redeploy chaos version %s" msgstr "" -#: ./cli/app/deploy.go:329 +#: ./cli/app/deploy.go:323 #, c-format msgid "version: taking chaos version: %s" msgstr "" -#: ./cli/app/deploy.go:350 +#: ./cli/app/deploy.go:344 #, c-format msgid "version: taking deployed version: %s" msgstr "" -#: ./cli/app/deploy.go:355 +#: ./cli/app/deploy.go:349 #, c-format msgid "version: taking new recipe version: %s" msgstr "" -#: ./cli/app/deploy.go:344 +#: ./cli/app/deploy.go:338 #, c-format msgid "version: taking version from .env file: %s" msgstr "" -#: ./cli/app/deploy.go:335 +#: ./cli/app/deploy.go:329 #, c-format msgid "version: taking version from cli arg: %s" msgstr "" @@ -5596,7 +5596,7 @@ msgstr "" msgid "writer: %v, " msgstr "" -#: ./cli/app/deploy.go:267 ./cli/app/new.go:221 ./cli/app/rollback.go:254 ./cli/app/undeploy.go:114 ./cli/app/upgrade.go:299 +#: ./cli/app/deploy.go:261 ./cli/app/new.go:221 ./cli/app/rollback.go:248 ./cli/app/undeploy.go:114 ./cli/app/upgrade.go:294 #, c-format msgid "writing recipe version failed: %s" msgstr "" -- 2.49.0 From 33aca421815f7edc43dbd11f9cc8b957f52a2bc4 Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Mon, 8 Sep 2025 11:21:44 -0400 Subject: [PATCH 20/28] feat: add --show-unchanged/-U option --- cli/app/deploy.go | 12 ++++++++++-- cli/app/rollback.go | 12 ++++++++++-- cli/app/upgrade.go | 12 ++++++++++-- cli/internal/cli.go | 1 + pkg/deploy/utils.go | 12 ++++++++---- 5 files changed, 39 insertions(+), 10 deletions(-) diff --git a/cli/app/deploy.go b/cli/app/deploy.go index b01faba3..5b9f76aa 100644 --- a/cli/app/deploy.go +++ b/cli/app/deploy.go @@ -196,13 +196,13 @@ checkout as-is. Recipe commit hashes are also supported as values for } // Gather configs - configInfo, err := deploy.GatherConfigsForDeploy(cl, app, compose, app.Env) + configInfo, err := deploy.GatherConfigsForDeploy(cl, app, compose, app.Env, internal.ShowUnchanged) if err != nil { log.Fatal(err) } // Gather images - imageInfo, err := deploy.GatherImagesForDeploy(cl, app, compose) + imageInfo, err := deploy.GatherImagesForDeploy(cl, app, compose, internal.ShowUnchanged) if err != nil { log.Fatal(err) } @@ -393,4 +393,12 @@ func init() { false, i18n.G("deploy latest recipe version"), ) + + AppDeployCommand.Flags().BoolVarP( + &internal.ShowUnchanged, + i18n.G("show-unchanged"), + i18n.G("U"), + false, + i18n.G("show all configs & images, including unchanged ones"), + ) } diff --git a/cli/app/rollback.go b/cli/app/rollback.go index 1c4b46f8..9b58003f 100644 --- a/cli/app/rollback.go +++ b/cli/app/rollback.go @@ -192,13 +192,13 @@ beforehand. See "abra app backup" for more.`), } // Gather configs - configInfo, err := deploy.GatherConfigsForDeploy(cl, app, compose, app.Env) + configInfo, err := deploy.GatherConfigsForDeploy(cl, app, compose, app.Env, internal.ShowUnchanged) if err != nil { log.Fatal(err) } // Gather images - imageInfo, err := deploy.GatherImagesForDeploy(cl, app, compose) + imageInfo, err := deploy.GatherImagesForDeploy(cl, app, compose, internal.ShowUnchanged) if err != nil { log.Fatal(err) } @@ -362,4 +362,12 @@ func init() { false, i18n.G("disable converge logic checks"), ) + + AppRollbackCommand.Flags().BoolVarP( + &internal.ShowUnchanged, + i18n.G("show-unchanged"), + i18n.G("U"), + false, + i18n.G("show all configs & images, including unchanged ones"), + ) } diff --git a/cli/app/upgrade.go b/cli/app/upgrade.go index d04504fb..35064524 100644 --- a/cli/app/upgrade.go +++ b/cli/app/upgrade.go @@ -218,13 +218,13 @@ beforehand. See "abra app backup" for more.`), } // Gather configs - configInfo, err := deploy.GatherConfigsForDeploy(cl, app, compose, app.Env) + configInfo, err := deploy.GatherConfigsForDeploy(cl, app, compose, app.Env, internal.ShowUnchanged) if err != nil { log.Fatal(err) } // Gather images - imageInfo, err := deploy.GatherImagesForDeploy(cl, app, compose) + imageInfo, err := deploy.GatherImagesForDeploy(cl, app, compose, internal.ShowUnchanged) if err != nil { log.Fatal(err) } @@ -480,4 +480,12 @@ func init() { false, i18n.G("only show release notes"), ) + + AppUpgradeCommand.Flags().BoolVarP( + &internal.ShowUnchanged, + i18n.G("show-unchanged"), + i18n.G("U"), + false, + i18n.G("show all configs & images, including unchanged ones"), + ) } diff --git a/cli/internal/cli.go b/cli/internal/cli.go index 3e8844d2..86b73233 100644 --- a/cli/internal/cli.go +++ b/cli/internal/cli.go @@ -19,4 +19,5 @@ var ( Minor bool NoDomainChecks bool Patch bool + ShowUnchanged bool ) diff --git a/pkg/deploy/utils.go b/pkg/deploy/utils.go index 30ce4c77..2e67c325 100644 --- a/pkg/deploy/utils.go +++ b/pkg/deploy/utils.go @@ -157,7 +157,7 @@ func GatherSecretsForDeploy(cl *dockerClient.Client, app appPkg.App) ([]string, return secretInfo, nil } -func GatherConfigsForDeploy(cl *dockerClient.Client, app appPkg.App, compose *composetypes.Config, abraShEnv map[string]string) ([]string, error) { +func GatherConfigsForDeploy(cl *dockerClient.Client, app appPkg.App, compose *composetypes.Config, abraShEnv map[string]string, showUnchanged bool) ([]string, error) { // Get current configs from existing deployment currentConfigs, err := GetConfigsForStack(cl, app) if err != nil { @@ -182,7 +182,9 @@ func GatherConfigsForDeploy(cl *dockerClient.Client, app appPkg.App, compose *co if currentVersion, exists := currentConfigs[configName]; exists { if currentVersion == newVersion { - configInfo = append(configInfo, fmt.Sprintf("%s: %s (unchanged)", configName, newVersion)) + if (showUnchanged) { + configInfo = append(configInfo, fmt.Sprintf("%s: %s (unchanged)", configName, newVersion)) + } } else { configInfo = append(configInfo, fmt.Sprintf("%s: %s → %s", configName, currentVersion, newVersion)) } @@ -194,7 +196,7 @@ func GatherConfigsForDeploy(cl *dockerClient.Client, app appPkg.App, compose *co return configInfo, nil } -func GatherImagesForDeploy(cl *dockerClient.Client, app appPkg.App, compose *composetypes.Config) ([]string, error) { +func GatherImagesForDeploy(cl *dockerClient.Client, app appPkg.App, compose *composetypes.Config, showUnchanged bool) ([]string, error) { // Get current images from existing deployment currentImages, err := GetImagesForStack(cl, app) @@ -230,7 +232,9 @@ func GatherImagesForDeploy(cl *dockerClient.Client, app appPkg.App, compose *com for newImageName, newImageVersion := range newImages { if currentVersion, exists := currentImages[newImageName]; exists { if currentVersion == newImageVersion { - imageInfo = append(imageInfo, fmt.Sprintf("%s: %s (unchanged)", newImageName, newImageVersion)) + if showUnchanged { + imageInfo = append(imageInfo, fmt.Sprintf("%s: %s (unchanged)", newImageName, newImageVersion)) + } } else { imageInfo = append(imageInfo, fmt.Sprintf("%s: %s → %s", newImageName, currentVersion, newImageVersion)) } -- 2.49.0 From e73b0cc2fc4f4c39db16a591044f1098d74c6cdc Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Mon, 8 Sep 2025 11:57:22 -0400 Subject: [PATCH 21/28] refactor: don't reinvent the wheel --- pkg/deploy/utils.go | 33 ++++++--------- pkg/deploy/utils_test.go | 87 ---------------------------------------- 2 files changed, 13 insertions(+), 107 deletions(-) delete mode 100644 pkg/deploy/utils_test.go diff --git a/pkg/deploy/utils.go b/pkg/deploy/utils.go index 2e67c325..e8e53e23 100644 --- a/pkg/deploy/utils.go +++ b/pkg/deploy/utils.go @@ -2,19 +2,19 @@ package deploy import ( "context" - "errors" "fmt" - "regexp" "sort" "strings" appPkg "coopcloud.tech/abra/pkg/app" "coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/envfile" + "coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/recipe" "coopcloud.tech/abra/pkg/secret" + "github.com/distribution/reference" composetypes "github.com/docker/cli/cli/compose/types" "github.com/docker/docker/api/types/swarm" dockerClient "github.com/docker/docker/client" @@ -82,19 +82,6 @@ func GetConfigsForStack(cl *dockerClient.Client, app appPkg.App) (map[string]str return configs, nil } -func GetImageNameAndTag(imageName string) (string, string, error) { - imageParts := regexp.MustCompile("^([^:]*):([^@]*)@?").FindSubmatch([]byte(imageName)) - - if len(imageParts) == 0 { - return "", "", errors.New("can't determine image version for image '%s'") - } - - imageBaseName := string(imageParts[1]) - imageTag := string(imageParts[2]) - - return imageBaseName, imageTag, nil -} - // GetImagesForStack retrieves all Docker images for services in a given stack. func GetImagesForStack(cl *dockerClient.Client, app appPkg.App) (map[string]string, error) { filters, err := app.Filters(false, false) @@ -116,12 +103,15 @@ func GetImagesForStack(cl *dockerClient.Client, app appPkg.App) (map[string]stri if service.Spec.TaskTemplate.ContainerSpec != nil { imageName := service.Spec.TaskTemplate.ContainerSpec.Image - imageBaseName, imageTag, err := GetImageNameAndTag(imageName) + imageParsed, err := reference.ParseNormalizedNamed(imageName) if err != nil { log.Warn(err) continue } + imageBaseName := reference.Path(imageParsed) + imageTag := imageParsed.(reference.NamedTagged).Tag() + existingImageVersion, ok := images[imageBaseName] if !ok { // First time seeing this, add to map @@ -210,7 +200,10 @@ func GatherImagesForDeploy(cl *dockerClient.Client, app appPkg.App, compose *com newImages := make(map[string]string) for _, service := range compose.Services { - imageBaseName, imageTag, err := GetImageNameAndTag(service.Image) + imageParsed, err := reference.ParseNormalizedNamed(service.Image) + imageBaseName := reference.Path(imageParsed) + imageTag := imageParsed.(reference.NamedTagged).Tag() + if err != nil { log.Warn(err) continue @@ -233,13 +226,13 @@ func GatherImagesForDeploy(cl *dockerClient.Client, app appPkg.App, compose *com if currentVersion, exists := currentImages[newImageName]; exists { if currentVersion == newImageVersion { if showUnchanged { - imageInfo = append(imageInfo, fmt.Sprintf("%s: %s (unchanged)", newImageName, newImageVersion)) + imageInfo = append(imageInfo, fmt.Sprintf("%s: %s (unchanged)", formatter.StripTagMeta(newImageName), newImageVersion)) } } else { - imageInfo = append(imageInfo, fmt.Sprintf("%s: %s → %s", newImageName, currentVersion, newImageVersion)) + imageInfo = append(imageInfo, fmt.Sprintf("%s: %s → %s", formatter.StripTagMeta(newImageName), currentVersion, newImageVersion)) } } else { - imageInfo = append(imageInfo, fmt.Sprintf("%s: %s (new)", newImageName, newImageVersion)) + imageInfo = append(imageInfo, fmt.Sprintf("%s: %s (new)", formatter.StripTagMeta(newImageName), newImageVersion)) } } diff --git a/pkg/deploy/utils_test.go b/pkg/deploy/utils_test.go deleted file mode 100644 index a0735d14..00000000 --- a/pkg/deploy/utils_test.go +++ /dev/null @@ -1,87 +0,0 @@ -package deploy - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestGetImageNameAndTag(t *testing.T) { - tests := []struct { - name string - imageName string - expectedName string - expectedTag string - expectError bool - description string - }{ - { - name: "standard image with tag", - imageName: "nginx:1.23", - expectedName: "nginx", - expectedTag: "1.23", - expectError: false, - description: "should parse standard image name with tag", - }, - { - name: "image with digest", - imageName: "nginx:1.23@sha256:abc123", - expectedName: "nginx", - expectedTag: "1.23", - expectError: false, - description: "should parse image with digest, ignoring digest part", - }, - { - name: "image with latest tag", - imageName: "redis:latest", - expectedName: "redis", - expectedTag: "latest", - expectError: false, - description: "should parse image with latest tag", - }, - { - name: "image with numeric tag", - imageName: "postgres:14", - expectedName: "postgres", - expectedTag: "14", - expectError: false, - description: "should parse image with numeric tag", - }, - { - name: "image with complex name", - imageName: "registry.example.com/myapp/api:v1.2.3", - expectedName: "registry.example.com/myapp/api", - expectedTag: "v1.2.3", - expectError: false, - description: "should parse image with registry prefix and complex name", - }, - { - name: "image without tag", - imageName: "nginx", - expectError: true, - description: "should error when no tag present", - }, - { - name: "empty image name", - imageName: "", - expectError: true, - description: "should error on empty image name", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - name, tag, err := GetImageNameAndTag(tt.imageName) - - if tt.expectError { - assert.Error(t, err) - assert.Empty(t, name) - assert.Empty(t, tag) - } else { - assert.NoError(t, err) - assert.Equal(t, tt.expectedName, name) - assert.Equal(t, tt.expectedTag, tag) - } - }) - } -} -- 2.49.0 From 0a4542465816abf2deec30b88eb5f8fdd0106845 Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Mon, 8 Sep 2025 14:45:04 -0400 Subject: [PATCH 22/28] test: check new deploy overview stuff --- tests/integration/app_deploy_overview.bats | 25 ++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/integration/app_deploy_overview.bats b/tests/integration/app_deploy_overview.bats index 475c657a..6abae8b4 100644 --- a/tests/integration/app_deploy_overview.bats +++ b/tests/integration/app_deploy_overview.bats @@ -41,6 +41,8 @@ teardown(){ assert_output --partial 'CURRENT DEPLOYMENT N/A' assert_output --partial 'ENV VERSION N/A' assert_output --partial "NEW DEPLOYMENT ${latestRelease}" + assert_output --partial "IMAGES nginx: ${latestRelease##*+} (new)" + assert_output --partial "CONFIGS test_conf: v1 (new)" run grep -q "TYPE=$TEST_RECIPE:${latestRelease}" \ "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" @@ -58,12 +60,35 @@ teardown(){ assert_output --partial "CURRENT DEPLOYMENT N/A" assert_output --partial "ENV VERSION ${latestRelease}" assert_output --partial "NEW DEPLOYMENT ${latestRelease}" + assert_output --partial "IMAGES nginx: ${latestRelease##*+} (new)" + assert_output --partial "CONFIGS test_conf: v1 (new)" run grep -q "TYPE=$TEST_RECIPE:${latestRelease}" \ "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env" assert_success } +# bats test_tags=slow +@test "show changed config version on re-deploy" { + run $ABRA app deploy "$TEST_APP_DOMAIN" \ + --no-input --no-converge-checks + assert_success + + run sed -i 's/TEST_CONF_VERSION=v1/TEST_CONF_VERSION=v2/' \ + "$ABRA_DIR/recipes/$TEST_RECIPE/abra.sh" \ + assert_success + + cat "$ABRA_DIR/recipes/$TEST_RECIPE/abra.sh" + + run $ABRA app deploy "$TEST_APP_DOMAIN" \ + --no-input --no-converge-checks --force --chaos + assert_success + + assert_output --partial "CONFIGS test_conf: v1 → v2" + + _checkout_recipe +} + # bats test_tags=slow @test "deploy, re-deploy, choose env version" { run $ABRA app deploy "$TEST_APP_DOMAIN" "0.1.1+1.20.2" \ -- 2.49.0 From e42b42e88221215d3ca3db1b02156b7d7e0b0abb Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Mon, 8 Sep 2025 14:59:26 -0400 Subject: [PATCH 23/28] chore: 4matting --- cli/internal/cli.go | 2 +- pkg/deploy/utils.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/internal/cli.go b/cli/internal/cli.go index 86b73233..1d32b475 100644 --- a/cli/internal/cli.go +++ b/cli/internal/cli.go @@ -19,5 +19,5 @@ var ( Minor bool NoDomainChecks bool Patch bool - ShowUnchanged bool + ShowUnchanged bool ) diff --git a/pkg/deploy/utils.go b/pkg/deploy/utils.go index e8e53e23..917dfdc2 100644 --- a/pkg/deploy/utils.go +++ b/pkg/deploy/utils.go @@ -172,7 +172,7 @@ func GatherConfigsForDeploy(cl *dockerClient.Client, app appPkg.App, compose *co if currentVersion, exists := currentConfigs[configName]; exists { if currentVersion == newVersion { - if (showUnchanged) { + if showUnchanged { configInfo = append(configInfo, fmt.Sprintf("%s: %s (unchanged)", configName, newVersion)) } } else { -- 2.49.0 From 241dffb8cd1da60f7c08ede7a4ca6ba802af9b9b Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Mon, 8 Sep 2025 15:00:45 -0400 Subject: [PATCH 24/28] chore: POT --- pkg/i18n/locales/abra.pot | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pkg/i18n/locales/abra.pot b/pkg/i18n/locales/abra.pot index 14dff346..8899a784 100644 --- a/pkg/i18n/locales/abra.pot +++ b/pkg/i18n/locales/abra.pot @@ -1431,6 +1431,10 @@ msgid "To load completions:\n" " # and source this file from your PowerShell profile." msgstr "" +#: ./cli/app/deploy.go:400 ./cli/app/rollback.go:369 ./cli/app/upgrade.go:487 +msgid "U" +msgstr "" + #: ./cli/internal/deploy.go:144 msgid "UNCHAOS DEPLOY" msgstr "" @@ -4635,6 +4639,10 @@ msgstr "" msgid "severity" msgstr "" +#: ./cli/app/deploy.go:402 ./cli/app/rollback.go:371 ./cli/app/upgrade.go:489 +msgid "show all configs & images, including unchanged ones" +msgstr "" + #: ./cli/app/backup.go:273 msgid "show all paths" msgstr "" @@ -4655,6 +4663,10 @@ msgstr "" msgid "show debug messages" msgstr "" +#: ./cli/app/deploy.go:399 ./cli/app/rollback.go:368 ./cli/app/upgrade.go:486 +msgid "show-unchanged" +msgstr "" + #: ./cli/app/logs.go:108 msgid "since" msgstr "" -- 2.49.0 From 34934cf62dfa0f37c90e5020a9d3a80ace04f3af Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Mon, 8 Sep 2025 22:05:41 -0400 Subject: [PATCH 25/28] refactor: move strings.Join to DeployOverview --- cli/app/deploy.go | 6 +++--- cli/app/rollback.go | 6 +++--- cli/app/undeploy.go | 6 +++--- cli/app/upgrade.go | 6 +++--- cli/internal/deploy.go | 12 ++++++------ 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/cli/app/deploy.go b/cli/app/deploy.go index 5b9f76aa..ff5e25ab 100644 --- a/cli/app/deploy.go +++ b/cli/app/deploy.go @@ -215,9 +215,9 @@ checkout as-is. Recipe commit hashes are also supported as values for toDeployVersion, "", deployWarnMessages, - strings.Join(secretInfo, "\n"), - strings.Join(configInfo, "\n"), - strings.Join(imageInfo, "\n"), + secretInfo, + configInfo, + imageInfo, ); err != nil { log.Fatal(err) } diff --git a/cli/app/rollback.go b/cli/app/rollback.go index 9b58003f..dfff8807 100644 --- a/cli/app/rollback.go +++ b/cli/app/rollback.go @@ -210,9 +210,9 @@ beforehand. See "abra app backup" for more.`), chosenDowngrade, "", downgradeWarnMessages, - strings.Join(secretInfo, "\n"), - strings.Join(configInfo, "\n"), - strings.Join(imageInfo, "\n"), + secretInfo, + configInfo, + imageInfo, ); err != nil { log.Fatal(err) } diff --git a/cli/app/undeploy.go b/cli/app/undeploy.go index 29633443..97f458a7 100644 --- a/cli/app/undeploy.go +++ b/cli/app/undeploy.go @@ -71,9 +71,9 @@ Passing "--prune/-p" does not remove those volumes.`), config.NO_DOMAIN_DEFAULT, "", nil, - "", - "", - "", + nil, + nil, + nil, ); err != nil { log.Fatal(err) } diff --git a/cli/app/upgrade.go b/cli/app/upgrade.go index 35064524..718ea6de 100644 --- a/cli/app/upgrade.go +++ b/cli/app/upgrade.go @@ -247,9 +247,9 @@ beforehand. See "abra app backup" for more.`), chosenUpgrade, upgradeReleaseNotes, upgradeWarnMessages, - strings.Join(secretInfo, "\n"), - strings.Join(configInfo, "\n"), - strings.Join(imageInfo, "\n"), + secretInfo, + configInfo, + imageInfo, ); err != nil { log.Fatal(err) } diff --git a/cli/internal/deploy.go b/cli/internal/deploy.go index 9fa556bb..00d8650b 100644 --- a/cli/internal/deploy.go +++ b/cli/internal/deploy.go @@ -50,9 +50,9 @@ func DeployOverview( toDeployVersion string, releaseNotes string, warnMessages []string, - secrets string, - configs string, - images string, + secrets []string, + configs []string, + images []string, ) error { deployConfig := "compose.yml" if composeFiles, ok := app.Env["COMPOSE_FILE"]; ok { @@ -84,13 +84,13 @@ func DeployOverview( {i18n.G("ENV VERSION"), formatter.BoldDirtyDefault(envVersion)}, {i18n.G("NEW DEPLOYMENT"), formatter.BoldDirtyDefault(toDeployVersion)}, {"", ""}, - {i18n.G("IMAGES"), images}, + {i18n.G("IMAGES"), strings.Join(images, "\n")}, } if len(secrets) > 0 { secretsRows := [][]string{ {"", ""}, - {i18n.G("SECRETS"), secrets}, + {i18n.G("SECRETS"), strings.Join(secrets, "\n")}, } rows = append(rows, secretsRows...) } @@ -98,7 +98,7 @@ func DeployOverview( if len(configs) > 0 { configsRows := [][]string{ {"", ""}, - {i18n.G("CONFIGS"), configs}, + {i18n.G("CONFIGS"), strings.Join(configs, "\n")}, } rows = append(rows, configsRows...) } -- 2.49.0 From 076d522b1a86cf579ecfbb7f5d670133788f4dd2 Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Tue, 9 Sep 2025 13:18:26 -0400 Subject: [PATCH 26/28] refactor: PR feedback --- cli/app/deploy.go | 1 - pkg/client/configs.go | 4 ++-- pkg/deploy/utils.go | 33 ++++++++++++++++----------------- 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/cli/app/deploy.go b/cli/app/deploy.go index ff5e25ab..fa0c14be 100644 --- a/cli/app/deploy.go +++ b/cli/app/deploy.go @@ -208,7 +208,6 @@ checkout as-is. Recipe commit hashes are also supported as values for } // Show deploy overview - if err := internal.DeployOverview( app, deployedVersion, diff --git a/pkg/client/configs.go b/pkg/client/configs.go index f102467f..406a32ad 100644 --- a/pkg/client/configs.go +++ b/pkg/client/configs.go @@ -39,11 +39,11 @@ func RemoveConfigs(cl *client.Client, ctx context.Context, configNames []string, return nil } +// GetConfigNameAndVersion parses a full config name like `app_example_com_someconf_v1` to extract name and version, ("someconf", "v1") func GetConfigNameAndVersion(fullName string, stackName string) (string, string, error) { name := strings.TrimPrefix(fullName, stackName+"_") if lastUnderscore := strings.LastIndex(name, "_"); lastUnderscore != -1 { return name[0:lastUnderscore], name[lastUnderscore+1:], nil - } else { - return "", "", errors.New(i18n.G("can't parse version from config '%s'", fullName)) } + return "", "", errors.New(i18n.G("can't parse version from config '%s'", fullName)) } diff --git a/pkg/deploy/utils.go b/pkg/deploy/utils.go index 917dfdc2..0cb69214 100644 --- a/pkg/deploy/utils.go +++ b/pkg/deploy/utils.go @@ -10,6 +10,7 @@ import ( "coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/envfile" "coopcloud.tech/abra/pkg/formatter" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/recipe" "coopcloud.tech/abra/pkg/secret" @@ -72,7 +73,7 @@ func GetConfigsForStack(cl *dockerClient.Client, app appPkg.App) (map[string]str } else { // Just make sure the versions are the same.. if existingConfigVersion != configVersion { - log.Warnf("different versions for config '%s', '%s' and %s'", configBaseName, existingConfigVersion, configVersion) + log.Warnf(i18n.G( "different versions for config '%s', '%s' and %s'", configBaseName, existingConfigVersion, configVersion)) } } } @@ -119,7 +120,7 @@ func GetImagesForStack(cl *dockerClient.Client, app appPkg.App) (map[string]stri } else { // Just make sure the versions are the same.. if existingImageVersion != imageTag { - log.Warnf("different versions for image '%s', '%s' and %s'", imageBaseName, existingImageVersion, imageTag) + log.Warnf(i18n.G("different versions for image '%s', '%s' and %s'", imageBaseName, existingImageVersion, imageTag)) } } } @@ -129,7 +130,6 @@ func GetImagesForStack(cl *dockerClient.Client, app appPkg.App) (map[string]stri } func GatherSecretsForDeploy(cl *dockerClient.Client, app appPkg.App) ([]string, error) { - secStats, err := secret.PollSecretsStatus(cl, app) if err != nil { return nil, err @@ -154,32 +154,32 @@ func GatherConfigsForDeploy(cl *dockerClient.Client, app appPkg.App, compose *co return nil, err } - log.Debugf("Deployed config names: %v", currentConfigs) + log.Debugf(i18n.G("deployed config names: %v", currentConfigs)) // Get new configs from the compose specification newConfigs := compose.Configs var configInfo []string for configName := range newConfigs { - log.Debugf("Searching abra.sh for version for %s", configName) + log.Debugf(i18n.G("searching abra.sh for version for %s", configName)) versionKey := strings.ToUpper(configName) + "_VERSION" newVersion, exists := abraShEnv[versionKey] if !exists { - log.Warnf("No version found for config %s", configName) - configInfo = append(configInfo, fmt.Sprintf("%s: ? (missing version)", configName)) + log.Warnf(i18n.G("no version found for config %s", configName)) + configInfo = append(configInfo, i18n.G("%s: ? (missing version)", configName)) continue } if currentVersion, exists := currentConfigs[configName]; exists { if currentVersion == newVersion { if showUnchanged { - configInfo = append(configInfo, fmt.Sprintf("%s: %s (unchanged)", configName, newVersion)) + configInfo = append(configInfo, i18n.G("%s: %s (unchanged)", configName, newVersion)) } } else { - configInfo = append(configInfo, fmt.Sprintf("%s: %s → %s", configName, currentVersion, newVersion)) + configInfo = append(configInfo, i18n.G("%s: %s → %s", configName, currentVersion, newVersion)) } } else { - configInfo = append(configInfo, fmt.Sprintf("%s: %s (new)", configName, newVersion)) + configInfo = append(configInfo, i18n.G("%s: %s (new)", configName, newVersion)) } } @@ -187,14 +187,13 @@ func GatherConfigsForDeploy(cl *dockerClient.Client, app appPkg.App, compose *co } func GatherImagesForDeploy(cl *dockerClient.Client, app appPkg.App, compose *composetypes.Config, showUnchanged bool) ([]string, error) { - // Get current images from existing deployment currentImages, err := GetImagesForStack(cl, app) if err != nil { return nil, err } - log.Debugf("Deployed images: %v", currentImages) + log.Debugf(i18n.G("deployed images: %v", currentImages)) // Proposed new images from the compose files newImages := make(map[string]string) @@ -215,24 +214,24 @@ func GatherImagesForDeploy(cl *dockerClient.Client, app appPkg.App, compose *com } else { // Just make sure the versions are the same.. if existingImageVersion != imageTag { - log.Warnf("different versions for image '%s', '%s' and %s'", imageBaseName, existingImageVersion, imageTag) + log.Warnf(i18n.G("different versions for image '%s', '%s' and %s'", imageBaseName, existingImageVersion, imageTag)) } } } - log.Debugf("Proposed images: %v", newImages) + log.Debugf(i18n.G("proposed images: %v", newImages)) var imageInfo []string for newImageName, newImageVersion := range newImages { if currentVersion, exists := currentImages[newImageName]; exists { if currentVersion == newImageVersion { if showUnchanged { - imageInfo = append(imageInfo, fmt.Sprintf("%s: %s (unchanged)", formatter.StripTagMeta(newImageName), newImageVersion)) + imageInfo = append(imageInfo, i18n.G("%s: %s (unchanged)", formatter.StripTagMeta(newImageName), newImageVersion)) } } else { - imageInfo = append(imageInfo, fmt.Sprintf("%s: %s → %s", formatter.StripTagMeta(newImageName), currentVersion, newImageVersion)) + imageInfo = append(imageInfo, i18n.G("%s: %s → %s", formatter.StripTagMeta(newImageName), currentVersion, newImageVersion)) } } else { - imageInfo = append(imageInfo, fmt.Sprintf("%s: %s (new)", formatter.StripTagMeta(newImageName), newImageVersion)) + imageInfo = append(imageInfo, i18n.G("%s: %s (new)", formatter.StripTagMeta(newImageName), newImageVersion)) } } -- 2.49.0 From d5f5d969442ea27266e9a181444ba4cd1655f5fe Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Tue, 9 Sep 2025 13:18:49 -0400 Subject: [PATCH 27/28] style: formatting --- pkg/deploy/utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/deploy/utils.go b/pkg/deploy/utils.go index 0cb69214..bfe333a2 100644 --- a/pkg/deploy/utils.go +++ b/pkg/deploy/utils.go @@ -73,7 +73,7 @@ func GetConfigsForStack(cl *dockerClient.Client, app appPkg.App) (map[string]str } else { // Just make sure the versions are the same.. if existingConfigVersion != configVersion { - log.Warnf(i18n.G( "different versions for config '%s', '%s' and %s'", configBaseName, existingConfigVersion, configVersion)) + log.Warnf(i18n.G("different versions for config '%s', '%s' and %s'", configBaseName, existingConfigVersion, configVersion)) } } } -- 2.49.0 From 39d1997edfe6f5689e3e066d0f7d23b80c83193a Mon Sep 17 00:00:00 2001 From: 3wc <3wc@doesthisthing.work> Date: Tue, 9 Sep 2025 13:19:22 -0400 Subject: [PATCH 28/28] chore: update POT --- pkg/i18n/locales/abra.pot | 121 ++++++++---- pkg/i18n/locales/es.po | 402 +++++++++++++++++++++++--------------- 2 files changed, 329 insertions(+), 194 deletions(-) diff --git a/pkg/i18n/locales/abra.pot b/pkg/i18n/locales/abra.pot index 8899a784..c2b27dd8 100644 --- a/pkg/i18n/locales/abra.pot +++ b/pkg/i18n/locales/abra.pot @@ -7,7 +7,7 @@ msgid "" msgstr "Project-Id-Version: \n" "Report-Msgid-Bugs-To: EMAIL\n" - "POT-Creation-Date: 2025-09-08 22:06-0400\n" + "POT-Creation-Date: 2025-09-09 13:19-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -441,16 +441,36 @@ msgstr "" msgid "%s: %s" msgstr "" +#: ./pkg/deploy/utils.go:182 ./pkg/deploy/utils.go:234 +#, c-format +msgid "%s: %s (new)" +msgstr "" + #: ./pkg/ui/deploy.go:344 #, c-format msgid "%s: %s (retries: %v, healthcheck: %s)" msgstr "" +#: ./pkg/deploy/utils.go:176 ./pkg/deploy/utils.go:228 +#, c-format +msgid "%s: %s (unchanged)" +msgstr "" + +#: ./pkg/deploy/utils.go:179 ./pkg/deploy/utils.go:231 +#, c-format +msgid "%s: %s → %s" +msgstr "" + #: ./pkg/app/app.go:521 #, c-format msgid "%s: %s: %s" msgstr "" +#: ./pkg/deploy/utils.go:169 +#, c-format +msgid "%s: ? (missing version)" +msgstr "" + #: ./pkg/recipe/recipe.go:237 #, c-format msgid "%s: attempt recipe metadata parse" @@ -582,7 +602,7 @@ msgstr "" msgid "Both local recipe and live deployment labels are shown." msgstr "" -#: ./cli/app/backup.go:319 ./cli/app/backup.go:335 ./cli/app/check.go:95 ./cli/app/cmd.go:285 ./cli/app/cp.go:385 ./cli/app/deploy.go:360 ./cli/app/labels.go:143 ./cli/app/new.go:377 ./cli/app/ps.go:213 ./cli/app/restart.go:162 ./cli/app/restore.go:138 ./cli/app/secret.go:569 ./cli/app/secret.go:609 ./cli/app/secret.go:633 ./cli/app/secret.go:641 ./cli/catalogue/catalogue.go:318 ./cli/recipe/lint.go:137 ./cli/updater/updater.go:538 +#: ./cli/app/backup.go:319 ./cli/app/backup.go:335 ./cli/app/check.go:95 ./cli/app/cmd.go:285 ./cli/app/cp.go:385 ./cli/app/deploy.go:359 ./cli/app/labels.go:143 ./cli/app/new.go:377 ./cli/app/ps.go:213 ./cli/app/restart.go:162 ./cli/app/restore.go:138 ./cli/app/secret.go:569 ./cli/app/secret.go:609 ./cli/app/secret.go:633 ./cli/app/secret.go:641 ./cli/catalogue/catalogue.go:318 ./cli/recipe/lint.go:137 ./cli/updater/updater.go:538 msgid "C" msgstr "" @@ -728,7 +748,7 @@ msgid "Creates a new app from a default recipe.\n" "on your $PATH." msgstr "" -#: ./cli/app/deploy.go:376 ./cli/app/new.go:353 ./cli/app/rollback.go:353 ./cli/app/upgrade.go:463 +#: ./cli/app/deploy.go:375 ./cli/app/new.go:353 ./cli/app/rollback.go:353 ./cli/app/upgrade.go:463 msgid "D" msgstr "" @@ -1431,7 +1451,7 @@ msgid "To load completions:\n" " # and source this file from your PowerShell profile." msgstr "" -#: ./cli/app/deploy.go:400 ./cli/app/rollback.go:369 ./cli/app/upgrade.go:487 +#: ./cli/app/deploy.go:399 ./cli/app/rollback.go:369 ./cli/app/upgrade.go:487 msgid "U" msgstr "" @@ -1785,7 +1805,7 @@ msgstr "" msgid "attempting to run %s" msgstr "" -#: ./cli/app/deploy.go:256 ./cli/app/upgrade.go:289 +#: ./cli/app/deploy.go:255 ./cli/app/upgrade.go:289 #, c-format msgid "attempting to run post deploy commands, saw: %s" msgstr "" @@ -1875,7 +1895,7 @@ msgstr "" #. no spaces in between #. translators: `abra app cp` aliases. use a comma separated list of aliases with #. no spaces in between -#: ./cli/app/backup.go:148 ./cli/app/cp.go:30 ./cli/app/deploy.go:384 ./cli/app/rollback.go:361 ./cli/app/upgrade.go:471 +#: ./cli/app/backup.go:148 ./cli/app/cp.go:30 ./cli/app/deploy.go:383 ./cli/app/rollback.go:361 ./cli/app/upgrade.go:471 msgid "c" msgstr "" @@ -1897,7 +1917,7 @@ msgstr "" msgid "can't copy dir to file" msgstr "" -#: ./pkg/client/configs.go:47 +#: ./pkg/client/configs.go:48 #, c-format msgid "can't parse version from config '%s'" msgstr "" @@ -1949,7 +1969,7 @@ msgstr "" msgid "cannot use '[secret] [version]' and '--all' together" msgstr "" -#: ./cli/app/deploy.go:295 +#: ./cli/app/deploy.go:294 msgid "cannot use --chaos and --latest together" msgstr "" @@ -1973,11 +1993,11 @@ msgstr "" msgid "cannot use [service] and --all-services/-a together" msgstr "" -#: ./cli/app/deploy.go:287 ./cli/app/new.go:76 +#: ./cli/app/deploy.go:286 ./cli/app/new.go:76 msgid "cannot use [version] and --chaos together" msgstr "" -#: ./cli/app/deploy.go:291 +#: ./cli/app/deploy.go:290 msgid "cannot use [version] and --latest together" msgstr "" @@ -2009,7 +2029,7 @@ msgstr "" msgid "cfg" msgstr "" -#: ./cli/app/backup.go:318 ./cli/app/backup.go:334 ./cli/app/check.go:94 ./cli/app/cmd.go:284 ./cli/app/cp.go:384 ./cli/app/deploy.go:359 ./cli/app/labels.go:142 ./cli/app/new.go:376 ./cli/app/ps.go:212 ./cli/app/restart.go:161 ./cli/app/restore.go:137 ./cli/app/secret.go:568 ./cli/app/secret.go:608 ./cli/app/secret.go:632 ./cli/app/secret.go:640 ./cli/catalogue/catalogue.go:317 ./cli/recipe/lint.go:136 ./cli/updater/updater.go:537 +#: ./cli/app/backup.go:318 ./cli/app/backup.go:334 ./cli/app/check.go:94 ./cli/app/cmd.go:284 ./cli/app/cp.go:384 ./cli/app/deploy.go:358 ./cli/app/labels.go:142 ./cli/app/new.go:376 ./cli/app/ps.go:212 ./cli/app/restart.go:161 ./cli/app/restore.go:137 ./cli/app/secret.go:568 ./cli/app/secret.go:608 ./cli/app/secret.go:632 ./cli/app/secret.go:640 ./cli/catalogue/catalogue.go:317 ./cli/recipe/lint.go:136 ./cli/updater/updater.go:537 msgid "chaos" msgstr "" @@ -2355,7 +2375,7 @@ msgstr "" msgid "deploy labels stanza present" msgstr "" -#: ./cli/app/deploy.go:394 +#: ./cli/app/deploy.go:393 msgid "deploy latest recipe version" msgstr "" @@ -2367,6 +2387,16 @@ msgstr "" msgid "deploy timed out 🟠" msgstr "" +#: ./pkg/deploy/utils.go:157 +#, c-format +msgid "deployed config names: %v" +msgstr "" + +#: ./pkg/deploy/utils.go:196 +#, c-format +msgid "deployed images: %v" +msgstr "" + #: ./cli/internal/deploy.go:130 msgid "deployment cancelled" msgstr "" @@ -2417,6 +2447,16 @@ msgstr "" msgid "diff [flags]" msgstr "" +#: ./pkg/deploy/utils.go:76 +#, c-format +msgid "different versions for config '%s', '%s' and %s'" +msgstr "" + +#: ./pkg/deploy/utils.go:123 ./pkg/deploy/utils.go:217 +#, c-format +msgid "different versions for image '%s', '%s' and %s'" +msgstr "" + #: ./pkg/recipe/recipe.go:202 #, c-format msgid "dir: %s, " @@ -2432,11 +2472,11 @@ msgstr "" msgid "dirty: %v, " msgstr "" -#: ./cli/app/deploy.go:386 ./cli/app/rollback.go:363 ./cli/app/upgrade.go:473 +#: ./cli/app/deploy.go:385 ./cli/app/rollback.go:363 ./cli/app/upgrade.go:473 msgid "disable converge logic checks" msgstr "" -#: ./cli/app/deploy.go:378 ./cli/app/rollback.go:355 ./cli/app/upgrade.go:465 +#: ./cli/app/deploy.go:377 ./cli/app/rollback.go:355 ./cli/app/upgrade.go:465 msgid "disable public DNS checks" msgstr "" @@ -2674,7 +2714,7 @@ msgstr "" #. translators: `abra recipe fetch` aliases. use a comma separated list of aliases #. with no spaces in between -#: ./cli/app/deploy.go:368 ./cli/app/remove.go:163 ./cli/app/rollback.go:345 ./cli/app/secret.go:593 ./cli/app/upgrade.go:455 ./cli/app/volume.go:217 ./cli/recipe/fetch.go:20 ./cli/recipe/fetch.go:138 +#: ./cli/app/deploy.go:367 ./cli/app/remove.go:163 ./cli/app/rollback.go:345 ./cli/app/secret.go:593 ./cli/app/upgrade.go:455 ./cli/app/volume.go:217 ./cli/recipe/fetch.go:20 ./cli/recipe/fetch.go:138 msgid "f" msgstr "" @@ -2910,7 +2950,7 @@ msgstr "" msgid "for %s read env %s with value: %s from docker service" msgstr "" -#: ./cli/app/deploy.go:367 ./cli/app/remove.go:162 ./cli/app/rollback.go:344 ./cli/app/upgrade.go:454 ./cli/app/volume.go:216 ./cli/recipe/fetch.go:137 +#: ./cli/app/deploy.go:366 ./cli/app/remove.go:162 ./cli/app/rollback.go:344 ./cli/app/upgrade.go:454 ./cli/app/volume.go:216 ./cli/recipe/fetch.go:137 msgid "force" msgstr "" @@ -3129,7 +3169,7 @@ msgstr "" msgid "id: %s, " msgstr "" -#: ./cli/app/backup.go:321 ./cli/app/backup.go:337 ./cli/app/check.go:97 ./cli/app/cmd.go:287 ./cli/app/cp.go:387 ./cli/app/deploy.go:362 ./cli/app/labels.go:145 ./cli/app/new.go:379 ./cli/app/ps.go:215 ./cli/app/restart.go:164 ./cli/app/restore.go:140 ./cli/app/secret.go:571 ./cli/app/secret.go:611 ./cli/app/secret.go:635 ./cli/app/secret.go:643 ./cli/catalogue/catalogue.go:320 ./cli/recipe/lint.go:139 ./cli/updater/updater.go:540 +#: ./cli/app/backup.go:321 ./cli/app/backup.go:337 ./cli/app/check.go:97 ./cli/app/cmd.go:287 ./cli/app/cp.go:387 ./cli/app/deploy.go:361 ./cli/app/labels.go:145 ./cli/app/new.go:379 ./cli/app/ps.go:215 ./cli/app/restart.go:164 ./cli/app/restore.go:140 ./cli/app/secret.go:571 ./cli/app/secret.go:611 ./cli/app/secret.go:635 ./cli/app/secret.go:643 ./cli/catalogue/catalogue.go:320 ./cli/recipe/lint.go:139 ./cli/updater/updater.go:540 msgid "ignore uncommitted recipes changes" msgstr "" @@ -3322,7 +3362,7 @@ msgstr "" #. no spaces in between #. translators: `abra recipe lint` aliases. use a comma separated list of #. aliases with no spaces in between -#: ./cli/app/cmd.go:261 ./cli/app/deploy.go:392 ./cli/app/logs.go:20 ./cli/recipe/lint.go:17 ./cli/server/add.go:207 +#: ./cli/app/cmd.go:261 ./cli/app/deploy.go:391 ./cli/app/logs.go:20 ./cli/recipe/lint.go:17 ./cli/server/add.go:207 msgid "l" msgstr "" @@ -3331,7 +3371,7 @@ msgstr "" msgid "labels [flags]" msgstr "" -#: ./cli/app/deploy.go:391 ./cli/app/list.go:183 +#: ./cli/app/deploy.go:390 ./cli/app/list.go:183 msgid "latest" msgstr "" @@ -3771,6 +3811,11 @@ msgstr "" msgid "no version bump type specififed?" msgstr "" +#: ./pkg/deploy/utils.go:168 +#, c-format +msgid "no version found for config %s" +msgstr "" + #: ./cli/app/volume.go:78 #, c-format msgid "no volumes created for %s" @@ -3784,11 +3829,11 @@ msgstr "" msgid "no volumes to remove" msgstr "" -#: ./cli/app/deploy.go:383 ./cli/app/rollback.go:360 ./cli/app/upgrade.go:470 +#: ./cli/app/deploy.go:382 ./cli/app/rollback.go:360 ./cli/app/upgrade.go:470 msgid "no-converge-checks" msgstr "" -#: ./cli/app/deploy.go:375 ./cli/app/rollback.go:352 ./cli/app/upgrade.go:462 +#: ./cli/app/deploy.go:374 ./cli/app/rollback.go:352 ./cli/app/upgrade.go:462 msgid "no-domain-checks" msgstr "" @@ -3924,7 +3969,7 @@ msgstr "" msgid "pattern" msgstr "" -#: ./cli/app/deploy.go:370 ./cli/app/remove.go:165 ./cli/app/rollback.go:347 ./cli/app/upgrade.go:457 ./cli/app/volume.go:219 +#: ./cli/app/deploy.go:369 ./cli/app/remove.go:165 ./cli/app/rollback.go:347 ./cli/app/upgrade.go:457 ./cli/app/volume.go:219 msgid "perform action without further prompt" msgstr "" @@ -3982,6 +4027,11 @@ msgstr "" msgid "processing %s for %s" msgstr "" +#: ./pkg/deploy/utils.go:221 +#, c-format +msgid "proposed images: %v" +msgstr "" + #: ./cli/app/undeploy.go:162 msgid "prune" msgstr "" @@ -4439,7 +4489,7 @@ msgstr "" msgid "run command locally" msgstr "" -#: ./cli/app/deploy.go:254 ./cli/app/upgrade.go:286 +#: ./cli/app/deploy.go:253 ./cli/app/upgrade.go:286 #, c-format msgid "run the following post-deploy commands: %s" msgstr "" @@ -4495,6 +4545,11 @@ msgstr "" msgid "satisfied" msgstr "" +#: ./pkg/deploy/utils.go:164 +#, c-format +msgid "searching abra.sh for version for %s" +msgstr "" + #: ./pkg/secret/secret.go:139 #, c-format msgid "secret %s is > %d chars when combined with %s" @@ -4519,7 +4574,7 @@ msgstr "" msgid "secret not found: %s" msgstr "" -#: ./cli/app/deploy.go:309 +#: ./cli/app/deploy.go:308 #, c-format msgid "secret not generated: %s" msgstr "" @@ -4639,7 +4694,7 @@ msgstr "" msgid "severity" msgstr "" -#: ./cli/app/deploy.go:402 ./cli/app/rollback.go:371 ./cli/app/upgrade.go:489 +#: ./cli/app/deploy.go:401 ./cli/app/rollback.go:371 ./cli/app/upgrade.go:489 msgid "show all configs & images, including unchanged ones" msgstr "" @@ -4663,7 +4718,7 @@ msgstr "" msgid "show debug messages" msgstr "" -#: ./cli/app/deploy.go:399 ./cli/app/rollback.go:368 ./cli/app/upgrade.go:486 +#: ./cli/app/deploy.go:398 ./cli/app/rollback.go:368 ./cli/app/upgrade.go:486 msgid "show-unchanged" msgstr "" @@ -5460,32 +5515,32 @@ msgstr "" msgid "version wiped from %s.env" msgstr "" -#: ./cli/app/deploy.go:336 +#: ./cli/app/deploy.go:335 #, c-format msgid "version: can not redeploy chaos version %s" msgstr "" -#: ./cli/app/deploy.go:323 +#: ./cli/app/deploy.go:322 #, c-format msgid "version: taking chaos version: %s" msgstr "" -#: ./cli/app/deploy.go:344 +#: ./cli/app/deploy.go:343 #, c-format msgid "version: taking deployed version: %s" msgstr "" -#: ./cli/app/deploy.go:349 +#: ./cli/app/deploy.go:348 #, c-format msgid "version: taking new recipe version: %s" msgstr "" -#: ./cli/app/deploy.go:338 +#: ./cli/app/deploy.go:337 #, c-format msgid "version: taking version from .env file: %s" msgstr "" -#: ./cli/app/deploy.go:329 +#: ./cli/app/deploy.go:328 #, c-format msgid "version: taking version from cli arg: %s" msgstr "" @@ -5608,7 +5663,7 @@ msgstr "" msgid "writer: %v, " msgstr "" -#: ./cli/app/deploy.go:261 ./cli/app/new.go:221 ./cli/app/rollback.go:248 ./cli/app/undeploy.go:114 ./cli/app/upgrade.go:294 +#: ./cli/app/deploy.go:260 ./cli/app/new.go:221 ./cli/app/rollback.go:248 ./cli/app/undeploy.go:114 ./cli/app/upgrade.go:294 #, c-format msgid "writing recipe version failed: %s" msgstr "" diff --git a/pkg/i18n/locales/es.po b/pkg/i18n/locales/es.po index 206e9d5b..819457b0 100644 --- a/pkg/i18n/locales/es.po +++ b/pkg/i18n/locales/es.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: EMAIL\n" -"POT-Creation-Date: 2025-09-06 08:28+0200\n" +"POT-Creation-Date: 2025-09-09 13:19-0400\n" "PO-Revision-Date: 2025-09-04 08:14+0000\n" "Last-Translator: chasqui \n" "Language-Team: Spanish [flags]" msgstr "verificar [flags]" -#: cli/updater/updater.go:562 +#: cli/updater/updater.go:548 msgid "check for major updates" msgstr "" -#: cli/app/deploy.go:94 cli/app/undeploy.go:57 cli/app/upgrade.go:419 +#: cli/app/deploy.go:93 cli/app/undeploy.go:57 cli/app/upgrade.go:435 #, c-format msgid "checking whether %s is already deployed" msgstr "" @@ -2204,12 +2241,12 @@ msgstr "" msgid "choosing %s as new version for %s" msgstr "" -#: cli/app/rollback.go:152 +#: cli/app/rollback.go:151 #, c-format msgid "choosing %s as version to rollback" msgstr "" -#: cli/app/upgrade.go:158 +#: cli/app/upgrade.go:157 #, c-format msgid "choosing %s as version to upgrade" msgstr "" @@ -2301,7 +2338,7 @@ msgstr "" msgid "compose: %s, " msgstr "" -#: pkg/client/configs.go:35 +#: pkg/client/configs.go:36 #, c-format msgid "conf %s: %s" msgstr "" @@ -2340,7 +2377,7 @@ msgstr "" msgid "considering %s config(s) for tag update" msgstr "" -#: cli/app/undeploy.go:132 cli/server/prune.go:53 +#: cli/app/undeploy.go:135 cli/server/prune.go:53 #, c-format msgid "containers pruned: %d; space reclaimed: %s" msgstr "" @@ -2471,7 +2508,7 @@ msgstr "" msgid "critical errors present in %s config" msgstr "" -#: cli/app/rollback.go:275 +#: cli/app/rollback.go:291 #, c-format msgid "current deployment '%s' is not a known version for %s" msgstr "" @@ -2487,12 +2524,12 @@ msgstr "" #. no spaces in between #. translators: `abra recipe diff` aliases. use a comma separated list of aliases #. with no spaces in between -#: cli/app/backup.go:73 cli/app/deploy.go:29 cli/recipe/diff.go:16 -#: cli/updater/updater.go:505 +#: cli/app/backup.go:73 cli/app/deploy.go:28 cli/recipe/diff.go:16 +#: cli/updater/updater.go:491 msgid "d" msgstr "" -#: cli/updater/updater.go:504 +#: cli/updater/updater.go:490 msgid "debug" msgstr "" @@ -2507,7 +2544,7 @@ msgid "deleted %s successfully from server" msgstr "" #. translators: `app deploy` command -#: cli/app/deploy.go:33 +#: cli/app/deploy.go:32 msgid "deploy [version] [flags]" msgstr "desplegar [version] [flags]" @@ -2523,7 +2560,7 @@ msgstr "" msgid "deploy labels stanza present" msgstr "" -#: cli/app/deploy.go:376 +#: cli/app/deploy.go:393 #, fuzzy msgid "deploy latest recipe version" msgstr "Publicar una nueva versión de una receta" @@ -2536,7 +2573,17 @@ msgstr "" msgid "deploy timed out 🟠" msgstr "" -#: cli/internal/deploy.go:109 +#: pkg/deploy/utils.go:157 +#, c-format +msgid "deployed config names: %v" +msgstr "" + +#: pkg/deploy/utils.go:196 +#, c-format +msgid "deployed images: %v" +msgstr "" + +#: cli/internal/deploy.go:130 msgid "deployment cancelled" msgstr "" @@ -2586,6 +2633,16 @@ msgstr "" msgid "diff [flags]" msgstr "comparar [flags]" +#: pkg/deploy/utils.go:76 +#, c-format +msgid "different versions for config '%s', '%s' and %s'" +msgstr "" + +#: pkg/deploy/utils.go:123 pkg/deploy/utils.go:217 +#, c-format +msgid "different versions for image '%s', '%s' and %s'" +msgstr "" + #: pkg/recipe/recipe.go:202 #, c-format msgid "dir: %s, " @@ -2601,11 +2658,11 @@ msgstr "" msgid "dirty: %v, " msgstr "" -#: cli/app/deploy.go:368 cli/app/rollback.go:347 cli/app/upgrade.go:457 +#: cli/app/deploy.go:385 cli/app/rollback.go:363 cli/app/upgrade.go:473 msgid "disable converge logic checks" msgstr "" -#: cli/app/deploy.go:360 cli/app/rollback.go:339 cli/app/upgrade.go:449 +#: cli/app/deploy.go:377 cli/app/rollback.go:355 cli/app/upgrade.go:465 msgid "disable public DNS checks" msgstr "" @@ -2638,24 +2695,24 @@ msgstr "" msgid "don't forget to run 'sudo mandb'" msgstr "" -#: cli/updater/updater.go:398 +#: cli/updater/updater.go:384 #, c-format msgid "don't update %s due to chaos deployment" msgstr "" -#: cli/updater/updater.go:408 +#: cli/updater/updater.go:394 #, c-format msgid "" "don't update %s due to disabled auto updates or missing ENABLE_AUTO_UPDATE " "env" msgstr "" -#: cli/updater/updater.go:388 +#: cli/updater/updater.go:374 #, c-format msgid "don't update %s due to missing recipe name" msgstr "" -#: cli/updater/updater.go:418 +#: cli/updater/updater.go:404 #, c-format msgid "don't update %s due to no new version" msgstr "" @@ -2665,7 +2722,7 @@ msgstr "" msgid "download [flags]" msgstr "descargar [flags]" -#: cli/internal/deploy.go:192 +#: cli/internal/deploy.go:213 msgid "dry run" msgstr "" @@ -2753,7 +2810,7 @@ msgstr "" msgid "ensure \"image: ...\" set on all services" msgstr "" -#: cli/app/deploy.go:113 +#: cli/app/deploy.go:112 #, c-format msgid "ensure recipe: %s" msgstr "" @@ -2850,8 +2907,8 @@ msgstr "" #. translators: `abra recipe fetch` aliases. use a comma separated list of aliases #. with no spaces in between -#: cli/app/deploy.go:350 cli/app/remove.go:163 cli/app/rollback.go:329 -#: cli/app/secret.go:593 cli/app/upgrade.go:439 cli/app/volume.go:217 +#: cli/app/deploy.go:367 cli/app/remove.go:163 cli/app/rollback.go:345 +#: cli/app/secret.go:593 cli/app/upgrade.go:455 cli/app/volume.go:217 #: cli/recipe/fetch.go:20 cli/recipe/fetch.go:138 msgid "f" msgstr "" @@ -2911,7 +2968,7 @@ msgstr "" msgid "failed to create volume %s on %s: %s" msgstr "🥷 Genera secretos (contraseñas) automáticamente 🤖" -#: cli/updater/updater.go:263 +#: cli/updater/updater.go:264 #, c-format msgid "failed to determine deployed version of %s" msgstr "" @@ -3083,13 +3140,13 @@ msgstr "" msgid "filter by recipe" msgstr "" -#: cli/updater/updater.go:214 +#: cli/updater/updater.go:215 #, c-format msgid "for %s read env %s with value: %s from docker service" msgstr "" -#: cli/app/deploy.go:349 cli/app/remove.go:162 cli/app/rollback.go:328 -#: cli/app/upgrade.go:438 cli/app/volume.go:216 cli/recipe/fetch.go:137 +#: cli/app/deploy.go:366 cli/app/remove.go:162 cli/app/rollback.go:344 +#: cli/app/upgrade.go:454 cli/app/volume.go:216 cli/recipe/fetch.go:137 msgid "force" msgstr "" @@ -3148,7 +3205,7 @@ msgstr "" msgid "generated secrets %s shown again, please take note of them %s" msgstr "" -#: cli/app/deploy.go:107 +#: cli/app/deploy.go:106 #, c-format msgid "get deploy version: %s" msgstr "" @@ -3310,16 +3367,16 @@ msgid "id: %s, " msgstr "" #: cli/app/backup.go:321 cli/app/backup.go:337 cli/app/check.go:97 -#: cli/app/cmd.go:287 cli/app/cp.go:387 cli/app/deploy.go:344 +#: cli/app/cmd.go:287 cli/app/cp.go:387 cli/app/deploy.go:361 #: cli/app/labels.go:145 cli/app/new.go:379 cli/app/ps.go:215 #: cli/app/restart.go:164 cli/app/restore.go:140 cli/app/secret.go:571 #: cli/app/secret.go:611 cli/app/secret.go:635 cli/app/secret.go:643 #: cli/catalogue/catalogue.go:320 cli/recipe/lint.go:139 -#: cli/updater/updater.go:554 +#: cli/updater/updater.go:540 msgid "ignore uncommitted recipes changes" msgstr "" -#: cli/app/undeploy.go:147 cli/server/prune.go:74 +#: cli/app/undeploy.go:150 cli/server/prune.go:74 #, c-format msgid "images pruned: %d; space reclaimed: %s" msgstr "" @@ -3497,11 +3554,11 @@ msgid "invalid version %s specified" msgstr "" #. translators: `kadabra` binary name -#: cli/updater/updater.go:484 +#: cli/updater/updater.go:470 msgid "kadabra [cmd] [flags]" msgstr "" -#: cli/updater/updater.go:498 +#: cli/updater/updater.go:484 #, c-format msgid "kadabra version %s, commit %s" msgstr "" @@ -3510,7 +3567,7 @@ msgstr "" #. no spaces in between #. translators: `abra recipe lint` aliases. use a comma separated list of #. aliases with no spaces in between -#: cli/app/cmd.go:261 cli/app/deploy.go:374 cli/app/logs.go:20 +#: cli/app/cmd.go:261 cli/app/deploy.go:391 cli/app/logs.go:20 #: cli/recipe/lint.go:17 cli/server/add.go:207 msgid "l" msgstr "" @@ -3520,7 +3577,7 @@ msgstr "" msgid "labels [flags]" msgstr "etiquetas [flags]" -#: cli/app/deploy.go:373 cli/app/list.go:183 +#: cli/app/deploy.go:390 cli/app/list.go:183 msgid "latest" msgstr "" @@ -3648,7 +3705,7 @@ msgstr "plataformas" #: cli/app/list.go:318 cli/app/move.go:34 cli/app/ps.go:205 #: cli/app/secret.go:553 cli/app/secret.go:649 cli/recipe/list.go:104 #: cli/recipe/upgrade.go:376 cli/recipe/version.go:139 cli/run.go:152 -#: cli/server/list.go:106 cli/updater/updater.go:560 +#: cli/server/list.go:106 cli/updater/updater.go:546 msgid "m" msgstr "" @@ -3665,7 +3722,7 @@ msgstr "" #: cli/internal/recipe.go:48 cli/internal/recipe.go:66 #: cli/internal/recipe.go:80 cli/recipe/release.go:647 cli/recipe/sync.go:277 -#: cli/recipe/upgrade.go:351 cli/updater/updater.go:559 +#: cli/recipe/upgrade.go:351 cli/updater/updater.go:545 msgid "major" msgstr "" @@ -3711,7 +3768,7 @@ msgstr "" msgid "missing arguments [secret]/[version] or '--all'" msgstr "" -#: cli/updater/updater.go:115 +#: cli/updater/updater.go:116 msgid "missing arguments or --all/-a flag" msgstr "" @@ -3740,8 +3797,8 @@ msgstr "" #. aliases with no spaces in between #. translators: `kadabra notify` aliases. use a comma separated list of aliases #. with no spaces in between -#: cli/app/new.go:48 cli/recipe/new.go:36 cli/updater/updater.go:35 -#: cli/updater/updater.go:513 +#: cli/app/new.go:48 cli/recipe/new.go:36 cli/updater/updater.go:36 +#: cli/updater/updater.go:499 msgid "n" msgstr "n" @@ -3777,7 +3834,7 @@ msgid "" "instead of \"swarm\"" msgstr "" -#: cli/app/undeploy.go:139 cli/server/prune.go:60 +#: cli/app/undeploy.go:142 cli/server/prune.go:60 #, c-format msgid "networks pruned: %d" msgstr "" @@ -3817,7 +3874,7 @@ msgstr "" msgid "no %s exists, skipping reading gitignore paths" msgstr "" -#: cli/updater/updater.go:167 pkg/app/compose.go:87 +#: cli/updater/updater.go:168 pkg/app/compose.go:87 #, c-format msgid "no %s label found for %s" msgstr "" @@ -3840,15 +3897,15 @@ msgstr "" msgid "no app provided" msgstr "" -#: cli/app/rollback.go:127 +#: cli/app/rollback.go:126 msgid "no available downgrades" msgstr "" -#: cli/app/upgrade.go:133 +#: cli/app/upgrade.go:132 msgid "no available upgrades" msgstr "" -#: cli/updater/updater.go:236 +#: cli/updater/updater.go:237 #, c-format msgid "no available upgrades for %s" msgstr "" @@ -3899,7 +3956,7 @@ msgid "" "tags to see all anyway)" msgstr "" -#: cli/updater/updater.go:285 +#: cli/updater/updater.go:286 #, fuzzy, c-format msgid "no published releases for %s in the recipe catalogue?" msgstr "TRANSLATE THIS FUCKING SHIT ALREADY" @@ -3981,6 +4038,11 @@ msgstr "" msgid "no version bump type specififed?" msgstr "" +#: pkg/deploy/utils.go:168 +#, c-format +msgid "no version found for config %s" +msgstr "" + #: cli/app/volume.go:78 #, c-format msgid "no volumes created for %s" @@ -3994,15 +4056,15 @@ msgstr "" msgid "no volumes to remove" msgstr "" -#: cli/app/deploy.go:365 cli/app/rollback.go:344 cli/app/upgrade.go:454 +#: cli/app/deploy.go:382 cli/app/rollback.go:360 cli/app/upgrade.go:470 msgid "no-converge-checks" msgstr "" -#: cli/app/deploy.go:357 cli/app/rollback.go:336 cli/app/upgrade.go:446 +#: cli/app/deploy.go:374 cli/app/rollback.go:352 cli/app/upgrade.go:462 msgid "no-domain-checks" msgstr "" -#: cli/updater/updater.go:512 +#: cli/updater/updater.go:498 msgid "no-input" msgstr "" @@ -4010,7 +4072,7 @@ msgstr "" msgid "no-tty" msgstr "" -#: cli/internal/deploy.go:222 +#: cli/internal/deploy.go:243 #, c-format msgid "not enough arguments: %s" msgstr "" @@ -4041,7 +4103,7 @@ msgid "nothing found in stack: %s" msgstr "" #. translators: `notify` command -#: cli/updater/updater.go:40 +#: cli/updater/updater.go:41 msgid "notify [flags]" msgstr "notificar [flags]" @@ -4065,7 +4127,7 @@ msgstr "" msgid "only show errors" msgstr "" -#: cli/app/upgrade.go:465 +#: cli/app/upgrade.go:481 msgid "only show release notes" msgstr "" @@ -4079,7 +4141,7 @@ msgstr "" #. aliases with no spaces in between #: cli/app/backup.go:295 cli/app/new.go:361 cli/app/ps.go:29 #: cli/app/secret.go:561 cli/app/secret.go:585 cli/app/secret.go:625 -#: cli/app/undeploy.go:160 cli/catalogue/catalogue.go:294 +#: cli/app/undeploy.go:163 cli/catalogue/catalogue.go:294 #: cli/recipe/list.go:112 cli/recipe/release.go:672 cli/server/prune.go:18 msgid "p" msgstr "" @@ -4099,22 +4161,22 @@ msgstr "" msgid "parsed following command arguments: %s" msgstr "" -#: cli/app/upgrade.go:322 +#: cli/app/upgrade.go:338 #, c-format msgid "parsing chosen upgrade version failed: %s" msgstr "" -#: cli/app/upgrade.go:366 +#: cli/app/upgrade.go:382 #, c-format msgid "parsing deployed version failed: %s" msgstr "" -#: cli/app/upgrade.go:327 +#: cli/app/upgrade.go:343 #, c-format msgid "parsing deployment version failed: %s" msgstr "" -#: cli/app/upgrade.go:333 cli/app/upgrade.go:372 +#: cli/app/upgrade.go:349 cli/app/upgrade.go:388 #, c-format msgid "parsing recipe version failed: %s" msgstr "" @@ -4142,8 +4204,8 @@ msgstr "" msgid "pattern" msgstr "" -#: cli/app/deploy.go:352 cli/app/remove.go:165 cli/app/rollback.go:331 -#: cli/app/upgrade.go:441 cli/app/volume.go:219 +#: cli/app/deploy.go:369 cli/app/remove.go:165 cli/app/rollback.go:347 +#: cli/app/upgrade.go:457 cli/app/volume.go:219 msgid "perform action without further prompt" msgstr "" @@ -4152,22 +4214,22 @@ msgstr "" msgid "please fix your synced label for %s and re-run this command" msgstr "" -#: cli/app/rollback.go:243 +#: cli/app/rollback.go:259 #, c-format msgid "please select a downgrade (version: %s):" msgstr "" -#: cli/app/rollback.go:248 +#: cli/app/rollback.go:264 #, c-format msgid "please select a downgrade (version: %s, chaos: %s):" msgstr "" -#: cli/app/upgrade.go:289 +#: cli/app/upgrade.go:305 #, c-format msgid "please select an upgrade (version: %s):" msgstr "" -#: cli/app/upgrade.go:294 +#: cli/app/upgrade.go:310 #, c-format msgid "please select an upgrade (version: %s, chaos: %s):" msgstr "" @@ -4195,7 +4257,7 @@ msgstr "" msgid "print machine-readable output" msgstr "" -#: cli/internal/deploy.go:196 +#: cli/internal/deploy.go:217 msgid "proceed?" msgstr "" @@ -4204,7 +4266,12 @@ msgstr "" msgid "processing %s for %s" msgstr "" -#: cli/app/undeploy.go:159 +#: pkg/deploy/utils.go:221 +#, c-format +msgid "proposed images: %v" +msgstr "" + +#: cli/app/undeploy.go:162 msgid "prune" msgstr "" @@ -4213,7 +4280,7 @@ msgstr "" msgid "prune [flags]" msgstr "limpiar [flags]" -#: cli/app/undeploy.go:162 +#: cli/app/undeploy.go:165 msgid "prune unused containers, networks, and dangling images" msgstr "" @@ -4247,7 +4314,7 @@ msgstr "" #. translators: `abra recipe` aliases. use a comma separated list of aliases #. with no spaces in between #: cli/app/backup.go:327 cli/app/list.go:303 cli/app/move.go:346 -#: cli/app/run.go:23 cli/app/upgrade.go:463 cli/catalogue/catalogue.go:302 +#: cli/app/run.go:23 cli/app/upgrade.go:479 cli/catalogue/catalogue.go:302 #: cli/recipe/recipe.go:12 cli/recipe/release.go:640 cli/recipe/sync.go:270 msgid "r" msgstr "" @@ -4361,7 +4428,7 @@ msgstr "" msgid "release [version] [flags]" msgstr "publicar [version] [flags]" -#: cli/app/upgrade.go:462 +#: cli/app/upgrade.go:478 msgid "releasenotes" msgstr "" @@ -4549,7 +4616,7 @@ msgstr "" msgid "retries" msgstr "" -#: cli/updater/updater.go:251 +#: cli/updater/updater.go:252 #, c-format msgid "retrieve deployed version whether %s is already deployed" msgstr "" @@ -4606,7 +4673,7 @@ msgstr "" #. aliases with no spaces in between #. translators: `abra recipe release` aliases. use a comma separated list of #. aliases with no spaces in between -#: cli/app/rollback.go:27 cli/recipe/release.go:28 +#: cli/app/rollback.go:26 cli/recipe/release.go:28 msgid "rl" msgstr "" @@ -4624,7 +4691,7 @@ msgid "rm" msgstr "" #. translators: `app rollback` command -#: cli/app/rollback.go:31 +#: cli/app/rollback.go:30 msgid "rollback [version] [flags]" msgstr "revertir [version] [flags]" @@ -4667,7 +4734,7 @@ msgstr "" msgid "run command locally" msgstr "" -#: cli/app/deploy.go:236 cli/app/upgrade.go:270 +#: cli/app/deploy.go:253 cli/app/upgrade.go:286 #, c-format msgid "run the following post-deploy commands: %s" msgstr "" @@ -4677,7 +4744,7 @@ msgstr "" msgid "running backup %s on %s with exec config %v" msgstr "" -#: cli/internal/deploy.go:252 +#: cli/internal/deploy.go:273 #, c-format msgid "running command %s %s within the context of %s_%s" msgstr "" @@ -4697,7 +4764,7 @@ msgstr "" msgid "running command: %s" msgstr "" -#: cli/internal/deploy.go:230 +#: cli/internal/deploy.go:251 #, c-format msgid "running post-command '%s %s' in container %s" msgstr "" @@ -4727,6 +4794,11 @@ msgstr "" msgid "satisfied" msgstr "" +#: pkg/deploy/utils.go:164 +#, c-format +msgid "searching abra.sh for version for %s" +msgstr "" + #: pkg/secret/secret.go:139 #, c-format msgid "secret %s is > %d chars when combined with %s" @@ -4751,7 +4823,7 @@ msgstr "" msgid "secret not found: %s" msgstr "" -#: cli/app/deploy.go:291 +#: cli/app/deploy.go:308 #, c-format msgid "secret not generated: %s" msgstr "" @@ -4874,6 +4946,10 @@ msgstr "" msgid "severity" msgstr "" +#: cli/app/deploy.go:401 cli/app/rollback.go:371 cli/app/upgrade.go:489 +msgid "show all configs & images, including unchanged ones" +msgstr "" + #: cli/app/backup.go:273 msgid "show all paths" msgstr "" @@ -4890,10 +4966,14 @@ msgstr "" msgid "show apps of a specific server" msgstr "" -#: cli/run.go:193 cli/updater/updater.go:507 +#: cli/run.go:193 cli/updater/updater.go:493 msgid "show debug messages" msgstr "" +#: cli/app/deploy.go:398 cli/app/rollback.go:368 cli/app/upgrade.go:486 +msgid "show-unchanged" +msgstr "" + #: cli/app/logs.go:108 msgid "since" msgstr "" @@ -4938,11 +5018,11 @@ msgstr "" msgid "skipping converge logic checks" msgstr "" -#: cli/app/deploy.go:189 +#: cli/app/deploy.go:184 msgid "skipping domain checks" msgstr "" -#: cli/app/deploy.go:186 +#: cli/app/deploy.go:181 msgid "skipping domain checks, no DOMAIN=... configured" msgstr "" @@ -5174,7 +5254,7 @@ msgstr "" msgid "tmpfs options are incompatible with type volume" msgstr "" -#: cli/run.go:201 cli/updater/updater.go:515 +#: cli/run.go:201 cli/updater/updater.go:501 msgid "toggle non-interactive mode" msgstr "" @@ -5210,7 +5290,7 @@ msgstr "" #. translators: `abra upgrade` aliases. use a comma separated list of aliases with #. no spaces in between #: cli/app/cmd.go:269 cli/app/run.go:118 cli/recipe/upgrade.go:42 -#: cli/updater/updater.go:80 cli/upgrade.go:17 +#: cli/updater/updater.go:81 cli/upgrade.go:17 msgid "u" msgstr "" @@ -5472,7 +5552,7 @@ msgstr "" msgid "undeploy [flags]" msgstr "desarmar [flags]" -#: cli/app/undeploy.go:108 +#: cli/app/undeploy.go:111 msgid "undeploy succeeded 🟢" msgstr "" @@ -5509,11 +5589,11 @@ msgstr "" msgid "unknown" msgstr "" -#: cli/app/rollback.go:149 +#: cli/app/rollback.go:148 msgid "unknown deployed version, unable to downgrade" msgstr "" -#: cli/app/upgrade.go:155 +#: cli/app/upgrade.go:154 msgid "unknown deployed version, unable to upgrade" msgstr "" @@ -5544,11 +5624,11 @@ msgstr "" #. translators: `abra app upgrade` aliases. use a comma separated list of aliases with #. no spaces in between -#: cli/app/upgrade.go:30 +#: cli/app/upgrade.go:29 msgid "up" msgstr "" -#: cli/updater/updater.go:570 +#: cli/updater/updater.go:556 msgid "update all deployed apps" msgstr "" @@ -5567,13 +5647,13 @@ msgstr "" msgid "upgrade" msgstr "" -#: cli/updater/updater.go:456 +#: cli/updater/updater.go:442 #, c-format msgid "upgrade %s (%s) to version %s" msgstr "" #. translators: `app upgrade` command -#: cli/app/upgrade.go:34 +#: cli/app/upgrade.go:33 msgid "upgrade [version] [flags]" msgstr "actualizar [version] [flags]" @@ -5583,7 +5663,7 @@ msgid "upgrade [flags]" msgstr "actualizar [flags]" #. translators: `app upgrade` command -#: cli/updater/updater.go:85 +#: cli/updater/updater.go:86 msgid "upgrade [[stack] [recipe] | --all] [flags]" msgstr "actualizar [[stack] [recipe] | --all] [flags]" @@ -5676,7 +5756,7 @@ msgstr "" msgid "version %s saved to %s.env" msgstr "" -#: cli/app/deploy.go:116 +#: cli/app/deploy.go:115 #, c-format msgid "" "version '%s' appears to be a chaos commit, but --chaos/-C was not provided" @@ -5701,32 +5781,32 @@ msgstr "" msgid "version wiped from %s.env" msgstr "" -#: cli/app/deploy.go:318 +#: cli/app/deploy.go:335 #, c-format msgid "version: can not redeploy chaos version %s" msgstr "" -#: cli/app/deploy.go:305 +#: cli/app/deploy.go:322 #, c-format msgid "version: taking chaos version: %s" msgstr "" -#: cli/app/deploy.go:326 +#: cli/app/deploy.go:343 #, c-format msgid "version: taking deployed version: %s" msgstr "" -#: cli/app/deploy.go:331 +#: cli/app/deploy.go:348 #, c-format msgid "version: taking new recipe version: %s" msgstr "" -#: cli/app/deploy.go:320 +#: cli/app/deploy.go:337 #, c-format msgid "version: taking version from .env file: %s" msgstr "" -#: cli/app/deploy.go:311 +#: cli/app/deploy.go:328 #, c-format msgid "version: taking version from cli arg: %s" msgstr "" @@ -5852,8 +5932,8 @@ msgstr "" msgid "writer: %v, " msgstr "" -#: cli/app/deploy.go:243 cli/app/new.go:221 cli/app/rollback.go:232 -#: cli/app/undeploy.go:111 cli/app/upgrade.go:278 +#: cli/app/deploy.go:260 cli/app/new.go:221 cli/app/rollback.go:248 +#: cli/app/undeploy.go:114 cli/app/upgrade.go:294 #, c-format msgid "writing recipe version failed: %s" msgstr "" -- 2.49.0