feat!: abra app env pull
#708
307
cli/app/env.go
307
cli/app/env.go
@ -1,28 +1,50 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"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"
|
||||
containerPkg "coopcloud.tech/abra/pkg/container"
|
||||
contextPkg "coopcloud.tech/abra/pkg/context"
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
"coopcloud.tech/abra/pkg/i18n"
|
||||
"coopcloud.tech/abra/pkg/log"
|
||||
"coopcloud.tech/abra/pkg/upstream/stack"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// translators: `abra app env` aliases. use a comma separated list of aliases with
|
||||
// no spaces in between
|
||||
// translators: `abra app env` aliases. use a comma separated list of aliases
|
||||
// with no spaces in between
|
||||
var appEnvAliases = i18n.G("e")
|
||||
|
||||
var AppEnvCommand = &cobra.Command{
|
||||
// translators: `app env` command
|
||||
Use: i18n.G("env <domain> [flags]"),
|
||||
Aliases: strings.Split(appEnvAliases, ","),
|
||||
// translators: Short description for `app env` command
|
||||
Short: i18n.G("Show app .env values"),
|
||||
Example: i18n.G(" abra app env 1312.net"),
|
||||
// translators: `abra app env list` aliases. use a comma separated list of
|
||||
// aliases with no spaces in between
|
||||
var appEnvListAliases = i18n.G("l,ls")
|
||||
|
||||
// translators: `abra app env pull` aliases. use a comma separated list of
|
||||
// aliases with no spaces in between
|
||||
var appEnvPullAliases = i18n.G("pl,p")
|
||||
|
||||
var AppEnvListCommand = &cobra.Command{
|
||||
// translators: `app env list` command
|
||||
Use: i18n.G("list <domain> [flags]"),
|
||||
Aliases: strings.Split(appEnvListAliases, ","),
|
||||
// translators: Short description for `app env list` command
|
||||
Short: i18n.G("List all app environment values"),
|
||||
Example: i18n.G(" abra app env list 1312.net"),
|
||||
Args: cobra.ExactArgs(1),
|
||||
ValidArgsFunction: func(
|
||||
cmd *cobra.Command,
|
||||
@ -49,3 +71,270 @@ var AppEnvCommand = &cobra.Command{
|
||||
fmt.Println(overview)
|
||||
},
|
||||
}
|
||||
|
||||
var AppEnvPullCommand = &cobra.Command{
|
||||
// translators: `app pull` command
|
||||
Use: i18n.G("pull <domain> [flags]"),
|
||||
Aliases: strings.Split(appEnvPullAliases, ","),
|
||||
// translators: Short description for `app env pull` command
|
||||
Short: i18n.G("Pull app environment values from a deployed app"),
|
||||
Long: i18n.G(`Pull app environment values from a deploymed app.
|
||||
|
||||
A convenient command for when you've lost your app environment file or want to
|
||||
synchronize your local app environment values with what is deployed live.`),
|
||||
Example: i18n.G(` # pull existing .env file and overwrite local values
|
||||
abra app env pull 1312.net --force
|
||||
|
||||
# pull lost app .env file
|
||||
abra app env pull my.gitea.net --server 1312.net`),
|
||||
Args: cobra.MaximumNArgs(2),
|
||||
ValidArgsFunction: func(
|
||||
cmd *cobra.Command,
|
||||
args []string,
|
||||
toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
return autocomplete.AppNameComplete()
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
appName := args[0]
|
||||
|
||||
appEnvPath := path.Join(config.ABRA_DIR, "servers", server, fmt.Sprintf("%s.env", appName))
|
||||
if _, err := os.Stat(appEnvPath); !os.IsNotExist(err) {
|
||||
log.Fatal(i18n.G("%s already exists?", appEnvPath))
|
||||
}
|
||||
|
||||
if server == "" {
|
||||
log.Fatal(i18n.G("unable to determine server of app %s, please pass --server/-s", appName))
|
||||
}
|
||||
|
||||
serverDir := filepath.Join(config.SERVERS_DIR, server)
|
||||
if _, err := os.Stat(serverDir); os.IsNotExist(err) {
|
||||
log.Fatal(i18n.G("unknown server %s, run \"abra server add %s\"?", server, server))
|
||||
}
|
||||
|
||||
store := contextPkg.NewDefaultDockerContextStore()
|
||||
contexts, err := store.Store.List()
|
||||
if err != nil {
|
||||
log.Fatal(i18n.G("unable to look up server context for %s: %s", server, err))
|
||||
}
|
||||
|
||||
var contextCreated bool
|
||||
for _, context := range contexts {
|
||||
if context.Name == server || server == "default" {
|
||||
contextCreated = true
|
||||
}
|
||||
}
|
||||
|
||||
if !contextCreated {
|
||||
log.Fatal(i18n.G("%s missing context, run \"abra server add %s\"?", server, server))
|
||||
}
|
||||
|
||||
cl, err := client.New(server)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
deployMeta, err := stack.IsDeployed(context.Background(), cl, appPkg.StackName(appName))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if !deployMeta.IsDeployed {
|
||||
log.Fatal(i18n.G("%s is not deployed?", appName))
|
||||
}
|
||||
|
||||
filters := filters.NewArgs()
|
||||
filters.Add("name", fmt.Sprintf("^%s_%s", app.StackName(appName), "app"))
|
||||
targetContainer, err := containerPkg.GetContainer(context.Background(), cl, filters, internal.NoInput)
|
||||
if err != nil {
|
||||
log.Fatal(i18n.G("unable to retrieve container for %s: %s", appName, err))
|
||||
}
|
||||
|
||||
inspectResult, err := cl.ContainerInspect(context.Background(), targetContainer.ID)
|
||||
if err != nil {
|
||||
log.Fatal(i18n.G("unable to inspect container for %s: %s", appName, err))
|
||||
}
|
||||
|
||||
deploymentEnv := make(map[string]string)
|
||||
for _, envVar := range inspectResult.Config.Env {
|
||||
split := strings.SplitN(envVar, "=", 2)
|
||||
if len(split) != 2 {
|
||||
log.Debug(i18n.G("no value attached to %s", envVar))
|
||||
continue
|
||||
}
|
||||
|
||||
key, val := split[0], split[1]
|
||||
deploymentEnv[key] = val
|
||||
}
|
||||
|
||||
log.Debug(i18n.G("pulled env values from %s deployment: %s", appName, deploymentEnv))
|
||||
|
||||
var (
|
||||
recipeEnvVar string
|
||||
recipeKey string
|
||||
)
|
||||
|
||||
if r, ok := deploymentEnv["TYPE"]; ok {
|
||||
recipeKey = "TYPE"
|
||||
recipeEnvVar = r
|
||||
}
|
||||
|
||||
if r, ok := deploymentEnv["RECIPE"]; ok {
|
||||
recipeKey = "RECIPE"
|
||||
recipeEnvVar = r
|
||||
}
|
||||
|
||||
if recipeEnvVar == "" {
|
||||
log.Fatal(i18n.G("unable to determine recipe type from %s, env: %v", appName, inspectResult.Config.Env))
|
||||
}
|
||||
|
||||
var recipeName = recipeEnvVar
|
||||
if strings.Contains(recipeEnvVar, ":") {
|
||||
split := strings.Split(recipeEnvVar, ":")
|
||||
recipeName = split[0]
|
||||
}
|
||||
|
||||
recipe := internal.ValidateRecipe(
|
||||
[]string{recipeName},
|
||||
cmd.Name(),
|
||||
)
|
||||
|
||||
version := deployMeta.Version
|
||||
if deployMeta.IsChaos {
|
||||
version = deployMeta.ChaosVersion
|
||||
}
|
||||
|
||||
if _, err := recipe.EnsureVersion(version); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
mergedEnv, err := recipe.SampleEnv()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Debug(i18n.G("retrieved env values from .env.sample of %s: %s", recipe.Name, mergedEnv))
|
||||
|
||||
for k, v := range deploymentEnv {
|
||||
mergedEnv[k] = v
|
||||
}
|
||||
|
||||
if !strings.Contains(recipeEnvVar, ":") {
|
||||
mergedEnv[recipeKey] = fmt.Sprintf("%s:%s", mergedEnv[recipeKey], version)
|
||||
}
|
||||
|
||||
log.Debug(i18n.G("final merged env values for %s are: %s", appName, mergedEnv))
|
||||
|
||||
envSample, err := os.ReadFile(recipe.SampleEnvPath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
err = os.WriteFile(appEnvPath, envSample, 0o664)
|
||||
if err != nil {
|
||||
log.Fatal(i18n.G("unable to write new env %s: %s", appEnvPath, err))
|
||||
}
|
||||
|
||||
read, err := os.ReadFile(appEnvPath)
|
||||
if err != nil {
|
||||
log.Fatal(i18n.G("unable to read new env %s: %s", appEnvPath, err))
|
||||
}
|
||||
|
||||
sampleEnv, err := recipe.SampleEnv()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
var composeFileUpdated bool
|
||||
newContents := string(read)
|
||||
for key, val := range mergedEnv {
|
||||
if sampleEnv[key] == val {
|
||||
continue
|
||||
}
|
||||
|
||||
if key == "COMPOSE_FILE" {
|
||||
composeFileUpdated = true
|
||||
continue
|
||||
}
|
||||
|
||||
if m, _ := regexp.MatchString(fmt.Sprintf(`#%s=`, key), newContents); m {
|
||||
log.Debug(i18n.G("uncommenting %s", key))
|
||||
re := regexp.MustCompile(fmt.Sprintf(`#%s=`, key))
|
||||
newContents = re.ReplaceAllString(newContents, fmt.Sprintf("%s=", key))
|
||||
}
|
||||
|
||||
if m, _ := regexp.MatchString(fmt.Sprintf(`# %s=`, key), newContents); m {
|
||||
log.Debug(i18n.G("uncommenting %s", key))
|
||||
re := regexp.MustCompile(fmt.Sprintf(`# %s=`, key))
|
||||
newContents = re.ReplaceAllString(newContents, fmt.Sprintf("%s=", key))
|
||||
}
|
||||
|
||||
if m, _ := regexp.MatchString(fmt.Sprintf(`%s=".*"`, key), newContents); m {
|
||||
log.Debug(i18n.G(`inserting %s="%s" (double quotes)`, key, val))
|
||||
re := regexp.MustCompile(fmt.Sprintf(`%s=".*"`, key))
|
||||
newContents = re.ReplaceAllString(newContents, fmt.Sprintf(`%s="%s"`, key, val))
|
||||
continue
|
||||
}
|
||||
|
||||
if m, _ := regexp.MatchString(fmt.Sprintf(`%s='.*'`, key), newContents); m {
|
||||
log.Debug(i18n.G(`inserting %s='%s' (single quotes)`, key, val))
|
||||
re := regexp.MustCompile(fmt.Sprintf(`%s='.*'`, key))
|
||||
newContents = re.ReplaceAllString(newContents, fmt.Sprintf(`%s='%s'`, key, val))
|
||||
continue
|
||||
}
|
||||
|
||||
if m, _ := regexp.MatchString(fmt.Sprintf("%s=.*", key), newContents); m {
|
||||
log.Debug(i18n.G("inserting %s=%s (no quotes)", key, val))
|
||||
re := regexp.MustCompile(fmt.Sprintf("%s=.*", key))
|
||||
newContents = re.ReplaceAllString(newContents, fmt.Sprintf("%s=%s", key, val))
|
||||
}
|
||||
}
|
||||
|
||||
err = os.WriteFile(appEnvPath, []byte(newContents), 0)
|
||||
if err != nil {
|
||||
log.Fatal(i18n.G("unable to write new env %s: %s", appEnvPath, err))
|
||||
}
|
||||
|
||||
log.Info(i18n.G("%s successfully created", appEnvPath))
|
||||
|
||||
if composeFileUpdated {
|
||||
log.Warn(i18n.G("manual update required: COMPOSE_FILE=\"%s\"", mergedEnv["COMPOSE_FILE"]))
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
var AppEnvCommand = &cobra.Command{
|
||||
// translators: `app env` command group
|
||||
Use: i18n.G("env [cmd] [args] [flags]"),
|
||||
Aliases: strings.Split(appEnvAliases, ","),
|
||||
// translators: Short description for `app env` command group
|
||||
Short: i18n.G("Manage app environment values"),
|
||||
}
|
||||
|
||||
var (
|
||||
server string
|
||||
)
|
||||
|
||||
func init() {
|
||||
AppEnvPullCommand.Flags().BoolVarP(
|
||||
&internal.Force,
|
||||
i18n.G("force"),
|
||||
i18n.G("f"),
|
||||
false,
|
||||
i18n.G("perform action without further prompt"),
|
||||
)
|
||||
|
||||
AppEnvPullCommand.Flags().StringVarP(
|
||||
&server,
|
||||
i18n.G("server"),
|
||||
i18n.G("s"),
|
||||
"",
|
||||
i18n.G("server associated with deployed app"),
|
||||
)
|
||||
|
||||
AppEnvPullCommand.RegisterFlagCompletionFunc(
|
||||
i18n.G("server"),
|
||||
func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
return autocomplete.ServerNameComplete()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ var AppUndeployCommand = &cobra.Command{
|
||||
Use: i18n.G("undeploy <domain> [flags]"),
|
||||
// translators: Short description for `app undeploy` command
|
||||
Aliases: strings.Split(appUndeployAliases, ","),
|
||||
Short: i18n.G("Undeploy a deployed app"),
|
||||
Long: i18n.G(`This does not destroy any application data.
|
||||
|
||||
However, you should remain vigilant, as your swarm installation will consider
|
||||
|
||||
@ -283,6 +283,11 @@ Config:
|
||||
app.AppBackupSnapshotsCommand,
|
||||
)
|
||||
|
||||
app.AppEnvCommand.AddCommand(
|
||||
app.AppEnvListCommand,
|
||||
app.AppEnvPullCommand,
|
||||
)
|
||||
|
||||
app.AppCommand.AddCommand(
|
||||
app.AppBackupCommand,
|
||||
app.AppCheckCommand,
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
msgid ""
|
||||
msgstr "Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2025-10-23 09:14+0200\n"
|
||||
"POT-Creation-Date: 2025-10-31 21:31+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@ -92,6 +92,14 @@ msgid " # pass <cmd> args/flags without \"--\"\n"
|
||||
" abra app cmd 1312.net my_cmd --local"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/env.go:85
|
||||
msgid " # pull existing .env file and overwrite local values\n"
|
||||
" abra app env pull 1312.net --force\n"
|
||||
"\n"
|
||||
" # pull lost app .env file\n"
|
||||
" abra app env pull my.gitea.net --server 1312.net"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/restart.go:36
|
||||
msgid " # restart a single app service\n"
|
||||
" abra app restart 1312.net app\n"
|
||||
@ -125,8 +133,8 @@ msgid " # standard deployment\n"
|
||||
" abra app deploy 1312.net 886db76d"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/env.go:25
|
||||
msgid " abra app env 1312.net"
|
||||
#: ./cli/app/env.go:47
|
||||
msgid " abra app env list 1312.net"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/remove.go:45
|
||||
@ -201,7 +209,7 @@ msgstr ""
|
||||
msgid "%s already exists"
|
||||
msgstr ""
|
||||
|
||||
#: ./pkg/app/app.go:380
|
||||
#: ./cli/app/env.go:102 ./pkg/app/app.go:380
|
||||
#, c-format
|
||||
msgid "%s already exists?"
|
||||
msgstr ""
|
||||
@ -341,7 +349,7 @@ msgstr ""
|
||||
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:447
|
||||
#: ./cli/app/env.go:142 ./cli/app/logs.go:65 ./cli/app/ps.go:62 ./cli/app/restart.go:100 ./cli/app/services.go:55 ./cli/app/undeploy.go:66 ./cli/app/upgrade.go:447
|
||||
#, c-format
|
||||
msgid "%s is not deployed?"
|
||||
msgstr ""
|
||||
@ -356,6 +364,11 @@ msgstr ""
|
||||
msgid "%s is still deployed. Run \"abra app undeploy %s\""
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/env.go:128
|
||||
#, c-format
|
||||
msgid "%s missing context, run \"abra server add %s\"?"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/deploy.go:182 ./cli/app/upgrade.go:208
|
||||
#, c-format
|
||||
msgid "%s missing from %s.env"
|
||||
@ -421,6 +434,11 @@ msgstr ""
|
||||
msgid "%s successfully added"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/env.go:297
|
||||
#, c-format
|
||||
msgid "%s successfully created"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/secret.go:254
|
||||
#, c-format
|
||||
msgid "%s successfully stored on server"
|
||||
@ -794,7 +812,7 @@ msgid "Downloads a backup.tar.gz to the current working directory.\n"
|
||||
"\"backupbot.backup.path\" labels."
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/env.go:48
|
||||
#: ./cli/app/env.go:70
|
||||
msgid "ENV OVERVIEW"
|
||||
msgstr ""
|
||||
|
||||
@ -939,6 +957,11 @@ msgstr ""
|
||||
msgid "Lint a recipe"
|
||||
msgstr ""
|
||||
|
||||
#. translators: Short description for `app env list` command
|
||||
#: ./cli/app/env.go:46
|
||||
msgid "List all app environment values"
|
||||
msgstr ""
|
||||
|
||||
#. translators: Short description for `app cmd list` command
|
||||
#: ./cli/app/cmd.go:210
|
||||
msgid "List all available commands"
|
||||
@ -993,6 +1016,11 @@ msgstr ""
|
||||
msgid "Manage app backups"
|
||||
msgstr ""
|
||||
|
||||
#. translators: Short description for `app env` command group
|
||||
#: ./cli/app/env.go:310
|
||||
msgid "Manage app environment values"
|
||||
msgstr ""
|
||||
|
||||
#. translators: Short description for `app secret` command group
|
||||
#: ./cli/app/secret.go:537
|
||||
msgid "Manage app secrets"
|
||||
@ -1099,6 +1127,18 @@ msgid "Prunes unused containers, networks, and dangling images.\n"
|
||||
"app. This can result in unwanted data loss if not used carefully."
|
||||
msgstr ""
|
||||
|
||||
#. translators: Short description for `app env pull` command
|
||||
#: ./cli/app/env.go:80
|
||||
msgid "Pull app environment values from a deployed app"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/env.go:81
|
||||
msgid "Pull app environment values from a deploymed app.\n"
|
||||
"\n"
|
||||
"A convenient command for when you've lost your app environment file or want to\n"
|
||||
"synchronize your local app environment values with what is deployed live."
|
||||
msgstr ""
|
||||
|
||||
#: ./pkg/lint/recipe.go:110
|
||||
msgid "README.md metadata filled in"
|
||||
msgstr ""
|
||||
@ -1268,11 +1308,6 @@ msgstr ""
|
||||
msgid "Select recipe"
|
||||
msgstr ""
|
||||
|
||||
#. translators: Short description for `app env` command
|
||||
#: ./cli/app/env.go:24
|
||||
msgid "Show app .env values"
|
||||
msgstr ""
|
||||
|
||||
#. translators: Short description for `app labels` command
|
||||
#: ./cli/app/labels.go:32
|
||||
msgid "Show deployment labels"
|
||||
@ -1387,7 +1422,7 @@ msgid "This command rolls an app back to a previous version.\n"
|
||||
"beforehand. See \"abra app backup\" for more."
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/undeploy.go:31
|
||||
#: ./cli/app/undeploy.go:32
|
||||
msgid "This does not destroy any application data.\n"
|
||||
"\n"
|
||||
"However, you should remain vigilant, as your swarm installation will consider\n"
|
||||
@ -1450,6 +1485,10 @@ msgstr ""
|
||||
msgid "UPGRADE"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/undeploy.go:31
|
||||
msgid "Undeploy a deployed app"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/recipe/upgrade.go:50
|
||||
msgid "Upgrade a given <recipe> configuration.\n"
|
||||
"\n"
|
||||
@ -2029,7 +2068,7 @@ msgstr ""
|
||||
msgid "check <domain> [flags]"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/deploy.go:94 ./cli/app/undeploy.go:57 ./cli/app/upgrade.go:439
|
||||
#: ./cli/app/deploy.go:94 ./cli/app/undeploy.go:58 ./cli/app/upgrade.go:439
|
||||
#, c-format
|
||||
msgid "checking whether %s is already deployed"
|
||||
msgstr ""
|
||||
@ -2180,7 +2219,7 @@ msgstr ""
|
||||
msgid "considering %s config(s) for tag update"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/undeploy.go:140 ./cli/server/prune.go:53
|
||||
#: ./cli/app/undeploy.go:141 ./cli/server/prune.go:53
|
||||
#, c-format
|
||||
msgid "containers pruned: %d; space reclaimed: %s"
|
||||
msgstr ""
|
||||
@ -2567,9 +2606,9 @@ msgstr ""
|
||||
msgid "duplicate secret target for %s not allowed"
|
||||
msgstr ""
|
||||
|
||||
#. translators: `abra app env` aliases. use a comma separated list of aliases with
|
||||
#. no spaces in between
|
||||
#: ./cli/app/env.go:17 ./cli/recipe/lint.go:145 ./cli/recipe/new.go:131
|
||||
#. translators: `abra app env` aliases. use a comma separated list of aliases
|
||||
#. with no spaces in between
|
||||
#: ./cli/app/env.go:31 ./cli/recipe/lint.go:145 ./cli/recipe/new.go:131
|
||||
msgid "e"
|
||||
msgstr ""
|
||||
|
||||
@ -2608,9 +2647,9 @@ msgstr ""
|
||||
msgid "enter / return to confirm, choose 'skip' to not upgrade this tag, vim mode is enabled"
|
||||
msgstr ""
|
||||
|
||||
#. translators: `app env` command
|
||||
#: ./cli/app/env.go:21
|
||||
msgid "env <domain> [flags]"
|
||||
#. translators: `app env` command group
|
||||
#: ./cli/app/env.go:307
|
||||
msgid "env [cmd] [args] [flags]"
|
||||
msgstr ""
|
||||
|
||||
#: ./pkg/app/app.go:248
|
||||
@ -2687,7 +2726,7 @@ msgstr ""
|
||||
|
||||
#. translators: `abra recipe fetch` aliases. use a comma separated list of aliases
|
||||
#. with no spaces in between
|
||||
#: ./cli/app/deploy.go:401 ./cli/app/remove.go:163 ./cli/app/rollback.go:349 ./cli/app/secret.go:593 ./cli/app/upgrade.go:459 ./cli/app/volume.go:217 ./cli/recipe/fetch.go:20 ./cli/recipe/fetch.go:138
|
||||
#: ./cli/app/deploy.go:401 ./cli/app/env.go:321 ./cli/app/remove.go:163 ./cli/app/rollback.go:349 ./cli/app/secret.go:593 ./cli/app/upgrade.go:459 ./cli/app/volume.go:217 ./cli/recipe/fetch.go:20 ./cli/recipe/fetch.go:138
|
||||
msgid "f"
|
||||
msgstr ""
|
||||
|
||||
@ -2913,7 +2952,12 @@ msgstr ""
|
||||
msgid "filter by recipe"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/deploy.go:400 ./cli/app/remove.go:162 ./cli/app/rollback.go:348 ./cli/app/upgrade.go:458 ./cli/app/volume.go:216 ./cli/recipe/fetch.go:137
|
||||
#: ./cli/app/env.go:225
|
||||
#, c-format
|
||||
msgid "final merged env values for %s are: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/deploy.go:400 ./cli/app/env.go:320 ./cli/app/remove.go:162 ./cli/app/rollback.go:348 ./cli/app/upgrade.go:458 ./cli/app/volume.go:216 ./cli/recipe/fetch.go:137
|
||||
msgid "force"
|
||||
msgstr ""
|
||||
|
||||
@ -3131,7 +3175,7 @@ msgstr ""
|
||||
msgid "ignore uncommitted recipes changes"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/undeploy.go:155 ./cli/server/prune.go:74
|
||||
#: ./cli/app/undeploy.go:156 ./cli/server/prune.go:74
|
||||
#, c-format
|
||||
msgid "images pruned: %d; space reclaimed: %s"
|
||||
msgstr ""
|
||||
@ -3251,6 +3295,21 @@ msgstr ""
|
||||
msgid "insert <domain> <secret> <version> [<data>] [flags]"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/env.go:286
|
||||
#, c-format
|
||||
msgid "inserting %s=%s (no quotes)"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/env.go:279
|
||||
#, c-format
|
||||
msgid "inserting %s='%s' (single quotes)"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/env.go:272
|
||||
#, c-format
|
||||
msgid "inserting %s=\"%s\" (double quotes)"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/upgrade.go:62
|
||||
msgid "install release candidate (may contain bugs)"
|
||||
msgstr ""
|
||||
@ -3314,6 +3373,12 @@ msgstr ""
|
||||
msgid "l"
|
||||
msgstr ""
|
||||
|
||||
#. translators: `abra app env list` aliases. use a comma separated list of
|
||||
#. aliases with no spaces in between
|
||||
#: ./cli/app/env.go:35
|
||||
msgid "l,ls"
|
||||
msgstr ""
|
||||
|
||||
#. translators: `app labels` command
|
||||
#: ./cli/app/labels.go:29
|
||||
msgid "labels <domain> [flags]"
|
||||
@ -3361,8 +3426,9 @@ msgstr ""
|
||||
|
||||
#. translators: `app backup list` command
|
||||
#. translators: `app cmd list` command
|
||||
#. translators: `app env list` command
|
||||
#. translators: `app volume list` command
|
||||
#: ./cli/app/backup.go:21 ./cli/app/cmd.go:207 ./cli/app/volume.go:25
|
||||
#: ./cli/app/backup.go:21 ./cli/app/cmd.go:207 ./cli/app/env.go:43 ./cli/app/volume.go:25
|
||||
msgid "list <domain> [flags]"
|
||||
msgstr ""
|
||||
|
||||
@ -3474,6 +3540,11 @@ msgstr ""
|
||||
msgid "man [flags]"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/env.go:300
|
||||
#, c-format
|
||||
msgid "manual update required: COMPOSE_FILE=\"%s\""
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/move.go:200
|
||||
#, c-format
|
||||
msgid "migrating app config from %s to %s"
|
||||
@ -3553,7 +3624,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:147 ./cli/server/prune.go:60
|
||||
#: ./cli/app/undeploy.go:148 ./cli/server/prune.go:60
|
||||
#, c-format
|
||||
msgid "networks pruned: %d"
|
||||
msgstr ""
|
||||
@ -3744,6 +3815,11 @@ msgstr ""
|
||||
msgid "no unstable tags"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/env.go:161
|
||||
#, c-format
|
||||
msgid "no value attached to %s"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/internal/recipe.go:72 ./cli/internal/recipe.go:87
|
||||
msgid "no version bump type specififed?"
|
||||
msgstr ""
|
||||
@ -3838,7 +3914,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:381 ./cli/app/ps.go:29 ./cli/app/secret.go:561 ./cli/app/secret.go:585 ./cli/app/secret.go:625 ./cli/app/undeploy.go:168 ./cli/catalogue/catalogue.go:294 ./cli/recipe/list.go:112 ./cli/recipe/release.go:681 ./cli/server/prune.go:18
|
||||
#: ./cli/app/backup.go:295 ./cli/app/new.go:381 ./cli/app/ps.go:29 ./cli/app/secret.go:561 ./cli/app/secret.go:585 ./cli/app/secret.go:625 ./cli/app/undeploy.go:169 ./cli/catalogue/catalogue.go:294 ./cli/recipe/list.go:112 ./cli/recipe/release.go:681 ./cli/server/prune.go:18
|
||||
msgid "p"
|
||||
msgstr ""
|
||||
|
||||
@ -3897,10 +3973,16 @@ msgstr ""
|
||||
msgid "pattern"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/deploy.go:403 ./cli/app/remove.go:165 ./cli/app/rollback.go:351 ./cli/app/upgrade.go:461 ./cli/app/volume.go:219
|
||||
#: ./cli/app/deploy.go:403 ./cli/app/env.go:323 ./cli/app/remove.go:165 ./cli/app/rollback.go:351 ./cli/app/upgrade.go:461 ./cli/app/volume.go:219
|
||||
msgid "perform action without further prompt"
|
||||
msgstr ""
|
||||
|
||||
#. translators: `abra app env pull` aliases. use a comma separated list of
|
||||
#. aliases with no spaces in between
|
||||
#: ./cli/app/env.go:39
|
||||
msgid "pl,p"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/recipe/release.go:634
|
||||
#, c-format
|
||||
msgid "please fix your synced label for %s and re-run this command"
|
||||
@ -3960,7 +4042,7 @@ msgstr ""
|
||||
msgid "proposed images: %v"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/undeploy.go:167
|
||||
#: ./cli/app/undeploy.go:168
|
||||
msgid "prune"
|
||||
msgstr ""
|
||||
|
||||
@ -3969,7 +4051,7 @@ msgstr ""
|
||||
msgid "prune <server> [flags]"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/undeploy.go:170
|
||||
#: ./cli/app/undeploy.go:171
|
||||
msgid "prune unused containers, networks, and dangling images"
|
||||
msgstr ""
|
||||
|
||||
@ -3994,6 +4076,16 @@ msgstr ""
|
||||
msgid "publish new release?"
|
||||
msgstr ""
|
||||
|
||||
#. translators: `app pull` command
|
||||
#: ./cli/app/env.go:77
|
||||
msgid "pull <domain> [flags]"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/env.go:169
|
||||
#, c-format
|
||||
msgid "pulled env values from %s deployment: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ./pkg/app/app.go:429
|
||||
msgid "querying remote servers..."
|
||||
msgstr ""
|
||||
@ -4340,6 +4432,11 @@ msgstr ""
|
||||
msgid "retrieved app statuses: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/env.go:215
|
||||
#, c-format
|
||||
msgid "retrieved env values from .env.sample of %s: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/recipe/version.go:46
|
||||
msgid "retrieved versions from local recipe repository"
|
||||
msgstr ""
|
||||
@ -4460,7 +4557,7 @@ msgstr ""
|
||||
#. aliases with no spaces in between
|
||||
#. translators: `abra server` aliases. use a comma separated list of aliases
|
||||
#. with no spaces in between
|
||||
#: ./cli/app/backup.go:198 ./cli/app/backup.go:263 ./cli/app/backup.go:287 ./cli/app/list.go:323 ./cli/app/logs.go:101 ./cli/app/new.go:358 ./cli/app/restore.go:114 ./cli/app/secret.go:535 ./cli/catalogue/catalogue.go:27 ./cli/catalogue/catalogue.go:310 ./cli/recipe/fetch.go:130 ./cli/recipe/sync.go:24 ./cli/server/server.go:12
|
||||
#: ./cli/app/backup.go:198 ./cli/app/backup.go:263 ./cli/app/backup.go:287 ./cli/app/env.go:329 ./cli/app/list.go:323 ./cli/app/logs.go:101 ./cli/app/new.go:358 ./cli/app/restore.go:114 ./cli/app/secret.go:535 ./cli/catalogue/catalogue.go:27 ./cli/catalogue/catalogue.go:310 ./cli/recipe/fetch.go:130 ./cli/recipe/sync.go:24 ./cli/server/server.go:12
|
||||
msgid "s"
|
||||
msgstr ""
|
||||
|
||||
@ -4527,7 +4624,7 @@ msgid "secrets are %s shown again, please save them %s"
|
||||
msgstr ""
|
||||
|
||||
#. translators: `abra server` command for autocompletion
|
||||
#: ./cli/app/list.go:322 ./cli/app/list.go:329 ./cli/app/new.go:357 ./cli/app/new.go:364 ./cli/run.go:101
|
||||
#: ./cli/app/env.go:328 ./cli/app/env.go:335 ./cli/app/list.go:322 ./cli/app/list.go:329 ./cli/app/new.go:357 ./cli/app/new.go:364 ./cli/run.go:101
|
||||
msgid "server"
|
||||
msgstr ""
|
||||
|
||||
@ -4541,6 +4638,10 @@ msgstr ""
|
||||
msgid "server [cmd] [args] [flags]"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/env.go:331
|
||||
msgid "server associated with deployed app"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/server/add.go:191
|
||||
#, c-format
|
||||
msgid "server dir for %s already created"
|
||||
@ -5029,6 +5130,16 @@ msgstr ""
|
||||
msgid "unable to delete tag %s: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/env.go:187
|
||||
#, c-format
|
||||
msgid "unable to determine recipe type from %s, env: %v"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/env.go:106
|
||||
#, c-format
|
||||
msgid "unable to determine server of app %s, please pass --server/-s"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/recipe/upgrade.go:253
|
||||
#, c-format
|
||||
msgid "unable to determine versioning semantics of %s, listing all tags"
|
||||
@ -5059,6 +5170,11 @@ msgstr ""
|
||||
msgid "unable to git pull in %s: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/env.go:154
|
||||
#, c-format
|
||||
msgid "unable to inspect container for %s: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ./pkg/lint/recipe.go:496
|
||||
#, c-format
|
||||
msgid "unable to list local tags for %s"
|
||||
@ -5068,6 +5184,11 @@ msgstr ""
|
||||
msgid "unable to locate git command, cannot output diff"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/env.go:117
|
||||
#, c-format
|
||||
msgid "unable to look up server context for %s: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/recipe/fetch.go:77 ./pkg/git/read.go:26 ./pkg/lint/recipe.go:491 ./pkg/recipe/git.go:236
|
||||
#, c-format
|
||||
msgid "unable to open %s: %s"
|
||||
@ -5123,6 +5244,11 @@ msgstr ""
|
||||
msgid "unable to query status of %s: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/env.go:239
|
||||
#, c-format
|
||||
msgid "unable to read new env %s: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ./pkg/recipe/git.go:241
|
||||
#, c-format
|
||||
msgid "unable to read remotes in %s: %s"
|
||||
@ -5173,6 +5299,11 @@ msgstr ""
|
||||
msgid "unable to retrieve %s resources on %s: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/env.go:149
|
||||
#, c-format
|
||||
msgid "unable to retrieve container for %s: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/list.go:153
|
||||
#, c-format
|
||||
msgid "unable to retrieve tags for %s: %s"
|
||||
@ -5203,6 +5334,16 @@ msgstr ""
|
||||
msgid "unable to validate recipe: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/env.go:234 ./cli/app/env.go:294
|
||||
#, c-format
|
||||
msgid "unable to write new env %s: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/env.go:260 ./cli/app/env.go:266
|
||||
#, c-format
|
||||
msgid "uncommenting %s"
|
||||
msgstr ""
|
||||
|
||||
#: ./pkg/upstream/convert/service.go:462
|
||||
#, c-format
|
||||
msgid "undefined config %q"
|
||||
@ -5228,7 +5369,7 @@ msgstr ""
|
||||
msgid "undeploy <domain> [flags]"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/undeploy.go:116
|
||||
#: ./cli/app/undeploy.go:117
|
||||
msgid "undeploy succeeded 🟢"
|
||||
msgstr ""
|
||||
|
||||
@ -5284,6 +5425,11 @@ msgstr ""
|
||||
msgid "unknown restart policy: %s"
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/env.go:111
|
||||
#, c-format
|
||||
msgid "unknown server %s, run \"abra server add %s\"?"
|
||||
msgstr ""
|
||||
|
||||
#: ./pkg/client/client.go:51
|
||||
#, c-format
|
||||
msgid "unknown server, run \"abra server add %s\"?"
|
||||
@ -5584,7 +5730,7 @@ msgstr ""
|
||||
msgid "writer: %v, "
|
||||
msgstr ""
|
||||
|
||||
#: ./cli/app/deploy.go:275 ./cli/app/new.go:241 ./cli/app/rollback.go:252 ./cli/app/undeploy.go:119 ./cli/app/upgrade.go:298
|
||||
#: ./cli/app/deploy.go:275 ./cli/app/new.go:241 ./cli/app/rollback.go:252 ./cli/app/undeploy.go:120 ./cli/app/upgrade.go:298
|
||||
#, c-format
|
||||
msgid "writing recipe version failed: %s"
|
||||
msgstr ""
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -28,17 +28,17 @@ teardown(){
|
||||
}
|
||||
|
||||
@test "validate app argument" {
|
||||
run $ABRA app env
|
||||
run $ABRA app env list
|
||||
assert_failure
|
||||
|
||||
run $ABRA app env DOESNTEXIST
|
||||
run $ABRA app env list DOESNTEXIST
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "show env version" {
|
||||
latestRelease=$(_latest_release)
|
||||
|
||||
run $ABRA app env "$TEST_APP_DOMAIN"
|
||||
run $ABRA app env list "$TEST_APP_DOMAIN"
|
||||
assert_success
|
||||
assert_output --partial "$latestRelease"
|
||||
}
|
||||
@ -48,7 +48,7 @@ teardown(){
|
||||
assert_success
|
||||
assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
|
||||
|
||||
run $ABRA app env "$TEST_APP_DOMAIN"
|
||||
run $ABRA app env list "$TEST_APP_DOMAIN"
|
||||
assert_success
|
||||
|
||||
assert_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
|
||||
@ -57,3 +57,40 @@ teardown(){
|
||||
run rm -rf "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
|
||||
assert_not_exists "$ABRA_DIR/recipes/$TEST_RECIPE/foo"
|
||||
}
|
||||
|
||||
@test "app env pull explodes when no deployed app" {
|
||||
run $ABRA app env pull "$TEST_APP_DOMAIN" -s "$TEST_SERVER"
|
||||
assert_failure
|
||||
}
|
||||
|
||||
# bats test_tags=slow
|
||||
@test "app env pull recreates app env when missing" {
|
||||
run $ABRA app deploy "$TEST_APP_DOMAIN" --no-input
|
||||
assert_success
|
||||
|
||||
run rm -rf "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||
assert_success
|
||||
assert_not_exists "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||
|
||||
run $ABRA app env pull "$TEST_APP_DOMAIN" -s "$TEST_SERVER"
|
||||
assert_success
|
||||
assert_exists "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||
}
|
||||
|
||||
# bats test_tags=slow
|
||||
@test "app env pull recreates correct version" {
|
||||
run $ABRA app deploy "$TEST_APP_DOMAIN" "0.1.0+1.20.0" --no-input
|
||||
assert_success
|
||||
|
||||
run rm -rf "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||
assert_success
|
||||
assert_not_exists "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||
|
||||
run $ABRA app env pull "$TEST_APP_DOMAIN" -s "$TEST_SERVER"
|
||||
assert_success
|
||||
assert_exists "$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||
|
||||
run grep -q "TYPE=$TEST_RECIPE:0.1.0+1.20.0" \
|
||||
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||
assert_success
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user