diff --git a/README.md b/README.md index 5ae21bbe..112d0abb 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![Build Status](https://build.coopcloud.tech/api/badges/toolshed/abra/status.svg?ref=refs/heads/main)](https://build.coopcloud.tech/toolshed/abra) [![Go Report Card](https://goreportcard.com/badge/git.coopcloud.tech/toolshed/abra)](https://goreportcard.com/report/git.coopcloud.tech/toolshed/abra) [![Go Reference](https://pkg.go.dev/badge/coopcloud.tech/abra.svg)](https://pkg.go.dev/coopcloud.tech/abra) +[![Translation status](https://translate.coopcloud.tech/widget/co-op-cloud/svg-badge.svg)](https://translate.coopcloud.tech/engage/co-op-cloud/) The Co-op Cloud utility belt 🎩🐇 diff --git a/cli/app/app.go b/cli/app/app.go index 259dadfc..59f31165 100644 --- a/cli/app/app.go +++ b/cli/app/app.go @@ -1,12 +1,12 @@ package app import ( - "github.com/leonelquinteros/gotext" + "coopcloud.tech/abra/pkg/i18n" "github.com/spf13/cobra" ) var AppCommand = &cobra.Command{ - Use: "app [cmd] [args] [flags]", - Aliases: []string{"a"}, - Short: gotext.Get("Manage apps"), + Use: i18n.G("app [cmd] [args] [flags]"), + Aliases: []string{i18n.G("a")}, + Short: i18n.G("Manage apps"), } diff --git a/cli/app/backup.go b/cli/app/backup.go index 83083172..13d70d7e 100644 --- a/cli/app/backup.go +++ b/cli/app/backup.go @@ -6,14 +6,15 @@ import ( "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/client" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/log" "github.com/spf13/cobra" ) var AppBackupListCommand = &cobra.Command{ - Use: "list [flags]", - Aliases: []string{"ls"}, - Short: "List the contents of a snapshot", + Use: i18n.G("list [flags]"), + Aliases: []string{i18n.G("ls")}, + Short: i18n.G("List the contents of a snapshot"), Args: cobra.ExactArgs(1), ValidArgsFunction: func( cmd *cobra.Command, @@ -40,17 +41,17 @@ var AppBackupListCommand = &cobra.Command{ } if snapshot != "" { - log.Debugf("including SNAPSHOT=%s in backupbot exec invocation", snapshot) + log.Debug(i18n.G("including SNAPSHOT=%s in backupbot exec invocation", snapshot)) execEnv = append(execEnv, fmt.Sprintf("SNAPSHOT=%s", snapshot)) } if showAllPaths { - log.Debugf("including SHOW_ALL=%v in backupbot exec invocation", showAllPaths) + log.Debug(i18n.G("including SHOW_ALL=%v in backupbot exec invocation", showAllPaths)) execEnv = append(execEnv, fmt.Sprintf("SHOW_ALL=%v", showAllPaths)) } if timestamps { - log.Debugf("including TIMESTAMPS=%v in backupbot exec invocation", timestamps) + log.Debug(i18n.G("including TIMESTAMPS=%v in backupbot exec invocation", timestamps)) execEnv = append(execEnv, fmt.Sprintf("TIMESTAMPS=%v", timestamps)) } @@ -61,13 +62,13 @@ var AppBackupListCommand = &cobra.Command{ } var AppBackupDownloadCommand = &cobra.Command{ - Use: "download [flags]", - Aliases: []string{"d"}, - Short: "Download a snapshot", - Long: `Downloads a backup.tar.gz to the current working directory. + Use: i18n.G("download [flags]"), + Aliases: []string{i18n.G("d")}, + Short: i18n.G("Download a snapshot"), + Long: i18n.G(`Downloads a backup.tar.gz to the current working directory. "--volumes/-v" includes data contained in volumes alongide paths specified in -"backupbot.backup.path" labels.`, +"backupbot.backup.path" labels.`), Args: cobra.ExactArgs(1), ValidArgsFunction: func( cmd *cobra.Command, @@ -98,22 +99,22 @@ var AppBackupDownloadCommand = &cobra.Command{ } if snapshot != "" { - log.Debugf("including SNAPSHOT=%s in backupbot exec invocation", snapshot) + log.Debug(i18n.G("including SNAPSHOT=%s in backupbot exec invocation", snapshot)) execEnv = append(execEnv, fmt.Sprintf("SNAPSHOT=%s", snapshot)) } if includePath != "" { - log.Debugf("including INCLUDE_PATH=%s in backupbot exec invocation", includePath) + log.Debug(i18n.G("including INCLUDE_PATH=%s in backupbot exec invocation", includePath)) execEnv = append(execEnv, fmt.Sprintf("INCLUDE_PATH=%s", includePath)) } if includeSecrets { - log.Debugf("including SECRETS=%v in backupbot exec invocation", includeSecrets) + log.Debug(i18n.G("including SECRETS=%v in backupbot exec invocation", includeSecrets)) execEnv = append(execEnv, fmt.Sprintf("SECRETS=%v", includeSecrets)) } if includeVolumes { - log.Debugf("including VOLUMES=%v in backupbot exec invocation", includeVolumes) + log.Debug(i18n.G("including VOLUMES=%v in backupbot exec invocation", includeVolumes)) execEnv = append(execEnv, fmt.Sprintf("VOLUMES=%v", includeVolumes)) } @@ -130,9 +131,9 @@ var AppBackupDownloadCommand = &cobra.Command{ } var AppBackupCreateCommand = &cobra.Command{ - Use: "create [flags]", - Aliases: []string{"c"}, - Short: "Create a new snapshot", + Use: i18n.G("create [flags]"), + Aliases: []string{i18n.G("c")}, + Short: i18n.G("Create a new snapshot"), Args: cobra.ExactArgs(1), ValidArgsFunction: func( cmd *cobra.Command, @@ -163,7 +164,7 @@ var AppBackupCreateCommand = &cobra.Command{ } if retries != "" { - log.Debugf("including RETRIES=%s in backupbot exec invocation", retries) + log.Debug(i18n.G("including RETRIES=%s in backupbot exec invocation", retries)) execEnv = append(execEnv, fmt.Sprintf("RETRIES=%s", retries)) } @@ -174,9 +175,9 @@ var AppBackupCreateCommand = &cobra.Command{ } var AppBackupSnapshotsCommand = &cobra.Command{ - Use: "snapshots [flags]", - Aliases: []string{"s"}, - Short: "List all snapshots", + Use: i18n.G("snapshots [flags]"), + Aliases: []string{i18n.G("s")}, + Short: i18n.G("List all snapshots"), Args: cobra.ExactArgs(1), ValidArgsFunction: func( cmd *cobra.Command, @@ -209,9 +210,9 @@ var AppBackupSnapshotsCommand = &cobra.Command{ } var AppBackupCommand = &cobra.Command{ - Use: "backup [cmd] [args] [flags]", - Aliases: []string{"b"}, - Short: "Manage app backups", + Use: i18n.G("backup [cmd] [args] [flags]"), + Aliases: []string{i18n.G("b")}, + Short: i18n.G("Manage app backups"), } var ( @@ -227,81 +228,81 @@ var ( func init() { AppBackupListCommand.Flags().StringVarP( &snapshot, - "snapshot", - "s", + i18n.G("snapshot"), + i18n.G("s"), "", - "list specific snapshot", + i18n.G("list specific snapshot"), ) AppBackupListCommand.Flags().BoolVarP( &showAllPaths, - "all", - "a", + i18n.G("all"), + i18n.G("a"), false, - "show all paths", + i18n.G("show all paths"), ) AppBackupListCommand.Flags().BoolVarP( ×tamps, - "timestamps", - "t", + i18n.G("timestamps"), + i18n.G("t"), false, - "include timestamps", + i18n.G("include timestamps"), ) AppBackupDownloadCommand.Flags().StringVarP( &snapshot, - "snapshot", - "s", + i18n.G("snapshot"), + i18n.G("s"), "", - "list specific snapshot", + i18n.G("list specific snapshot"), ) AppBackupDownloadCommand.Flags().StringVarP( &includePath, - "path", - "p", + i18n.G("path"), + i18n.G("p"), "", - "volumes path", + i18n.G("volumes path"), ) AppBackupDownloadCommand.Flags().BoolVarP( &includeSecrets, - "secrets", - "S", + i18n.G("secrets"), + i18n.G("S"), false, - "include secrets", + i18n.G("include secrets"), ) AppBackupDownloadCommand.Flags().BoolVarP( &includeVolumes, - "volumes", - "v", + i18n.G("volumes"), + i18n.G("v"), false, - "include volumes", + i18n.G("include volumes"), ) AppBackupDownloadCommand.Flags().BoolVarP( &internal.Chaos, - "chaos", - "C", + i18n.G("chaos"), + i18n.G("C"), false, - "ignore uncommitted recipes changes", + i18n.G("ignore uncommitted recipes changes"), ) AppBackupCreateCommand.Flags().StringVarP( &retries, - "retries", - "r", + i18n.G("retries"), + i18n.G("r"), "1", - "number of retry attempts", + i18n.G("number of retry attempts"), ) AppBackupCreateCommand.Flags().BoolVarP( &internal.Chaos, - "chaos", - "C", + i18n.G("chaos"), + i18n.G("C"), false, - "ignore uncommitted recipes changes", + i18n.G("ignore uncommitted recipes changes"), ) } diff --git a/cli/app/check.go b/cli/app/check.go index dde31b93..fab92047 100644 --- a/cli/app/check.go +++ b/cli/app/check.go @@ -7,16 +7,17 @@ import ( appPkg "coopcloud.tech/abra/pkg/app" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/formatter" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/log" "github.com/charmbracelet/lipgloss" "github.com/spf13/cobra" ) var AppCheckCommand = &cobra.Command{ - Use: "check [flags]", - Aliases: []string{"chk"}, - Short: "Ensure an app is well configured", - Long: `Compare env vars in both the app ".env" and recipe ".env.sample" file. + Use: i18n.G("check [flags]"), + Aliases: []string{i18n.G("chk")}, + Short: i18n.G("Ensure an app is well configured"), + Long: i18n.G(`Compare env vars in both the app ".env" and recipe ".env.sample" file. The goal is to ensure that recipe ".env.sample" env vars are defined in your app ".env" file. Only env var definitions in the ".env.sample" which are @@ -25,7 +26,7 @@ these env vars, then "check" will complain. Recipe maintainers may or may not provide defaults for env vars within their recipes regardless of commenting or not (e.g. through the use of -${FOO:} syntax). "check" does not confirm or deny this for you.`, +${FOO:} syntax). "check" does not confirm or deny this for you.`), Args: cobra.ExactArgs(1), ValidArgsFunction: func( cmd *cobra.Command, @@ -83,9 +84,9 @@ ${FOO:} syntax). "check" does not confirm or deny this for you.`, func init() { AppCheckCommand.Flags().BoolVarP( &internal.Chaos, - "chaos", - "C", + i18n.G("chaos"), + i18n.G("C"), false, - "ignore uncommitted recipes changes", + i18n.G("ignore uncommitted recipes changes"), ) } diff --git a/cli/app/cmd.go b/cli/app/cmd.go index a8e2e17f..00477fe0 100644 --- a/cli/app/cmd.go +++ b/cli/app/cmd.go @@ -13,15 +13,16 @@ import ( appPkg "coopcloud.tech/abra/pkg/app" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/client" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/log" "github.com/spf13/cobra" ) var AppCmdCommand = &cobra.Command{ - Use: "command [service | --local] [[args] [flags] | [flags] -- [args]]", - Aliases: []string{"cmd"}, - Short: "Run app commands", - Long: `Run an app specific command. + Use: i18n.G("command [service | --local] [[args] [flags] | [flags] -- [args]]"), + Aliases: []string{i18n.G("cmd")}, + Short: i18n.G("Run app commands"), + Long: i18n.G(`Run an app specific command. These commands are bash functions, defined in the abra.sh of the recipe itself. They can be run within the context of a service (e.g. app) or locally on your @@ -30,24 +31,24 @@ work station by passing "--local/-l". N.B. If using the "--" style to pass arguments, flags (e.g. "--local/-l") must be passed *before* the "--". It is possible to pass arguments without the "--" as long as no dashes are present (i.e. "foo" works without "--", "-foo" -does not).`, - Example: ` # pass args/flags without "--" +does not).`), + Example: i18n.G(` # pass args/flags without "--" abra app cmd 1312.net app my_cmd_arg foo --user bar # pass args/flags with "--" abra app cmd 1312.net app my_cmd_args --user bar -- foo -vvv # drop the [service] arg if using "--local/-l" - abra app cmd 1312.net my_cmd --local`, + abra app cmd 1312.net my_cmd --local`), Args: func(cmd *cobra.Command, args []string) error { if local { if !(len(args) >= 2) { - return errors.New("requires at least 2 arguments with --local/-l") + return errors.New(i18n.G("requires at least 2 arguments with --local/-l")) } if slices.Contains(os.Args, "--") { if cmd.ArgsLenAtDash() > 2 { - return errors.New("accepts at most 2 args with --local/-l") + return errors.New(i18n.G("accepts at most 2 args with --local/-l")) } } @@ -63,7 +64,7 @@ does not).`, } if !(len(args) >= 3) { - return errors.New("requires at least 3 arguments") + return errors.New(i18n.G("requires at least 3 arguments")) } return nil @@ -97,14 +98,14 @@ does not).`, } if local && remoteUser != "" { - log.Fatal("cannot use --local & --user together") + log.Fatal(i18n.G("cannot use --local & --user together")) } hasCmdArgs, parsedCmdArgs := parseCmdArgs(args, local) if _, err := os.Stat(app.Recipe.AbraShPath); err != nil { if os.IsNotExist(err) { - log.Fatalf("%s does not exist for %s?", app.Recipe.AbraShPath, app.Name) + log.Fatal(i18n.G("%s does not exist for %s?", app.Recipe.AbraShPath, app.Name)) } log.Fatal(err) } @@ -115,7 +116,7 @@ does not).`, log.Fatal(err) } - log.Debugf("--local detected, running %s on local work station", cmdName) + log.Debug(i18n.G("--local detected, running %s on local work station", cmdName)) var exportEnv string for k, v := range app.Env { @@ -124,16 +125,16 @@ does not).`, var sourceAndExec string if hasCmdArgs { - log.Debugf("parsed following command arguments: %s", parsedCmdArgs) + log.Debug(i18n.G("parsed following command arguments: %s", parsedCmdArgs)) sourceAndExec = fmt.Sprintf("TARGET=local; APP_NAME=%s; STACK_NAME=%s; %s . %s; %s %s", app.Name, app.StackName(), exportEnv, app.Recipe.AbraShPath, cmdName, parsedCmdArgs) } else { - log.Debug("did not detect any command arguments") + log.Debug(i18n.G("did not detect any command arguments")) sourceAndExec = fmt.Sprintf("TARGET=local; APP_NAME=%s; STACK_NAME=%s; %s . %s; %s", app.Name, app.StackName(), exportEnv, app.Recipe.AbraShPath, cmdName) } shell := "/bin/bash" if _, err := os.Stat(shell); errors.Is(err, os.ErrNotExist) { - log.Debugf("%s does not exist locally, use /bin/sh as fallback", shell) + log.Debug(i18n.G("%s does not exist locally, use /bin/sh as fallback", shell)) shell = "/bin/sh" } cmd := exec.Command(shell, "-c", sourceAndExec) @@ -164,15 +165,15 @@ does not).`, } if !matchingServiceName { - log.Fatalf("no service %s for %s?", targetServiceName, app.Name) + log.Fatal(i18n.G("no service %s for %s?", targetServiceName, app.Name)) } - log.Debugf("running command %s within the context of %s_%s", cmdName, app.StackName(), targetServiceName) + log.Debug(i18n.G("running command %s within the context of %s_%s", cmdName, app.StackName(), targetServiceName)) if hasCmdArgs { - log.Debugf("parsed following command arguments: %s", parsedCmdArgs) + log.Debug(i18n.G("parsed following command arguments: %s", parsedCmdArgs)) } else { - log.Debug("did not detect any command arguments") + log.Debug(i18n.G("did not detect any command arguments")) } cl, err := client.New(app.Server) @@ -192,9 +193,9 @@ does not).`, } var AppCmdListCommand = &cobra.Command{ - Use: "list [flags]", - Aliases: []string{"ls"}, - Short: "List all available commands", + Use: i18n.G("list [flags]"), + Aliases: []string{i18n.G("ls")}, + Short: i18n.G("List all available commands"), Args: cobra.MinimumNArgs(1), Run: func(cmd *cobra.Command, args []string) { app := internal.ValidateApp(args) @@ -244,33 +245,33 @@ var ( func init() { AppCmdCommand.Flags().BoolVarP( &local, - "local", - "l", + i18n.G("local"), + i18n.G("l"), false, - "run command locally", + i18n.G("run command locally"), ) AppCmdCommand.Flags().StringVarP( &remoteUser, - "user", - "u", + i18n.G("user"), + i18n.G("u"), "", - "request remote user", + i18n.G("request remote user"), ) AppCmdCommand.Flags().BoolVarP( &disableTTY, - "tty", - "T", + i18n.G("tty"), + i18n.G("T"), false, - "disable remote TTY", + i18n.G("disable remote TTY"), ) AppCmdCommand.Flags().BoolVarP( &internal.Chaos, - "chaos", - "C", + i18n.G("chaos"), + i18n.G("C"), false, - "ignore uncommitted recipes changes", + i18n.G("ignore uncommitted recipes changes"), ) } diff --git a/cli/app/config.go b/cli/app/config.go index 163f1afc..23028973 100644 --- a/cli/app/config.go +++ b/cli/app/config.go @@ -6,16 +6,17 @@ import ( appPkg "coopcloud.tech/abra/pkg/app" "coopcloud.tech/abra/pkg/autocomplete" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/log" "github.com/AlecAivazis/survey/v2" "github.com/spf13/cobra" ) var AppConfigCommand = &cobra.Command{ - Use: "config [flags]", - Aliases: []string{"cfg"}, - Short: "Edit app config", - Example: " abra config 1312.net", + Use: i18n.G("config [flags]"), + Aliases: []string{i18n.G("cfg")}, + Short: i18n.G("Edit app config"), + Example: i18n.G(" abra config 1312.net"), Args: cobra.ExactArgs(1), ValidArgsFunction: func( cmd *cobra.Command, @@ -32,13 +33,13 @@ var AppConfigCommand = &cobra.Command{ appName := args[0] appFile, exists := files[appName] if !exists { - log.Fatalf("cannot find app with name %s", appName) + log.Fatal(i18n.G("cannot find app with name %s", appName)) } ed, ok := os.LookupEnv("EDITOR") if !ok { edPrompt := &survey.Select{ - Message: "which editor do you wish to use?", + Message: i18n.G("which editor do you wish to use?"), Options: []string{"vi", "vim", "nvim", "nano", "pico", "emacs"}, } if err := survey.AskOne(edPrompt, &ed); err != nil { diff --git a/cli/app/cp.go b/cli/app/cp.go index 6d0b1130..e75a3f7a 100644 --- a/cli/app/cp.go +++ b/cli/app/cp.go @@ -3,7 +3,6 @@ package app import ( "context" "errors" - "fmt" "io" "os" "path" @@ -15,6 +14,7 @@ import ( "coopcloud.tech/abra/pkg/client" containerPkg "coopcloud.tech/abra/pkg/container" "coopcloud.tech/abra/pkg/formatter" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/upstream/container" "github.com/docker/cli/cli/command" @@ -26,14 +26,14 @@ import ( ) var AppCpCommand = &cobra.Command{ - Use: "cp [flags]", - Aliases: []string{"c"}, - Short: "Copy files to/from a deployed app service", - Example: ` # copy myfile.txt to the root of the app service + Use: i18n.G("cp [flags]"), + Aliases: []string{i18n.G("c")}, + Short: i18n.G("Copy files to/from a deployed app service"), + Example: i18n.G(` # copy myfile.txt to the root of the app service abra app cp 1312.net myfile.txt app:/ # copy that file back to your current working directory locally - abra app cp 1312.net app:/myfile.txt ./`, + abra app cp 1312.net app:/myfile.txt ./`), Args: cobra.ExactArgs(3), ValidArgsFunction: func( cmd *cobra.Command, @@ -69,7 +69,7 @@ var AppCpCommand = &cobra.Command{ if err != nil { log.Fatal(err) } - log.Debugf("retrieved %s as target container on %s", formatter.ShortenID(container.ID), app.Server) + log.Debug(i18n.G("retrieved %s as target container on %s", formatter.ShortenID(container.ID), app.Server)) if toContainer { err = CopyToContainer(cl, container.ID, srcPath, dstPath) @@ -82,7 +82,7 @@ var AppCpCommand = &cobra.Command{ }, } -var errServiceMissing = errors.New("one of / arguments must take $SERVICE:$PATH form") +var errServiceMissing = errors.New(i18n.G("one of / arguments must take $SERVICE:$PATH form")) // parseSrcAndDst parses src and dest string. One of src or dst must be of the form $SERVICE:$PATH func parseSrcAndDst(src, dst string) (srcPath string, dstPath string, service string, toContainer bool, err error) { @@ -105,7 +105,7 @@ func parseSrcAndDst(src, dst string) (srcPath string, dstPath string, service st func CopyToContainer(cl *dockerClient.Client, containerID, srcPath, dstPath string) error { srcStat, err := os.Stat(srcPath) if err != nil { - return fmt.Errorf("local %s ", err) + return errors.New(i18n.G("local %s ", err)) } dstStat, err := cl.ContainerStatPath(context.Background(), containerID, dstPath) @@ -114,7 +114,7 @@ func CopyToContainer(cl *dockerClient.Client, containerID, srcPath, dstPath stri if errdefs.IsNotFound(err) { dstExists = false } else { - return fmt.Errorf("remote path: %s", err) + return errors.New(i18n.G("remote path: %s", err)) } } @@ -142,7 +142,7 @@ func CopyToContainer(cl *dockerClient.Client, containerID, srcPath, dstPath stri Detach: false, Tty: true, }); err != nil { - return fmt.Errorf("create remote directory: %s", err) + return errors.New(i18n.G("create remote directory: %s", err)) } case CopyModeFileToFile: // Remove the file component from the path, since docker can only copy @@ -161,7 +161,7 @@ func CopyToContainer(cl *dockerClient.Client, containerID, srcPath, dstPath stri return err } - log.Debugf("copy %s from local to %s on container", srcPath, dstPath) + log.Debug(i18n.G("copy %s from local to %s on container", srcPath, dstPath)) copyOpts := containertypes.CopyToContainerOptions{AllowOverwriteDirWithFile: false, CopyUIDGID: false} if err := cl.CopyToContainer(context.Background(), containerID, dstPath, content, copyOpts); err != nil { return err @@ -181,7 +181,7 @@ func CopyToContainer(cl *dockerClient.Client, containerID, srcPath, dstPath stri Detach: false, Tty: true, }); err != nil { - return fmt.Errorf("create remote directory: %s", err) + return errors.New(i18n.G("create remote directory: %s", err)) } } @@ -194,9 +194,9 @@ func CopyFromContainer(cl *dockerClient.Client, containerID, srcPath, dstPath st srcStat, err := cl.ContainerStatPath(context.Background(), containerID, srcPath) if err != nil { if errdefs.IsNotFound(err) { - return fmt.Errorf("remote: %s does not exist", srcPath) + return errors.New(i18n.G("remote: %s does not exist", srcPath)) } else { - return fmt.Errorf("remote path: %s", err) + return errors.New(i18n.G("remote path: %s", err)) } } @@ -207,7 +207,7 @@ func CopyFromContainer(cl *dockerClient.Client, containerID, srcPath, dstPath st if os.IsNotExist(err) { dstExists = false } else { - return fmt.Errorf("remote path: %s", err) + return errors.New(i18n.G("remote path: %s", err)) } } else { dstMode = dstStat.Mode() @@ -242,7 +242,7 @@ func CopyFromContainer(cl *dockerClient.Client, containerID, srcPath, dstPath st content, _, err := cl.CopyFromContainer(context.Background(), containerID, srcPath) if err != nil { - return fmt.Errorf("copy: %s", err) + return errors.New(i18n.G("copy: %s", err)) } defer content.Close() if err := archive.Untar(content, dstPath, &archive.TarOptions{ @@ -250,7 +250,7 @@ func CopyFromContainer(cl *dockerClient.Client, containerID, srcPath, dstPath st Compression: archive.Gzip, NoLchown: true, }); err != nil { - return fmt.Errorf("untar: %s", err) + return errors.New(i18n.G("untar: %s", err)) } if moveDstFile != "" { @@ -269,8 +269,8 @@ func CopyFromContainer(cl *dockerClient.Client, containerID, srcPath, dstPath st } var ( - ErrCopyDirToFile = fmt.Errorf("can't copy dir to file") - ErrDstDirNotExist = fmt.Errorf("destination directory does not exist") + ErrCopyDirToFile = errors.New(i18n.G("can't copy dir to file")) + ErrDstDirNotExist = errors.New(i18n.G("destination directory does not exist")) ) type CopyMode int @@ -375,9 +375,9 @@ func moveFile(sourcePath, destPath string) error { func init() { AppCpCommand.Flags().BoolVarP( &internal.Chaos, - "chaos", - "C", + i18n.G("chaos"), + i18n.G("C"), false, - "ignore uncommitted recipes changes", + i18n.G("ignore uncommitted recipes changes"), ) } diff --git a/cli/app/deploy.go b/cli/app/deploy.go index 72e45a58..19cd8872 100644 --- a/cli/app/deploy.go +++ b/cli/app/deploy.go @@ -2,7 +2,7 @@ package app import ( "context" - "fmt" + "errors" "strings" "coopcloud.tech/abra/cli/internal" @@ -16,6 +16,7 @@ import ( "coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/dns" "coopcloud.tech/abra/pkg/formatter" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/lint" "coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/upstream/stack" @@ -24,15 +25,15 @@ import ( ) var AppDeployCommand = &cobra.Command{ - Use: "deploy [version] [flags]", - Aliases: []string{"d"}, - Short: "Deploy an app", - Long: `Deploy an app. + Use: i18n.G("deploy [version] [flags]"), + Aliases: []string{i18n.G("d")}, + Short: i18n.G("Deploy an app"), + Long: i18n.G(`Deploy an app. This command supports chaos operations. Use "--chaos/-C" to deploy your recipe checkout as-is. Recipe commit hashes are also supported as values for -"[version]". Please note, "upgrade"/"rollback" do not support chaos operations.`, - Example: ` # standard deployment +"[version]". Please note, "upgrade"/"rollback" do not support chaos operations.`), + Example: i18n.G(` # standard deployment abra app deploy 1312.net # chaos deployment @@ -42,7 +43,7 @@ checkout as-is. Recipe commit hashes are also supported as values for abra app deploy 1312.net 2.0.0+1.2.3 # deploy a specific git hash - abra app deploy 1312.net 886db76d`, + abra app deploy 1312.net 886db76d`), Args: cobra.RangeArgs(1, 2), ValidArgsFunction: func( cmd *cobra.Command, @@ -55,7 +56,7 @@ checkout as-is. Recipe commit hashes are also supported as values for case 1: app, err := appPkg.Get(args[0]) if err != nil { - errMsg := fmt.Sprintf("autocomplete failed: %s", err) + errMsg := i18n.G("autocomplete failed: %s", err) return []string{errMsg}, cobra.ShellCompDirectiveError } return autocomplete.RecipeVersionComplete(app.Recipe.Name) @@ -84,7 +85,7 @@ checkout as-is. Recipe commit hashes are also supported as values for log.Fatal(err) } - log.Debugf("checking whether %s is already deployed", app.StackName()) + log.Debug(i18n.G("checking whether %s is already deployed", app.StackName())) deployMeta, err := stack.IsDeployed(context.Background(), cl, app.StackName()) if err != nil { @@ -92,18 +93,18 @@ checkout as-is. Recipe commit hashes are also supported as values for } if deployMeta.IsDeployed && !(internal.Force || internal.Chaos) { - log.Fatalf("%s is already deployed", app.Name) + log.Fatal(i18n.G("%s is already deployed", app.Name)) } toDeployVersion, err = getDeployVersion(args, deployMeta, app) if err != nil { - log.Fatal(fmt.Errorf("get deploy version: %s", err)) + log.Fatal(i18n.G("get deploy version: %s", err)) } if !internal.Chaos { _, err = app.Recipe.EnsureVersion(toDeployVersion) if err != nil { - log.Fatalf("ensure recipe: %s", err) + log.Fatal(i18n.G("ensure recipe: %s", err)) } } @@ -162,7 +163,7 @@ checkout as-is. Recipe commit hashes are also supported as values for for _, envVar := range envVars { if !envVar.Present { deployWarnMessages = append(deployWarnMessages, - fmt.Sprintf("%s missing from %s.env", envVar.Name, app.Domain), + i18n.G("%s missing from %s.env", envVar.Name, app.Domain), ) } } @@ -173,10 +174,10 @@ checkout as-is. Recipe commit hashes are also supported as values for log.Fatal(err) } } else { - log.Debug("skipping domain checks, no DOMAIN=... configured") + log.Debug(i18n.G("skipping domain checks, no DOMAIN=... configured")) } } else { - log.Debug("skipping domain checks") + log.Debug(i18n.G("skipping domain checks")) } deployedVersion := config.NO_VERSION_DEFAULT @@ -199,7 +200,7 @@ checkout as-is. Recipe commit hashes are also supported as values for log.Fatal(err) } - log.Debugf("set waiting timeout to %d second(s)", stack.WaitTimeout) + log.Debug(i18n.G("set waiting timeout to %d second(s)", stack.WaitTimeout)) serviceNames, err := appPkg.GetAppServiceNames(app.Name) if err != nil { @@ -225,14 +226,14 @@ checkout as-is. Recipe commit hashes are also supported as values for postDeployCmds, ok := app.Env["POST_DEPLOY_CMDS"] if ok && !internal.DontWaitConverge { - log.Debugf("run the following post-deploy commands: %s", postDeployCmds) + log.Debug(i18n.G("run the following post-deploy commands: %s", postDeployCmds)) if err := internal.PostCmds(cl, app, postDeployCmds); err != nil { - log.Fatalf("attempting to run post deploy commands, saw: %s", err) + log.Fatal(i18n.G("attempting to run post deploy commands, saw: %s", err)) } } if err := app.WriteRecipeVersion(toDeployVersion, false); err != nil { - log.Fatalf("writing recipe version failed: %s", err) + log.Fatal(i18n.G("writing recipe version failed: %s", err)) } }, } @@ -258,7 +259,7 @@ func getLatestVersionOrCommit(app app.App) (string, error) { // validateArgsAndFlags ensures compatible args/flags. func validateArgsAndFlags(args []string) error { if len(args) == 2 && args[1] != "" && internal.Chaos { - return fmt.Errorf("cannot use [version] and --chaos together") + return errors.New(i18n.G("cannot use [version] and --chaos together")) } return nil @@ -272,7 +273,7 @@ func validateSecrets(cl *dockerClient.Client, app app.App) error { for _, secStat := range secStats { if !secStat.CreatedOnRemote { - return fmt.Errorf("secret not generated: %s", secStat.LocalName) + return errors.New(i18n.G("secret not generated: %s", secStat.LocalName)) } } @@ -286,33 +287,33 @@ func getDeployVersion(cliArgs []string, deployMeta stack.DeployMeta, app app.App if err != nil { return "", err } - log.Debugf("version: taking chaos version: %s", v) + log.Debug(i18n.G("version: taking chaos version: %s", v)) return v, nil } // Check if the deploy version is set with a cli argument if len(cliArgs) == 2 && cliArgs[1] != "" { - log.Debugf("version: taking version from cli arg: %s", cliArgs[1]) + log.Debug(i18n.G("version: taking version from cli arg: %s", cliArgs[1])) return cliArgs[1], nil } // Check if the recipe has a version in the .env file if app.Recipe.EnvVersion != "" && !internal.IgnoreEnvVersion { if strings.HasSuffix(app.Recipe.EnvVersionRaw, "+U") { - return "", fmt.Errorf("version: can not redeploy chaos version %s", app.Recipe.EnvVersionRaw) + return "", errors.New(i18n.G("version: can not redeploy chaos version %s", app.Recipe.EnvVersionRaw)) } - log.Debugf("version: taking version from .env file: %s", app.Recipe.EnvVersion) + log.Debug(i18n.G("version: taking version from .env file: %s", app.Recipe.EnvVersion)) return app.Recipe.EnvVersion, nil } // Take deployed version if deployMeta.IsDeployed { - log.Debugf("version: taking deployed version: %s", deployMeta.Version) + log.Debug(i18n.G("version: taking deployed version: %s", deployMeta.Version)) return deployMeta.Version, nil } v, err := getLatestVersionOrCommit(app) - log.Debugf("version: taking new recipe version: %s", v) + log.Debug(i18n.G("version: taking new recipe version: %s", v)) if err != nil { return "", err } @@ -322,33 +323,33 @@ func getDeployVersion(cliArgs []string, deployMeta stack.DeployMeta, app app.App func init() { AppDeployCommand.Flags().BoolVarP( &internal.Chaos, - "chaos", - "C", + i18n.G("chaos"), + i18n.G("C"), false, - "ignore uncommitted recipes changes", + i18n.G("ignore uncommitted recipes changes"), ) AppDeployCommand.Flags().BoolVarP( &internal.Force, - "force", - "f", + i18n.G("force"), + i18n.G("f"), false, - "perform action without further prompt", + i18n.G("perform action without further prompt"), ) AppDeployCommand.Flags().BoolVarP( &internal.NoDomainChecks, - "no-domain-checks", - "D", + i18n.G("no-domain-checks"), + i18n.G("D"), false, - "disable public DNS checks", + i18n.G("disable public DNS checks"), ) AppDeployCommand.Flags().BoolVarP( &internal.DontWaitConverge, - "no-converge-checks", - "c", + i18n.G("no-converge-checks"), + i18n.G("c"), false, - "disable converge logic checks", + i18n.G("disable converge logic checks"), ) } diff --git a/cli/app/env.go b/cli/app/env.go index 44f3e3fe..265885f1 100644 --- a/cli/app/env.go +++ b/cli/app/env.go @@ -7,14 +7,15 @@ import ( "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/formatter" + "coopcloud.tech/abra/pkg/i18n" "github.com/spf13/cobra" ) var AppEnvCommand = &cobra.Command{ - Use: "env [flags]", - Aliases: []string{"e"}, - Short: "Show app .env values", - Example: " abra app env 1312.net", + Use: i18n.G("env [flags]"), + Aliases: []string{i18n.G("e")}, + Short: i18n.G("Show app .env values"), + Example: i18n.G(" abra app env 1312.net"), Args: cobra.ExactArgs(1), ValidArgsFunction: func( cmd *cobra.Command, @@ -37,7 +38,7 @@ var AppEnvCommand = &cobra.Command{ rows = append(rows, []string{k, app.Env[k]}) } - overview := formatter.CreateOverview("ENV OVERVIEW", rows) + overview := formatter.CreateOverview(i18n.G("ENV OVERVIEW"), rows) fmt.Println(overview) }, } diff --git a/cli/app/labels.go b/cli/app/labels.go index 5201db61..43017377 100644 --- a/cli/app/labels.go +++ b/cli/app/labels.go @@ -9,6 +9,7 @@ import ( "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/formatter" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/upstream/convert" composetypes "github.com/docker/cli/cli/compose/types" @@ -19,11 +20,11 @@ import ( ) var AppLabelsCommand = &cobra.Command{ - Use: "labels [flags]", - Aliases: []string{"lb"}, - Short: "Show deployment labels", - Long: "Both local recipe and live deployment labels are shown.", - Example: " abra app labels 1312.net", + Use: i18n.G("labels [flags]"), + Aliases: []string{i18n.G("lb")}, + Short: i18n.G("Show deployment labels"), + Long: i18n.G("Both local recipe and live deployment labels are shown."), + Example: i18n.G(" abra app labels 1312.net"), Args: cobra.ExactArgs(1), ValidArgsFunction: func( cmd *cobra.Command, @@ -49,7 +50,7 @@ var AppLabelsCommand = &cobra.Command{ } rows := [][]string{ - {"DEPLOYED LABELS", "---"}, + {i18n.G("DEPLOYED LABELS"), "---"}, } remoteLabelKeys := make([]string, 0, len(remoteLabels)) @@ -67,10 +68,10 @@ var AppLabelsCommand = &cobra.Command{ } if len(remoteLabelKeys) == 0 { - rows = append(rows, []string{"unknown"}) + rows = append(rows, []string{i18n.G("unknown")}) } - rows = append(rows, []string{"RECIPE LABELS", "---"}) + rows = append(rows, []string{i18n.G("RECIPE LABELS"), "---"}) config, err := app.Recipe.GetComposeConfig(app.Env) if err != nil { @@ -98,7 +99,7 @@ var AppLabelsCommand = &cobra.Command{ }) } - overview := formatter.CreateOverview("LABELS OVERVIEW", rows) + overview := formatter.CreateOverview(i18n.G("LABELS OVERVIEW"), rows) fmt.Println(overview) }, } @@ -131,9 +132,9 @@ func getLabels(cl *dockerClient.Client, stackName string) (map[string]string, er func init() { AppLabelsCommand.Flags().BoolVarP( &internal.Chaos, - "chaos", - "C", + i18n.G("chaos"), + i18n.G("C"), false, - "ignore uncommitted recipes changes", + i18n.G("ignore uncommitted recipes changes"), ) } diff --git a/cli/app/list.go b/cli/app/list.go index 50e7ce5c..2451ed8b 100644 --- a/cli/app/list.go +++ b/cli/app/list.go @@ -11,6 +11,7 @@ import ( appPkg "coopcloud.tech/abra/pkg/app" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/formatter" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/log" "coopcloud.tech/tagcmp" "github.com/spf13/cobra" @@ -39,20 +40,20 @@ type serverStatus struct { } var AppListCommand = &cobra.Command{ - Use: "list [flags]", - Aliases: []string{"ls"}, - Short: "List all managed apps", - Long: `Generate a report of all managed apps. + Use: i18n.G("list [flags]"), + Aliases: []string{i18n.G("ls")}, + Short: i18n.G("List all managed apps"), + Long: i18n.G(`Generate a report of all managed apps. -Use "--status/-S" flag to query all servers for the live deployment status.`, - Example: ` # list apps of all servers without live status +Use "--status/-S" flag to query all servers for the live deployment status.`), + Example: i18n.G(` # list apps of all servers without live status abra app ls # list apps of a specific server with live status abra app ls -s 1312.net -S # list apps of all servers which match a specific recipe - abra app ls -r gitea`, + abra app ls -r gitea`), Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { appFiles, err := appPkg.LoadAppFiles(listAppServer) @@ -107,11 +108,11 @@ Use "--status/-S" flag to query all servers for the live deployment status.`, totalAppsCount++ if status { - status := "unknown" - version := "unknown" - chaos := "unknown" - chaosVersion := "unknown" - autoUpdate := "unknown" + status := i18n.G("unknown") + version := i18n.G("unknown") + chaos := i18n.G("unknown") + chaosVersion := i18n.G("unknown") + autoUpdate := i18n.G("unknown") if statusMeta, ok := statuses[app.StackName()]; ok { if currentVersion, exists := statusMeta["version"]; exists { if currentVersion != "" { @@ -144,12 +145,12 @@ Use "--status/-S" flag to query all servers for the live deployment status.`, var newUpdates []string if version != "unknown" && chaos == "false" { if err := app.Recipe.EnsureExists(); err != nil { - log.Fatalf("unable to clone %s: %s", app.Name, err) + log.Fatal(i18n.G("unable to clone %s: %s", app.Name, err)) } updates, err := app.Recipe.Tags() if err != nil { - log.Fatalf("unable to retrieve tags for %s: %s", app.Name, err) + log.Fatal(i18n.G("unable to retrieve tags for %s: %s", app.Name, err)) } parsedVersion, err := tagcmp.Parse(version) @@ -171,9 +172,9 @@ Use "--status/-S" flag to query all servers for the live deployment status.`, if len(newUpdates) == 0 { if version == "unknown" { - appStats.Upgrade = "unknown" + appStats.Upgrade = i18n.G("unknown") } else { - appStats.Upgrade = "latest" + appStats.Upgrade = i18n.G("latest") stats.LatestCount++ } } else { @@ -212,14 +213,15 @@ Use "--status/-S" flag to query all servers for the live deployment status.`, serverStat := allStats[app.Server] - headers := []string{"RECIPE", "DOMAIN", "SERVER"} + headers := []string{i18n.G("RECIPE"), i18n.G("DOMAIN"), i18n.G("SERVER")} if status { headers = append(headers, []string{ - "STATUS", - "CHAOS", - "VERSION", - "UPGRADE", - "AUTOUPDATE"}..., + i18n.G("STATUS"), + i18n.G("CHAOS"), + i18n.G("VERSION"), + i18n.G("UPGRADE"), + i18n.G("AUTOUPDATE"), + }..., ) } @@ -283,22 +285,22 @@ var ( func init() { AppListCommand.Flags().BoolVarP( &status, - "status", - "S", + i18n.G("status"), + i18n.G("S"), false, - "show app deployment status", + i18n.G("show app deployment status"), ) AppListCommand.Flags().StringVarP( &recipeFilter, - "recipe", - "r", + i18n.G("recipe"), + i18n.G("r"), "", - "show apps of a specific recipe", + i18n.G("show apps of a specific recipe"), ) AppListCommand.RegisterFlagCompletionFunc( - "recipe", + i18n.G("recipe"), func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { return autocomplete.RecipeNameComplete() }, @@ -306,22 +308,22 @@ func init() { AppListCommand.Flags().BoolVarP( &internal.MachineReadable, - "machine", - "m", + i18n.G("machine"), + i18n.G("m"), false, - "print machine-readable output", + i18n.G("print machine-readable output"), ) AppListCommand.Flags().StringVarP( &listAppServer, - "server", - "s", + i18n.G("server"), + i18n.G("s"), "", - "show apps of a specific server", + i18n.G("show apps of a specific server"), ) AppListCommand.RegisterFlagCompletionFunc( - "server", + i18n.G("server"), func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { return autocomplete.ServerNameComplete() }, diff --git a/cli/app/logs.go b/cli/app/logs.go index 741bfd1b..6bc6b400 100644 --- a/cli/app/logs.go +++ b/cli/app/logs.go @@ -2,12 +2,12 @@ package app import ( "context" - "fmt" "coopcloud.tech/abra/cli/internal" appPkg "coopcloud.tech/abra/pkg/app" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/client" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/logs" "coopcloud.tech/abra/pkg/upstream/stack" @@ -15,9 +15,9 @@ import ( ) var AppLogsCommand = &cobra.Command{ - Use: "logs [service] [flags]", - Aliases: []string{"l"}, - Short: "Tail app logs", + Use: i18n.G("logs [service] [flags]"), + Aliases: []string{i18n.G("l")}, + Short: i18n.G("Tail app logs"), Args: cobra.RangeArgs(1, 2), ValidArgsFunction: func( cmd *cobra.Command, @@ -29,8 +29,7 @@ var AppLogsCommand = &cobra.Command{ case 1: app, err := appPkg.Get(args[0]) if err != nil { - errMsg := fmt.Sprintf("autocomplete failed: %s", err) - return []string{errMsg}, cobra.ShellCompDirectiveError + return []string{i18n.G("autocomplete failed: %s", err)}, cobra.ShellCompDirectiveError } return autocomplete.ServiceNameComplete(app.Name) default: @@ -56,7 +55,7 @@ var AppLogsCommand = &cobra.Command{ } if !deployMeta.IsDeployed { - log.Fatalf("%s is not deployed?", app.Name) + log.Fatal(i18n.G("%s is not deployed?", app.Name)) } var serviceNames []string @@ -91,17 +90,17 @@ var ( func init() { AppLogsCommand.Flags().BoolVarP( &stdErr, - "stderr", - "s", + i18n.G("stderr"), + i18n.G("s"), false, - "only tail stderr", + i18n.G("only tail stderr"), ) AppLogsCommand.Flags().StringVarP( &sinceLogs, - "since", - "S", + i18n.G("since"), + i18n.G("S"), "", - "tail logs since YYYY-MM-DDTHH:MM:SSZ", + i18n.G("tail logs since YYYY-MM-DDTHH:MM:SSZ"), ) } diff --git a/cli/app/new.go b/cli/app/new.go index e022beed..26738798 100644 --- a/cli/app/new.go +++ b/cli/app/new.go @@ -1,6 +1,7 @@ package app import ( + "errors" "fmt" "coopcloud.tech/abra/cli/internal" @@ -10,6 +11,7 @@ import ( "coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/formatter" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/log" recipePkg "coopcloud.tech/abra/pkg/recipe" "coopcloud.tech/abra/pkg/secret" @@ -19,7 +21,7 @@ import ( "github.com/spf13/cobra" ) -var appNewDescription = `Creates a new app from a default recipe. +var appNewDescription = i18n.G(`Creates a new app from a default recipe. This new app configuration is stored in your $ABRA_DIR directory under the appropriate server. @@ -39,12 +41,12 @@ store them somewhere safe. You can use the "--pass/-P" to store these generated passwords locally in a pass store (see passwordstore.org for more). The pass command must be available -on your $PATH.` +on your $PATH.`) var AppNewCommand = &cobra.Command{ - Use: "new [recipe] [version] [flags]", - Aliases: []string{"n"}, - Short: "Create a new app", + Use: i18n.G("new [recipe] [version] [flags]"), + Aliases: []string{i18n.G("n")}, + Short: i18n.G("Create a new app"), Long: appNewDescription, Args: cobra.RangeArgs(0, 2), ValidArgsFunction: func( @@ -65,7 +67,7 @@ var AppNewCommand = &cobra.Command{ recipe := internal.ValidateRecipe(args, cmd.Name()) if len(args) == 2 && internal.Chaos { - log.Fatal("cannot use [version] and --chaos together") + log.Fatal(i18n.G("cannot use [version] and --chaos together")) } var recipeVersion string @@ -113,7 +115,7 @@ var AppNewCommand = &cobra.Command{ if recipeVersion == "" { head, err := recipe.Head() if err != nil { - log.Fatalf("failed to retrieve latest commit for %s: %s", recipe.Name, err) + log.Fatal(i18n.G("failed to retrieve latest commit for %s: %s", recipe.Name, err)) } recipeVersion = formatter.SmallSHA(head.String()) @@ -130,7 +132,7 @@ var AppNewCommand = &cobra.Command{ } sanitisedAppName := appPkg.SanitiseAppName(appDomain) - log.Debugf("%s sanitised as %s for new app", appDomain, sanitisedAppName) + log.Debug(i18n.G("%s sanitised as %s for new app", appDomain, sanitisedAppName)) if err := appPkg.TemplateAppEnvSample( recipe, @@ -182,7 +184,7 @@ var AppNewCommand = &cobra.Command{ log.Fatal(err) } - headers := []string{"NAME", "VALUE"} + headers := []string{i18n.G("NAME"), i18n.G("VALUE")} secretsTable.Headers(headers...) for name, val := range appSecrets { @@ -194,7 +196,7 @@ var AppNewCommand = &cobra.Command{ newAppServer = "local" } - log.Infof("%s created (version: %s)", appDomain, recipeVersion) + log.Info(i18n.G("%s created (version: %s)", appDomain, recipeVersion)) if len(appSecrets) > 0 { rows := [][]string{} @@ -202,15 +204,15 @@ var AppNewCommand = &cobra.Command{ rows = append(rows, []string{k, v}) } - overview := formatter.CreateOverview("SECRETS OVERVIEW", rows) + overview := formatter.CreateOverview(i18n.G("SECRETS OVERVIEW"), rows) fmt.Println(overview) - log.Warnf( + log.Warn(i18n.G( "secrets are %s shown again, please save them %s", formatter.BoldUnderlineStyle.Render("NOT"), formatter.BoldUnderlineStyle.Render("NOW"), - ) + )) } app, err := app.Get(appDomain) @@ -219,7 +221,7 @@ var AppNewCommand = &cobra.Command{ } if err := app.WriteRecipeVersion(recipeVersion, false); err != nil { - log.Fatalf("writing recipe version failed: %s", err) + log.Fatal(i18n.G("writing recipe version failed: %s", err)) } }, } @@ -231,7 +233,7 @@ type AppSecrets map[string]string func createSecrets(cl *dockerClient.Client, secretsConfig map[string]secret.Secret, sanitisedAppName string) (AppSecrets, error) { // NOTE(d1): trim to match app.StackName() implementation if len(sanitisedAppName) > config.MAX_SANITISED_APP_NAME_LENGTH { - log.Debugf("trimming %s to %s to avoid runtime limits", sanitisedAppName, sanitisedAppName[:config.MAX_SANITISED_APP_NAME_LENGTH]) + log.Debug(i18n.G("trimming %s to %s to avoid runtime limits", sanitisedAppName, sanitisedAppName[:config.MAX_SANITISED_APP_NAME_LENGTH])) sanitisedAppName = sanitisedAppName[:config.MAX_SANITISED_APP_NAME_LENGTH] } @@ -261,7 +263,7 @@ func createSecrets(cl *dockerClient.Client, secretsConfig map[string]secret.Secr func ensureDomainFlag(recipe recipePkg.Recipe, server string) error { if appDomain == "" && !internal.NoInput { prompt := &survey.Input{ - Message: "Specify app domain", + Message: i18n.G("Specify app domain"), Default: fmt.Sprintf("%s.%s", recipe.Name, server), } if err := survey.AskOne(prompt, &appDomain); err != nil { @@ -270,7 +272,7 @@ func ensureDomainFlag(recipe recipePkg.Recipe, server string) error { } if appDomain == "" { - return fmt.Errorf("no domain provided") + return fmt.Errorf(i18n.G("no domain provided")) } return nil @@ -279,13 +281,13 @@ func ensureDomainFlag(recipe recipePkg.Recipe, server string) error { // promptForSecrets asks if we should generate secrets for a new app. func promptForSecrets(recipeName string, secretsConfig map[string]secret.Secret) error { if len(secretsConfig) == 0 { - log.Debugf("%s has no secrets to generate, skipping...", recipeName) + log.Debug(i18n.G("%s has no secrets to generate, skipping...", recipeName)) return nil } if !generateSecrets && !internal.NoInput { prompt := &survey.Confirm{ - Message: "Generate app secrets?", + Message: i18n.G("Generate app secrets?"), } if err := survey.AskOne(prompt, &generateSecrets); err != nil { return err @@ -304,13 +306,13 @@ func ensureServerFlag() error { if len(servers) == 1 { newAppServer = servers[0] - log.Infof("single server detected, choosing %s automatically", newAppServer) + log.Info(i18n.G("single server detected, choosing %s automatically", newAppServer)) return nil } if newAppServer == "" && !internal.NoInput { prompt := &survey.Select{ - Message: "Select app server:", + Message: i18n.G("Select app server:"), Options: servers, } if err := survey.AskOne(prompt, &newAppServer); err != nil { @@ -319,7 +321,7 @@ func ensureServerFlag() error { } if newAppServer == "" { - return fmt.Errorf("no server provided") + return errors.New(i18n.G("no server provided")) } return nil @@ -335,14 +337,14 @@ var ( func init() { AppNewCommand.Flags().StringVarP( &newAppServer, - "server", - "s", + i18n.G("server"), + i18n.G("s"), "", - "specify server for new app", + i18n.G("specify server for new app"), ) AppNewCommand.RegisterFlagCompletionFunc( - "server", + i18n.G("server"), func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { return autocomplete.ServerNameComplete() }, @@ -350,34 +352,34 @@ func init() { AppNewCommand.Flags().StringVarP( &appDomain, - "domain", - "D", + i18n.G("domain"), + i18n.G("D"), "", - "domain name for app", + i18n.G("domain name for app"), ) AppNewCommand.Flags().BoolVarP( &saveInPass, - "pass", - "p", + i18n.G("pass"), + i18n.G("p"), false, - "store secrets in a local pass store", + i18n.G("store secrets in a local pass store"), ) AppNewCommand.Flags().BoolVarP( &generateSecrets, - "secrets", - "S", + i18n.G("secrets"), + i18n.G("S"), false, - "automatically generate secrets", + i18n.G("automatically generate secrets"), ) AppNewCommand.Flags().BoolVarP( &internal.Chaos, - "chaos", - "C", + i18n.G("chaos"), + i18n.G("C"), false, - "ignore uncommitted recipes changes", + i18n.G("ignore uncommitted recipes changes"), ) } diff --git a/cli/app/ps.go b/cli/app/ps.go index 029e0d06..1c6540c3 100644 --- a/cli/app/ps.go +++ b/cli/app/ps.go @@ -13,6 +13,7 @@ import ( "coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/formatter" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/log" abraService "coopcloud.tech/abra/pkg/service" stack "coopcloud.tech/abra/pkg/upstream/stack" @@ -24,9 +25,9 @@ import ( ) var AppPsCommand = &cobra.Command{ - Use: "ps [flags]", - Aliases: []string{"p"}, - Short: "Check app deployment status", + Use: i18n.G("ps [flags]"), + Aliases: []string{i18n.G("p")}, + Short: i18n.G("Check app deployment status"), Args: cobra.ExactArgs(1), ValidArgsFunction: func( cmd *cobra.Command, @@ -52,7 +53,7 @@ var AppPsCommand = &cobra.Command{ } if !deployMeta.IsDeployed { - log.Fatalf("%s is not deployed?", app.Name) + log.Fatal(i18n.G("%s is not deployed?", app.Name)) } chaosVersion := config.CHAOS_DEFAULT @@ -115,11 +116,11 @@ func showPSOutput(app appPkg.App, cl *dockerClient.Client, deployedVersion, chao "version": deployedVersion, "chaos": chaosVersion, "service": service.Name, - "image": "unknown", - "created": "unknown", - "status": "unknown", - "state": "unknown", - "ports": "unknown", + "image": i18n.G("unknown"), + "created": i18n.G("unknown"), + "status": i18n.G("unknown"), + "state": i18n.G("unknown"), + "ports": i18n.G("unknown"), } } else { container := containers[0] @@ -161,7 +162,7 @@ func showPSOutput(app appPkg.App, cl *dockerClient.Client, deployedVersion, chao if internal.MachineReadable { rendered, err := json.Marshal(allContainerStats) if err != nil { - log.Fatal("unable to convert to JSON: %s", err) + log.Fatal(i18n.G("unable to convert to JSON: %s", err)) } fmt.Println(string(rendered)) @@ -175,11 +176,11 @@ func showPSOutput(app appPkg.App, cl *dockerClient.Client, deployedVersion, chao } headers := []string{ - "SERVICE", - "STATUS", - "IMAGE", - "VERSION", - "CHAOS", + i18n.G("SERVICE"), + i18n.G("STATUS"), + i18n.G("IMAGE"), + i18n.G("VERSION"), + i18n.G("CHAOS"), } table. @@ -194,17 +195,17 @@ func showPSOutput(app appPkg.App, cl *dockerClient.Client, deployedVersion, chao func init() { AppPsCommand.Flags().BoolVarP( &internal.MachineReadable, - "machine", - "m", + i18n.G("machine"), + i18n.G("m"), false, - "print machine-readable output", + i18n.G("print machine-readable output"), ) AppPsCommand.Flags().BoolVarP( &internal.Chaos, - "chaos", - "C", + i18n.G("chaos"), + i18n.G("C"), false, - "ignore uncommitted recipes changes", + i18n.G("ignore uncommitted recipes changes"), ) } diff --git a/cli/app/remove.go b/cli/app/remove.go index f65f8638..6d5695ec 100644 --- a/cli/app/remove.go +++ b/cli/app/remove.go @@ -2,12 +2,12 @@ package app import ( "context" - "fmt" "os" "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/client" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/upstream/stack" "github.com/AlecAivazis/survey/v2" @@ -16,10 +16,10 @@ import ( ) var AppRemoveCommand = &cobra.Command{ - Use: "remove [flags]", - Aliases: []string{"rm"}, - Short: "Remove all app data, locally and remotely", - Long: `Remove everything related to an app which is already undeployed. + Use: i18n.G("remove [flags]"), + Aliases: []string{i18n.G("rm")}, + Short: i18n.G("Remove all app data, locally and remotely"), + Long: i18n.G(`Remove everything related to an app which is already undeployed. By default, it will prompt for confirmation before proceeding. All secrets, volumes and the local app env file will be deleted. @@ -34,8 +34,8 @@ Please note, if you delete the local app env file without removing volumes and secrets first, Abra will *not* be able to help you remove them afterwards. To delete everything without prompt, use the "--force/-f" or the "--no-input/n" -flag.`, - Example: " abra app remove 1312.net", +flag.`), + Example: i18n.G(" abra app remove 1312.net"), Args: cobra.ExactArgs(1), ValidArgsFunction: func( cmd *cobra.Command, @@ -47,16 +47,16 @@ flag.`, app := internal.ValidateApp(args) if !internal.Force && !internal.NoInput { - log.Warnf("ALERTA ALERTA: deleting %s data and config (local/remote)", app.Name) + log.Warn(i18n.G("ALERTA ALERTA: deleting %s data and config (local/remote)", app.Name)) response := false - prompt := &survey.Confirm{Message: "are you sure?"} + prompt := &survey.Confirm{Message: i18n.G("are you sure?")} if err := survey.AskOne(prompt, &response); err != nil { log.Fatal(err) } if !response { - log.Fatal("aborting as requested") + log.Fatal(i18n.G("aborting as requested")) } } @@ -70,7 +70,7 @@ flag.`, log.Fatal(err) } if deployMeta.IsDeployed { - log.Fatalf("%s is still deployed. Run \"abra app undeploy %s\"", app.Name, app.Name) + log.Fatal(i18n.G("%s is still deployed. Run \"abra app undeploy %s\"", app.Name, app.Name)) } fs, err := app.Filters(false, false) @@ -86,12 +86,12 @@ flag.`, if len(configNames) > 0 { if err := client.RemoveConfigs(cl, context.Background(), configNames, internal.Force); err != nil { - log.Fatalf("removing configs failed: %s", err) + log.Fatal(i18n.G("removing configs failed: %s", err)) } - log.Infof("%d config(s) removed successfully", len(configNames)) + log.Info(i18n.G("%d config(s) removed successfully", len(configNames))) } else { - log.Info("no configs to remove") + log.Info(i18n.G("no configs to remove")) } secretList, err := cl.SecretList(context.Background(), types.SecretListOptions{Filters: fs}) @@ -113,10 +113,10 @@ flag.`, if err != nil { log.Fatal(err) } - log.Info(fmt.Sprintf("secret: %s removed", name)) + log.Info(i18n.G("secret: %s removed", name)) } } else { - log.Info("no secrets to remove") + log.Info(i18n.G("no secrets to remove")) } fs, err = app.Filters(false, true) @@ -133,28 +133,28 @@ flag.`, if len(volumeNames) > 0 { err := client.RemoveVolumes(cl, context.Background(), volumeNames, internal.Force, 5) if err != nil { - log.Fatalf("removing volumes failed: %s", err) + log.Fatal(i18n.G("removing volumes failed: %s", err)) } - log.Infof("%d volume(s) removed successfully", len(volumeNames)) + log.Info(i18n.G("%d volume(s) removed successfully", len(volumeNames))) } else { - log.Info("no volumes to remove") + log.Info(i18n.G("no volumes to remove")) } if err = os.Remove(app.Path); err != nil { log.Fatal(err) } - log.Info(fmt.Sprintf("file: %s removed", app.Path)) + log.Info(i18n.G("file: %s removed", app.Path)) }, } func init() { AppRemoveCommand.Flags().BoolVarP( &internal.Force, - "force", - "f", + i18n.G("force"), + i18n.G("f"), false, - "perform action without further prompt", + i18n.G("perform action without further prompt"), ) } diff --git a/cli/app/restart.go b/cli/app/restart.go index 860c77e4..bb838492 100644 --- a/cli/app/restart.go +++ b/cli/app/restart.go @@ -8,6 +8,7 @@ import ( appPkg "coopcloud.tech/abra/pkg/app" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/client" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/ui" upstream "coopcloud.tech/abra/pkg/upstream/service" @@ -17,19 +18,19 @@ import ( ) var AppRestartCommand = &cobra.Command{ - Use: "restart [[service] | --all-services] [flags]", - Aliases: []string{"re"}, - Short: "Restart an app", - Long: `This command restarts services within a deployed app. + Use: i18n.G("restart [[service] | --all-services] [flags]"), + Aliases: []string{i18n.G("re")}, + Short: i18n.G("Restart an app"), + Long: i18n.G(`This command restarts services within a deployed app. Run "abra app ps " to see a list of service names. -Pass "--all-services/-a" to restart all services.`, - Example: ` # restart a single app service +Pass "--all-services/-a" to restart all services.`), + Example: i18n.G(` # restart a single app service abra app restart 1312.net app # restart all app services - abra app restart 1312.net -a`, + abra app restart 1312.net -a`), Args: cobra.RangeArgs(1, 2), ValidArgsFunction: func( cmd *cobra.Command, @@ -60,11 +61,11 @@ Pass "--all-services/-a" to restart all services.`, } if serviceName == "" && !allServices { - log.Fatal("missing [service]") + log.Fatal(i18n.G("missing [service]")) } if serviceName != "" && allServices { - log.Fatal("cannot use [service] and --all-services/-a together") + log.Fatal(i18n.G("cannot use [service] and --all-services/-a together")) } var serviceNames []string @@ -89,7 +90,7 @@ Pass "--all-services/-a" to restart all services.`, } if !deployMeta.IsDeployed { - log.Fatalf("%s is not deployed?", app.Name) + log.Fatal(i18n.G("%s is not deployed?", app.Name)) } for _, serviceName := range serviceNames { @@ -104,7 +105,7 @@ Pass "--all-services/-a" to restart all services.`, log.Fatal(err) } - log.Debugf("attempting to scale %s to 0", stackServiceName) + log.Debug(i18n.G("attempting to scale %s to 0", stackServiceName)) if err := upstream.RunServiceScale(context.Background(), cl, stackServiceName, 0); err != nil { log.Fatal(err) @@ -128,8 +129,8 @@ Pass "--all-services/-a" to restart all services.`, log.Fatal(err) } - log.Debugf("%s has been scaled to 0", stackServiceName) - log.Debugf("attempting to scale %s to 1", stackServiceName) + log.Debug(i18n.G("%s has been scaled to 0", stackServiceName)) + log.Debug(i18n.G("attempting to scale %s to 1", stackServiceName)) if err := upstream.RunServiceScale(context.Background(), cl, stackServiceName, 1); err != nil { log.Fatal(err) @@ -139,8 +140,8 @@ Pass "--all-services/-a" to restart all services.`, log.Fatal(err) } - log.Debugf("%s has been scaled to 1", stackServiceName) - log.Infof("%s service successfully restarted", serviceName) + log.Debug(i18n.G("%s has been scaled to 1", stackServiceName)) + log.Info(i18n.G("%s service successfully restarted", serviceName)) } }, } @@ -150,16 +151,16 @@ var allServices bool func init() { AppRestartCommand.Flags().BoolVarP( &internal.Chaos, - "chaos", - "C", + i18n.G("chaos"), + i18n.G("C"), false, - "ignore uncommitted recipes changes", + i18n.G("ignore uncommitted recipes changes"), ) AppRestartCommand.Flags().BoolVarP( &allServices, - "all-services", - "a", + i18n.G("all-services"), + i18n.G("a"), false, - "restart all services", + i18n.G("restart all services"), ) } diff --git a/cli/app/restore.go b/cli/app/restore.go index 21b1dcc0..a51d9d21 100644 --- a/cli/app/restore.go +++ b/cli/app/restore.go @@ -7,17 +7,18 @@ import ( "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/client" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/log" "github.com/spf13/cobra" ) var AppRestoreCommand = &cobra.Command{ - Use: "restore [flags]", - Aliases: []string{"rs"}, - Short: "Restore a snapshot", - Long: `Snapshots are restored while apps are deployed. + Use: i18n.G("restore [flags]"), + Aliases: []string{i18n.G("rs")}, + Short: i18n.G("Restore a snapshot"), + Long: i18n.G(`Snapshots are restored while apps are deployed. -Some restore scenarios may require service / app restarts.`, +Some restore scenarios may require service / app restarts.`), Args: cobra.ExactArgs(1), ValidArgsFunction: func( cmd *cobra.Command, @@ -48,34 +49,34 @@ Some restore scenarios may require service / app restarts.`, } if snapshot != "" { - log.Debugf("including SNAPSHOT=%s in backupbot exec invocation", snapshot) + log.Debug(i18n.G("including SNAPSHOT=%s in backupbot exec invocation", snapshot)) execEnv = append(execEnv, fmt.Sprintf("SNAPSHOT=%s", snapshot)) } if targetPath != "" { - log.Debugf("including TARGET=%s in backupbot exec invocation", targetPath) + log.Debug(i18n.G("including TARGET=%s in backupbot exec invocation", targetPath)) execEnv = append(execEnv, fmt.Sprintf("TARGET=%s", targetPath)) } if internal.NoInput { - log.Debugf("including NONINTERACTIVE=%v in backupbot exec invocation", internal.NoInput) + log.Debug(i18n.G("including NONINTERACTIVE=%v in backupbot exec invocation", internal.NoInput)) execEnv = append(execEnv, fmt.Sprintf("NONINTERACTIVE=%v", internal.NoInput)) } if len(volumes) > 0 { allVolumes := strings.Join(volumes, ",") - log.Debugf("including VOLUMES=%s in backupbot exec invocation", allVolumes) + log.Debug(i18n.G("including VOLUMES=%s in backupbot exec invocation", allVolumes)) execEnv = append(execEnv, fmt.Sprintf("VOLUMES=%s", allVolumes)) } if len(services) > 0 { allServices := strings.Join(services, ",") - log.Debugf("including CONTAINER=%s in backupbot exec invocation", allServices) + log.Debug(i18n.G("including CONTAINER=%s in backupbot exec invocation", allServices)) execEnv = append(execEnv, fmt.Sprintf("CONTAINER=%s", allServices)) } if hooks { - log.Debugf("including NO_COMMANDS=%v in backupbot exec invocation", false) + log.Debug(i18n.G("including NO_COMMANDS=%v in backupbot exec invocation", false)) execEnv = append(execEnv, fmt.Sprintf("NO_COMMANDS=%v", false)) } @@ -95,41 +96,41 @@ var ( func init() { AppRestoreCommand.Flags().StringVarP( &targetPath, - "target", - "t", + i18n.G("target"), + i18n.G("t"), "/", - "target path", + i18n.G("target path"), ) AppRestoreCommand.Flags().StringArrayVarP( &services, - "services", - "s", + i18n.G("services"), + i18n.G("s"), []string{}, - "restore specific services", + i18n.G("restore specific services"), ) AppRestoreCommand.Flags().StringArrayVarP( &volumes, - "volumes", - "v", + i18n.G("volumes"), + i18n.G("v"), []string{}, - "restore specific volumes", + i18n.G("restore specific volumes"), ) AppRestoreCommand.Flags().BoolVarP( &hooks, - "hooks", - "H", + i18n.G("hooks"), + i18n.G("H"), false, - "enable pre/post-hook command execution", + i18n.G("enable pre/post-hook command execution"), ) AppRestoreCommand.Flags().BoolVarP( &internal.Chaos, - "chaos", - "C", + i18n.G("chaos"), + i18n.G("C"), false, - "ignore uncommitted recipes changes", + i18n.G("ignore uncommitted recipes changes"), ) } diff --git a/cli/app/rollback.go b/cli/app/rollback.go index 7bdebf94..0218dd0a 100644 --- a/cli/app/rollback.go +++ b/cli/app/rollback.go @@ -1,7 +1,7 @@ package app import ( - "fmt" + "errors" "coopcloud.tech/abra/pkg/app" appPkg "coopcloud.tech/abra/pkg/app" @@ -9,6 +9,7 @@ import ( "coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/envfile" "coopcloud.tech/abra/pkg/formatter" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/lint" stack "coopcloud.tech/abra/pkg/upstream/stack" "coopcloud.tech/tagcmp" @@ -21,10 +22,10 @@ import ( ) var AppRollbackCommand = &cobra.Command{ - Use: "rollback [version] [flags]", - Aliases: []string{"rl"}, - Short: "Roll an app back to a previous version", - Long: `This command rolls an app back to a previous version. + Use: i18n.G("rollback [version] [flags]"), + Aliases: []string{i18n.G("rl")}, + Short: i18n.G("Roll an app back to a previous version"), + Long: i18n.G(`This command rolls an app back to a previous version. Unlike "abra app deploy", chaos operations are not supported here. Only recipe versions are supported values for "[version]". @@ -37,12 +38,12 @@ are available. The live deployment version is the "source of truth" in this case. The stored .env version is not consulted. A downgrade can be destructive, please ensure you have a copy of your app data -beforehand. See "abra app backup" for more.`, - Example: ` # standard rollback +beforehand. See "abra app backup" for more.`), + Example: i18n.G(` # standard rollback abra app rollback 1312.net # rollback to specific version - abra app rollback 1312.net 2.0.0+1.2.3`, + abra app rollback 1312.net 2.0.0+1.2.3`), Args: cobra.RangeArgs(1, 2), ValidArgsFunction: func( cmd *cobra.Command, @@ -54,8 +55,7 @@ beforehand. See "abra app backup" for more.`, case 1: app, err := appPkg.Get(args[0]) if err != nil { - errMsg := fmt.Sprintf("autocomplete failed: %s", err) - return []string{errMsg}, cobra.ShellCompDirectiveError + return []string{i18n.G("autocomplete failed: %s", err)}, cobra.ShellCompDirectiveError } return autocomplete.RecipeVersionComplete(app.Recipe.Name) default: @@ -117,7 +117,7 @@ beforehand. See "abra app backup" for more.`, } if !downgradeAvailable { - log.Info("no available downgrades") + log.Info(i18n.G("no available downgrades")) return } } @@ -139,10 +139,10 @@ beforehand. See "abra app backup" for more.`, } if chosenDowngrade == "" { - log.Fatal("unknown deployed version, unable to downgrade") + log.Fatal(i18n.G("unknown deployed version, unable to downgrade")) } - log.Debugf("choosing %s as version to rollback", chosenDowngrade) + log.Debug(i18n.G("choosing %s as version to rollback", chosenDowngrade)) if _, err := app.Recipe.EnsureVersion(chosenDowngrade); err != nil { log.Fatal(err) @@ -199,7 +199,7 @@ beforehand. See "abra app backup" for more.`, log.Fatal(err) } - log.Debugf("set waiting timeout to %d second(s)", stack.WaitTimeout) + log.Debug(i18n.G("set waiting timeout to %d second(s)", stack.WaitTimeout)) serviceNames, err := appPkg.GetAppServiceNames(app.Name) if err != nil { @@ -224,7 +224,7 @@ beforehand. See "abra app backup" for more.`, } if err := app.WriteRecipeVersion(chosenDowngrade, false); err != nil { - log.Fatalf("writing recipe version failed: %s", err) + log.Fatal(i18n.G("writing recipe version failed: %s", err)) } }, } @@ -235,12 +235,12 @@ func chooseDowngrade( deployMeta stack.DeployMeta, chosenDowngrade *string, ) error { - msg := fmt.Sprintf("please select a downgrade (version: %s):", deployMeta.Version) + msg := i18n.G("please select a downgrade (version: %s):", deployMeta.Version) if deployMeta.IsChaos { chaosVersion := formatter.BoldDirtyDefault(deployMeta.ChaosVersion) - msg = fmt.Sprintf( + msg = i18n.G( "please select a downgrade (version: %s, chaos: %s):", deployMeta.Version, chaosVersion, @@ -267,21 +267,21 @@ func validateDowngradeVersionArg( ) error { parsedDeployedVersion, err := tagcmp.Parse(deployMeta.Version) if err != nil { - return fmt.Errorf("current deployment '%s' is not a known version for %s", deployMeta.Version, app.Recipe.Name) + return errors.New(i18n.G("current deployment '%s' is not a known version for %s", deployMeta.Version, app.Recipe.Name)) } parsedSpecificVersion, err := tagcmp.Parse(specificVersion) if err != nil { - return fmt.Errorf("'%s' is not a known version for %s", specificVersion, app.Recipe.Name) + return errors.New(i18n.G("'%s' is not a known version for %s", specificVersion, app.Recipe.Name)) } if parsedSpecificVersion.IsGreaterThan(parsedDeployedVersion) && !parsedSpecificVersion.Equals(parsedDeployedVersion) { - return fmt.Errorf("%s is not a downgrade for %s?", deployMeta.Version, specificVersion) + return errors.New(i18n.G("%s is not a downgrade for %s?", deployMeta.Version, specificVersion)) } if parsedSpecificVersion.Equals(parsedDeployedVersion) && !internal.Force { - return fmt.Errorf("%s is not a downgrade for %s?", deployMeta.Version, specificVersion) + return errors.New(i18n.G("%s is not a downgrade for %s?", deployMeta.Version, specificVersion)) } return nil @@ -320,24 +320,25 @@ func ensureDowngradesAvailable( func init() { AppRollbackCommand.Flags().BoolVarP( &internal.Force, - "force", - "f", + i18n.G("force"), + i18n.G("f"), false, - "perform action without further prompt", + i18n.G("perform action without further prompt"), ) AppRollbackCommand.Flags().BoolVarP( &internal.NoDomainChecks, - "no-domain-checks", - "D", + i18n.G("no-domain-checks"), + i18n.G("D"), false, - "disable public DNS checks", + i18n.G("disable public DNS checks"), ) AppRollbackCommand.Flags().BoolVarP( - &internal.DontWaitConverge, "no-converge-checks", - "c", + &internal.DontWaitConverge, + i18n.G("no-converge-checks"), + i18n.G("c"), false, - "disable converge logic checks", + i18n.G("disable converge logic checks"), ) } diff --git a/cli/app/run.go b/cli/app/run.go index 21c0f1ea..a0f4a1a9 100644 --- a/cli/app/run.go +++ b/cli/app/run.go @@ -8,6 +8,7 @@ import ( "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/client" containerPkg "coopcloud.tech/abra/pkg/container" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/upstream/container" "github.com/docker/cli/cli/command" @@ -17,17 +18,17 @@ import ( ) var AppRunCommand = &cobra.Command{ - Use: "run [[args] [flags] | [flags] -- [args]]", - Aliases: []string{"r"}, - Short: "Run a command inside a service container", - Example: ` # run with args/flags + Use: i18n.G("run [[args] [flags] | [flags] -- [args]]"), + Aliases: []string{i18n.G("r")}, + Short: i18n.G("Run a command inside a service container"), + Example: i18n.G(` # run with args/flags abra app run 1312.net app -- ls -lha # run without args/flags abra app run 1312.net app bash --user nobody # run with both kinds of args/flags - abra app run 1312.net app --user nobody -- ls -lha`, + abra app run 1312.net app --user nobody -- ls -lha`), Args: cobra.MinimumNArgs(3), ValidArgsFunction: func( cmd *cobra.Command, @@ -98,17 +99,17 @@ var ( func init() { AppRunCommand.Flags().BoolVarP(&noTTY, - "no-tty", - "t", + i18n.G("no-tty"), + i18n.G("t"), false, - "do not request a TTY", + i18n.G("do not request a TTY"), ) AppRunCommand.Flags().StringVarP( &runAsUser, - "user", - "u", + i18n.G("user"), + i18n.G("u"), "", - "run command as user", + i18n.G("run command as user"), ) } diff --git a/cli/app/secret.go b/cli/app/secret.go index 6b5da2a2..550714b2 100644 --- a/cli/app/secret.go +++ b/cli/app/secret.go @@ -12,6 +12,7 @@ import ( "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/formatter" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/secret" "github.com/docker/docker/api/types" @@ -20,9 +21,9 @@ import ( ) var AppSecretGenerateCommand = &cobra.Command{ - Use: "generate [[secret] [version] | --all] [flags]", - Aliases: []string{"g"}, - Short: "Generate secrets", + Use: i18n.G("generate [[secret] [version] | --all] [flags]"), + Aliases: []string{i18n.G("g")}, + Short: i18n.G("Generate secrets"), Args: cobra.RangeArgs(1, 3), ValidArgsFunction: func( cmd *cobra.Command, @@ -34,8 +35,7 @@ var AppSecretGenerateCommand = &cobra.Command{ case 1: app, err := appPkg.Get(args[0]) if err != nil { - errMsg := fmt.Sprintf("autocomplete failed: %s", err) - return []string{errMsg}, cobra.ShellCompDirectiveError + return []string{i18n.G("autocomplete failed: %s", err)}, cobra.ShellCompDirectiveError } return autocomplete.SecretComplete(app.Recipe.Name) default: @@ -50,11 +50,11 @@ var AppSecretGenerateCommand = &cobra.Command{ } if len(args) <= 2 && !generateAllSecrets { - log.Fatal("missing arguments [secret]/[version] or '--all'") + log.Fatal(i18n.G("missing arguments [secret]/[version] or '--all'")) } if len(args) > 2 && generateAllSecrets { - log.Fatal("cannot use '[secret] [version]' and '--all' together") + log.Fatal(i18n.G("cannot use '[secret] [version]' and '--all' together")) } composeFiles, err := app.Recipe.GetComposeFiles(app.Env) @@ -72,7 +72,7 @@ var AppSecretGenerateCommand = &cobra.Command{ secretVersion := args[2] s, ok := secrets[secretName] if !ok { - log.Fatalf("%s doesn't exist in the env config?", secretName) + log.Fatal(i18n.G("%s doesn't exist in the env config?", secretName)) } s.Version = secretVersion secrets = map[string]secret.Secret{ @@ -99,11 +99,11 @@ var AppSecretGenerateCommand = &cobra.Command{ } if len(secretVals) == 0 { - log.Warn("no secrets generated") + log.Warn(i18n.G("no secrets generated")) os.Exit(1) } - headers := []string{"NAME", "VALUE"} + headers := []string{i18n.G("NAME"), i18n.G("VALUE")} table, err := formatter.CreateTable() if err != nil { log.Fatal(err) @@ -121,7 +121,7 @@ var AppSecretGenerateCommand = &cobra.Command{ if internal.MachineReadable { out, err := formatter.ToJSON(headers, rows) if err != nil { - log.Fatal("unable to render to JSON: %s", err) + log.Fatal(i18n.G("unable to render to JSON: %s", err)) } fmt.Println(out) return @@ -131,31 +131,31 @@ var AppSecretGenerateCommand = &cobra.Command{ log.Fatal(err) } - log.Warnf( + log.Warn(i18n.G( "generated secrets %s shown again, please take note of them %s", - formatter.BoldStyle.Render("NOT"), - formatter.BoldStyle.Render("NOW"), - ) + formatter.BoldStyle.Render(i18n.G("NOT")), + formatter.BoldStyle.Render(i18n.G("NOW")), + )) }, } var AppSecretInsertCommand = &cobra.Command{ - Use: "insert [flags]", - Aliases: []string{"i"}, - Short: "Insert secret", - Long: `This command inserts a secret into an app environment. + Use: i18n.G("insert [flags]"), + Aliases: []string{i18n.G("i")}, + Short: i18n.G("Insert secret"), + Long: i18n.G(`This command inserts a secret into an app environment. Arbitrary secret insertion is not supported. Secrets that are inserted must match those configured in the recipe beforehand. This can be useful when you want to manually generate secrets for an app environment. Typically, you can let Abra generate them for you on app creation -(see "abra app new --secrets/-S" for more).`, - Example: ` # insert regular secret +(see "abra app new --secrets/-S" for more).`), + Example: i18n.G(` # insert regular secret abra app secret insert 1312.net my_secret v1 mySuperSecret # insert secret as file - abra app secret insert 1312.net my_secret v1 secret.txt -f`, + abra app secret insert 1312.net my_secret v1 secret.txt -f`), Args: cobra.MinimumNArgs(4), ValidArgsFunction: func( cmd *cobra.Command, @@ -167,8 +167,7 @@ environment. Typically, you can let Abra generate them for you on app creation case 1: app, err := appPkg.Get(args[0]) if err != nil { - errMsg := fmt.Sprintf("autocomplete failed: %s", err) - return []string{errMsg}, cobra.ShellCompDirectiveError + return []string{i18n.G("autocomplete failed: %s", err)}, cobra.ShellCompDirectiveError } return autocomplete.SecretComplete(app.Recipe.Name) default: @@ -208,13 +207,13 @@ environment. Typically, you can let Abra generate them for you on app creation } } if !isRecipeSecret { - log.Fatalf("no secret %s available for recipe %s?", name, app.Recipe.Name) + log.Fatal(i18n.G("no secret %s available for recipe %s?", name, app.Recipe.Name)) } if insertFromFile { raw, err := os.ReadFile(data) if err != nil { - log.Fatalf("reading secret from file: %s", err) + log.Fatal(i18n.G("reading secret from file: %s", err)) } data = string(raw) } @@ -228,7 +227,7 @@ environment. Typically, you can let Abra generate them for you on app creation log.Fatal(err) } - log.Infof("%s successfully stored on server", secretName) + log.Info(i18n.G("%s successfully stored on server", secretName)) if storeInPass { if err := secret.PassInsertSecret(data, name, app.Name, app.Server); err != nil { @@ -244,28 +243,28 @@ func secretRm(cl *dockerClient.Client, app appPkg.App, secretName, parsed string return err } - log.Infof("deleted %s successfully from server", secretName) + log.Info(i18n.G("deleted %s successfully from server", secretName)) if removeFromPass { if err := secret.PassRmSecret(parsed, app.StackName(), app.Server); err != nil { return err } - log.Infof("deleted %s successfully from local pass store", secretName) + log.Info(i18n.G("deleted %s successfully from local pass store", secretName)) } return nil } var AppSecretRmCommand = &cobra.Command{ - Use: "remove [[secret] | --all] [flags]", - Aliases: []string{"rm"}, - Short: "Remove a secret", - Long: `This command removes a secret from an app environment. + Use: i18n.G("remove [[secret] | --all] [flags]"), + Aliases: []string{i18n.G("rm")}, + Short: i18n.G("Remove a secret"), + Long: i18n.G(`This command removes a secret from an app environment. Arbitrary secret removal is not supported. Secrets that are removed must -match those configured in the recipe beforehand.`, - Example: " abra app secret rm 1312.net oauth_key", +match those configured in the recipe beforehand.`), + Example: i18n.G(" abra app secret rm 1312.net oauth_key"), Args: cobra.RangeArgs(1, 2), ValidArgsFunction: func( cmd *cobra.Command, @@ -278,8 +277,7 @@ match those configured in the recipe beforehand.`, if !rmAllSecrets { app, err := appPkg.Get(args[0]) if err != nil { - errMsg := fmt.Sprintf("autocomplete failed: %s", err) - return []string{errMsg}, cobra.ShellCompDirectiveError + return []string{i18n.G("autocomplete failed: %s", err)}, cobra.ShellCompDirectiveError } return autocomplete.SecretComplete(app.Recipe.Name) } @@ -306,11 +304,11 @@ match those configured in the recipe beforehand.`, } if len(args) == 2 && rmAllSecrets { - log.Fatal("cannot use [secret] and --all/-a together") + log.Fatal(i18n.G("cannot use [secret] and --all/-a together")) } if len(args) != 2 && !rmAllSecrets { - log.Fatal("no secret(s) specified?") + log.Fatal(i18n.G("no secret(s) specified?")) } cl, err := client.New(app.Server) @@ -361,19 +359,19 @@ match those configured in the recipe beforehand.`, } if !match && secretToRm != "" { - log.Fatalf("%s doesn't exist on server?", secretToRm) + log.Fatal(i18n.G("%s doesn't exist on server?", secretToRm)) } if !match { - log.Fatal("no secrets to remove?") + log.Fatal(i18n.G("no secrets to remove?")) } }, } var AppSecretLsCommand = &cobra.Command{ - Use: "list ", - Aliases: []string{"ls"}, - Short: "List all secrets", + Use: i18n.G("list "), + Aliases: []string{i18n.G("ls")}, + Short: i18n.G("List all secrets"), Args: cobra.MinimumNArgs(1), ValidArgsFunction: func( cmd *cobra.Command, @@ -393,7 +391,7 @@ var AppSecretLsCommand = &cobra.Command{ log.Fatal(err) } - headers := []string{"NAME", "VERSION", "GENERATED NAME", "CREATED ON SERVER"} + headers := []string{i18n.G("NAME"), i18n.G("VERSION"), i18n.G("GENERATED NAME"), i18n.G("CREATED ON SERVER")} table, err := formatter.CreateTable() if err != nil { log.Fatal(err) @@ -423,7 +421,7 @@ var AppSecretLsCommand = &cobra.Command{ if internal.MachineReadable { out, err := formatter.ToJSON(headers, rows) if err != nil { - log.Fatal("unable to render to JSON: %s", err) + log.Fatal(i18n.G("unable to render to JSON: %s", err)) } fmt.Println(out) return @@ -436,14 +434,14 @@ var AppSecretLsCommand = &cobra.Command{ return } - log.Warnf("no secrets stored for %s", app.Name) + log.Warn(i18n.G("no secrets stored for %s", app.Name)) }, } var AppSecretCommand = &cobra.Command{ - Use: "secret [cmd] [args] [flags]", - Aliases: []string{"s"}, - Short: "Manage app secrets", + Use: i18n.G("secret [cmd] [args] [flags]"), + Aliases: []string{i18n.G("s")}, + Short: i18n.G("Manage app secrets"), } var ( @@ -458,105 +456,105 @@ var ( func init() { AppSecretGenerateCommand.Flags().BoolVarP( &internal.MachineReadable, - "machine", - "m", + i18n.G("machine"), + i18n.G("m"), false, - "print machine-readable output", + i18n.G("print machine-readable output"), ) AppSecretGenerateCommand.Flags().BoolVarP( &storeInPass, - "pass", - "p", + i18n.G("pass"), + i18n.G("p"), false, - "store generated secrets in a local pass store", + i18n.G("store generated secrets in a local pass store"), ) AppSecretGenerateCommand.Flags().BoolVarP( &internal.Chaos, - "chaos", - "C", + i18n.G("chaos"), + i18n.G("C"), false, - "ignore uncommitted recipes changes", + i18n.G("ignore uncommitted recipes changes"), ) AppSecretGenerateCommand.Flags().BoolVarP( &generateAllSecrets, - "all", - "a", + i18n.G("all"), + i18n.G("a"), false, - "generate all secrets", + i18n.G("generate all secrets"), ) AppSecretInsertCommand.Flags().BoolVarP( &storeInPass, - "pass", - "p", + i18n.G("pass"), + i18n.G("p"), false, - "store generated secrets in a local pass store", + i18n.G("store generated secrets in a local pass store"), ) AppSecretInsertCommand.Flags().BoolVarP( &insertFromFile, - "file", - "f", + i18n.G("file"), + i18n.G("f"), false, - "treat input as a file", + i18n.G("treat input as a file"), ) AppSecretInsertCommand.Flags().BoolVarP( &trimInput, - "trim", - "t", + i18n.G("trim"), + i18n.G("t"), false, - "trim input", + i18n.G("trim input"), ) AppSecretInsertCommand.Flags().BoolVarP( &internal.Chaos, - "chaos", - "C", + i18n.G("chaos"), + i18n.G("C"), false, - "ignore uncommitted recipes changes", + i18n.G("ignore uncommitted recipes changes"), ) AppSecretRmCommand.Flags().BoolVarP( &rmAllSecrets, - "all", - "a", + i18n.G("all"), + i18n.G("a"), false, - "remove all secrets", + i18n.G("remove all secrets"), ) AppSecretRmCommand.Flags().BoolVarP( &removeFromPass, - "pass", - "p", + i18n.G("pass"), + i18n.G("p"), false, - "remove generated secrets from a local pass store", + i18n.G("remove generated secrets from a local pass store"), ) AppSecretRmCommand.Flags().BoolVarP( &internal.Chaos, - "chaos", - "C", + i18n.G("chaos"), + i18n.G("C"), false, - "ignore uncommitted recipes changes", + i18n.G("ignore uncommitted recipes changes"), ) AppSecretLsCommand.Flags().BoolVarP( &internal.Chaos, - "chaos", - "C", + i18n.G("chaos"), + i18n.G("C"), false, - "ignore uncommitted recipes changes", + i18n.G("ignore uncommitted recipes changes"), ) AppSecretLsCommand.Flags().BoolVarP( &internal.MachineReadable, - "machine", - "m", + i18n.G("machine"), + i18n.G("m"), false, - "print machine-readable output", + i18n.G("print machine-readable output"), ) } diff --git a/cli/app/services.go b/cli/app/services.go index a49eba9c..4843ea86 100644 --- a/cli/app/services.go +++ b/cli/app/services.go @@ -9,6 +9,7 @@ import ( "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/formatter" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/service" stack "coopcloud.tech/abra/pkg/upstream/stack" @@ -17,9 +18,9 @@ import ( ) var AppServicesCommand = &cobra.Command{ - Use: "services [flags]", - Aliases: []string{"sr"}, - Short: "Display all services of an app", + Use: i18n.G("services [flags]"), + Aliases: []string{i18n.G("sr")}, + Short: i18n.G("Display all services of an app"), Args: cobra.ExactArgs(1), ValidArgsFunction: func( cmd *cobra.Command, @@ -45,7 +46,7 @@ var AppServicesCommand = &cobra.Command{ } if !deployMeta.IsDeployed { - log.Fatalf("%s is not deployed?", app.Name) + log.Fatal(i18n.G("%s is not deployed?", app.Name)) } filters, err := app.Filters(true, true) @@ -63,7 +64,7 @@ var AppServicesCommand = &cobra.Command{ log.Fatal(err) } - headers := []string{"SERVICE (SHORT)", "SERVICE (LONG)"} + headers := []string{i18n.G("SERVICE (SHORT)"), i18n.G("SERVICE (LONG)")} table.Headers(headers...) var rows [][]string diff --git a/cli/app/undeploy.go b/cli/app/undeploy.go index 12aba61c..ecb32365 100644 --- a/cli/app/undeploy.go +++ b/cli/app/undeploy.go @@ -10,6 +10,7 @@ import ( "coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/formatter" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/log" stack "coopcloud.tech/abra/pkg/upstream/stack" "github.com/docker/docker/api/types/filters" @@ -18,15 +19,15 @@ import ( ) var AppUndeployCommand = &cobra.Command{ - Use: "undeploy [flags]", - Aliases: []string{"un"}, - Short: "Undeploy an app", - Long: `This does not destroy any application data. + Use: i18n.G("undeploy [flags]"), + Aliases: []string{i18n.G("un")}, + Short: i18n.G("Undeploy an app"), + Long: i18n.G(`This does not destroy any application data. However, you should remain vigilant, as your swarm installation will consider any previously attached volumes as eligible for pruning once undeployed. -Passing "--prune/-p" does not remove those volumes.`, +Passing "--prune/-p" does not remove those volumes.`), Args: cobra.ExactArgs(1), ValidArgsFunction: func( cmd *cobra.Command, @@ -47,7 +48,7 @@ Passing "--prune/-p" does not remove those volumes.`, log.Fatal(err) } - log.Debugf("checking whether %s is already deployed", stackName) + log.Debug(i18n.G("checking whether %s is already deployed", stackName)) deployMeta, err := stack.IsDeployed(context.Background(), cl, stackName) if err != nil { @@ -55,7 +56,7 @@ Passing "--prune/-p" does not remove those volumes.`, } if !deployMeta.IsDeployed { - log.Fatalf("%s is not deployed?", app.Name) + log.Fatal(i18n.G("%s is not deployed?", app.Name)) } if err := internal.DeployOverview( @@ -84,7 +85,7 @@ Passing "--prune/-p" does not remove those volumes.`, log.Fatal(err) } - log.Info("initialising undeploy") + log.Info(i18n.G("initialising undeploy")) rmOpts := stack.Remove{ Namespaces: []string{stackName}, @@ -100,10 +101,10 @@ Passing "--prune/-p" does not remove those volumes.`, } } - log.Info("undeploy succeeded 🟢") + log.Info(i18n.G("undeploy succeeded 🟢")) if err := app.WriteRecipeVersion(deployMeta.Version, false); err != nil { - log.Fatalf("writing recipe version failed: %s", err) + log.Fatal(i18n.G("writing recipe version failed: %s", err)) } }, } @@ -124,14 +125,14 @@ func pruneApp(cl *dockerClient.Client, app appPkg.App) error { } cntSpaceReclaimed := formatter.ByteCountSI(cr.SpaceReclaimed) - log.Infof("containers pruned: %d; space reclaimed: %s", len(cr.ContainersDeleted), cntSpaceReclaimed) + log.Info(i18n.G("containers pruned: %d; space reclaimed: %s", len(cr.ContainersDeleted), cntSpaceReclaimed)) nr, err := cl.NetworksPrune(ctx, pruneFilters) if err != nil { return err } - log.Infof("networks pruned: %d", len(nr.NetworksDeleted)) + log.Info(i18n.G("networks pruned: %d", len(nr.NetworksDeleted))) ir, err := cl.ImagesPrune(ctx, pruneFilters) if err != nil { @@ -139,7 +140,7 @@ func pruneApp(cl *dockerClient.Client, app appPkg.App) error { } imgSpaceReclaimed := formatter.ByteCountSI(ir.SpaceReclaimed) - log.Infof("images pruned: %d; space reclaimed: %s", len(ir.ImagesDeleted), imgSpaceReclaimed) + log.Info(i18n.G("images pruned: %d; space reclaimed: %s", len(ir.ImagesDeleted), imgSpaceReclaimed)) return nil } @@ -151,9 +152,9 @@ var ( func init() { AppUndeployCommand.Flags().BoolVarP( &prune, - "prune", - "p", + i18n.G("prune"), + i18n.G("p"), false, - "prune unused containers, networks, and dangling images", + i18n.G("prune unused containers, networks, and dangling images"), ) } diff --git a/cli/app/upgrade.go b/cli/app/upgrade.go index 5e6ef87d..be574c45 100644 --- a/cli/app/upgrade.go +++ b/cli/app/upgrade.go @@ -2,6 +2,7 @@ package app import ( "context" + "errors" "fmt" "strings" @@ -13,6 +14,7 @@ import ( "coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/envfile" "coopcloud.tech/abra/pkg/formatter" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/lint" "coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/recipe" @@ -24,10 +26,10 @@ import ( ) var AppUpgradeCommand = &cobra.Command{ - Use: "upgrade [version] [flags]", - Aliases: []string{"up"}, - Short: "Upgrade an app", - Long: `Upgrade an app. + Use: i18n.G("upgrade [version] [flags]"), + Aliases: []string{i18n.G("up")}, + Short: i18n.G("Upgrade an app"), + Long: i18n.G(`Upgrade an app. Unlike "abra app deploy", chaos operations are not supported here. Only recipe versions are supported values for "[version]". @@ -40,7 +42,7 @@ are available. The live deployment version is the "source of truth" in this case. The stored .env version is not consulted. An upgrade can be destructive, please ensure you have a copy of your app data -beforehand. See "abra app backup" for more.`, +beforehand. See "abra app backup" for more.`), Args: cobra.RangeArgs(1, 2), ValidArgsFunction: func( cmd *cobra.Command, @@ -53,8 +55,7 @@ beforehand. See "abra app backup" for more.`, case 1: app, err := appPkg.Get(args[0]) if err != nil { - errMsg := fmt.Sprintf("autocomplete failed: %s", err) - return []string{errMsg}, cobra.ShellCompDirectiveError + return []string{i18n.G("autocomplete failed: %s", err)}, cobra.ShellCompDirectiveError } return autocomplete.RecipeVersionComplete(app.Recipe.Name) default: @@ -123,7 +124,7 @@ beforehand. See "abra app backup" for more.`, } if !upgradeAvailable { - log.Info("no available upgrades") + log.Info(i18n.G("no available upgrades")) return } } @@ -145,10 +146,10 @@ beforehand. See "abra app backup" for more.`, } if chosenUpgrade == "" { - log.Fatal("unknown deployed version, unable to upgrade") + log.Fatal(i18n.G("unknown deployed version, unable to upgrade")) } - log.Debugf("choosing %s as version to upgrade", chosenUpgrade) + log.Debug(i18n.G("choosing %s as version to upgrade", chosenUpgrade)) // Get the release notes before checking out the new version in the // recipe. This enables us to get release notes, that were added after @@ -204,7 +205,7 @@ beforehand. See "abra app backup" for more.`, for _, envVar := range envVars { if !envVar.Present { upgradeWarnMessages = append(upgradeWarnMessages, - fmt.Sprintf("%s missing from %s.env", envVar.Name, app.Domain), + i18n.G("%s missing from %s.env", envVar.Name, app.Domain), ) } } @@ -236,7 +237,7 @@ beforehand. See "abra app backup" for more.`, log.Fatal(err) } - log.Debugf("set waiting timeout to %d second(s)", stack.WaitTimeout) + log.Debug(i18n.G("set waiting timeout to %d second(s)", stack.WaitTimeout)) serviceNames, err := appPkg.GetAppServiceNames(app.Name) if err != nil { @@ -262,15 +263,15 @@ beforehand. See "abra app backup" for more.`, postDeployCmds, ok := app.Env["POST_UPGRADE_CMDS"] if ok && !internal.DontWaitConverge { - log.Debugf("run the following post-deploy commands: %s", postDeployCmds) + log.Debug(i18n.G("run the following post-deploy commands: %s", postDeployCmds)) if err := internal.PostCmds(cl, app, postDeployCmds); err != nil { - log.Fatalf("attempting to run post deploy commands, saw: %s", err) + log.Fatal(i18n.G("attempting to run post deploy commands, saw: %s", err)) } } if err := app.WriteRecipeVersion(chosenUpgrade, false); err != nil { - log.Fatalf("writing recipe version failed: %s", err) + log.Fatal(i18n.G("writing recipe version failed: %s", err)) } }, } @@ -281,12 +282,12 @@ func chooseUpgrade( deployMeta stack.DeployMeta, chosenUpgrade *string, ) error { - msg := fmt.Sprintf("please select an upgrade (version: %s):", deployMeta.Version) + msg := i18n.G("please select an upgrade (version: %s):", deployMeta.Version) if deployMeta.IsChaos { chaosVersion := formatter.BoldDirtyDefault(deployMeta.ChaosVersion) - msg = fmt.Sprintf( + msg = i18n.G( "please select an upgrade (version: %s, chaos: %s):", deployMeta.Version, chaosVersion, @@ -314,18 +315,18 @@ func getReleaseNotes( ) error { parsedChosenUpgrade, err := tagcmp.Parse(chosenUpgrade) if err != nil { - return fmt.Errorf("parsing chosen upgrade version failed: %s", err) + return errors.New(i18n.G("parsing chosen upgrade version failed: %s", err)) } parsedDeployedVersion, err := tagcmp.Parse(deployMeta.Version) if err != nil { - return fmt.Errorf("parsing deployment version failed: %s", err) + return errors.New(i18n.G("parsing deployment version failed: %s", err)) } for _, version := range internal.SortVersionsDesc(versions) { parsedVersion, err := tagcmp.Parse(version) if err != nil { - return fmt.Errorf("parsing recipe version failed: %s", err) + return errors.New(i18n.G("parsing recipe version failed: %s", err)) } if parsedVersion.IsGreaterThan(parsedDeployedVersion) && @@ -358,13 +359,13 @@ func ensureUpgradesAvailable( ) (bool, error) { parsedDeployedVersion, err := tagcmp.Parse(deployMeta.Version) if err != nil { - return false, fmt.Errorf("parsing deployed version failed: %s", err) + return false, errors.New(i18n.G("parsing deployed version failed: %s", err)) } for _, version := range versions { parsedVersion, err := tagcmp.Parse(version) if err != nil { - return false, fmt.Errorf("parsing recipe version failed: %s", err) + return false, errors.New(i18n.G("parsing recipe version failed: %s", err)) } if parsedVersion.IsGreaterThan(parsedDeployedVersion) && @@ -388,21 +389,21 @@ func validateUpgradeVersionArg( ) error { parsedSpecificVersion, err := tagcmp.Parse(specificVersion) if err != nil { - return fmt.Errorf("'%s' is not a known version for %s", specificVersion, app.Recipe.Name) + return errors.New(i18n.G("'%s' is not a known version for %s", specificVersion, app.Recipe.Name)) } parsedDeployedVersion, err := tagcmp.Parse(deployMeta.Version) if err != nil { - return fmt.Errorf("'%s' is not a known version", deployMeta.Version) + return errors.New(i18n.G("'%s' is not a known version", deployMeta.Version)) } if parsedSpecificVersion.IsLessThan(parsedDeployedVersion) && !parsedSpecificVersion.Equals(parsedDeployedVersion) { - return fmt.Errorf("%s is not an upgrade for %s?", deployMeta.Version, specificVersion) + return errors.New(i18n.G("%s is not an upgrade for %s?", deployMeta.Version, specificVersion)) } if parsedSpecificVersion.Equals(parsedDeployedVersion) && !internal.Force { - return fmt.Errorf("%s is not an upgrade for %s?", deployMeta.Version, specificVersion) + return errors.New(i18n.G("%s is not an upgrade for %s?", deployMeta.Version, specificVersion)) } return nil @@ -411,7 +412,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) { - log.Debugf("checking whether %s is already deployed", app.StackName()) + log.Debug(i18n.G("checking whether %s is already deployed", app.StackName())) deployMeta, err := stack.IsDeployed(context.Background(), cl, app.StackName()) if err != nil { @@ -419,7 +420,7 @@ func ensureDeployed(cl *dockerClient.Client, app app.App) (stack.DeployMeta, err } if !deployMeta.IsDeployed { - return stack.DeployMeta{}, fmt.Errorf("%s is not deployed?", app.Name) + return stack.DeployMeta{}, errors.New(i18n.G("%s is not deployed?", app.Name)) } return deployMeta, nil @@ -430,32 +431,33 @@ var showReleaseNotes bool func init() { AppUpgradeCommand.Flags().BoolVarP( &internal.Force, - "force", - "f", + i18n.G("force"), + i18n.G("f"), false, - "perform action without further prompt", + i18n.G("perform action without further prompt"), ) AppUpgradeCommand.Flags().BoolVarP( &internal.NoDomainChecks, - "no-domain-checks", - "D", + i18n.G("no-domain-checks"), + i18n.G("D"), false, - "disable public DNS checks", + i18n.G("disable public DNS checks"), ) AppUpgradeCommand.Flags().BoolVarP( - &internal.DontWaitConverge, "no-converge-checks", - "c", + &internal.DontWaitConverge, + i18n.G("no-converge-checks"), + i18n.G("c"), false, - "disable converge logic checks", + i18n.G("disable converge logic checks"), ) AppUpgradeCommand.Flags().BoolVarP( &showReleaseNotes, - "releasenotes", - "r", + i18n.G("releasenotes"), + i18n.G("r"), false, - "only show release notes", + i18n.G("only show release notes"), ) } diff --git a/cli/app/volume.go b/cli/app/volume.go index a19ab65c..bde116e6 100644 --- a/cli/app/volume.go +++ b/cli/app/volume.go @@ -8,6 +8,7 @@ import ( "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/formatter" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/upstream/stack" "github.com/AlecAivazis/survey/v2" @@ -15,9 +16,9 @@ import ( ) var AppVolumeListCommand = &cobra.Command{ - Use: "list [flags]", - Aliases: []string{"ls"}, - Short: "List volumes associated with an app", + Use: i18n.G("list [flags]"), + Aliases: []string{i18n.G("ls")}, + Short: i18n.G("List volumes associated with an app"), Args: cobra.ExactArgs(1), ValidArgsFunction: func( cmd *cobra.Command, @@ -43,7 +44,7 @@ var AppVolumeListCommand = &cobra.Command{ log.Fatal(err) } - headers := []string{"NAME", "ON SERVER"} + headers := []string{i18n.G("NAME"), i18n.G("ON SERVER")} table, err := formatter.CreateTable() if err != nil { @@ -67,14 +68,14 @@ var AppVolumeListCommand = &cobra.Command{ return } - log.Warnf("no volumes created for %s", app.Name) + log.Warn(i18n.G("no volumes created for %s", app.Name)) }, } var AppVolumeRemoveCommand = &cobra.Command{ - Use: "remove [volume] [flags]", - Short: "Remove volume(s) associated with an app", - Long: `Remove volumes associated with an app. + Use: i18n.G("remove [volume] [flags]"), + Short: i18n.G("Remove volume(s) associated with an app"), + Long: i18n.G(`Remove volumes associated with an app. The app in question must be undeployed before you try to remove volumes. See "abra app undeploy " for more. @@ -83,13 +84,13 @@ The command is interactive and will show a multiple select input which allows you to make a seclection. Use the "?" key to see more help on navigating this interface. -Passing "--force/-f" will select all volumes for removal. Be careful.`, - Example: ` # delete volumes interactively +Passing "--force/-f" will select all volumes for removal. Be careful.`), + Example: i18n.G(` # delete volumes interactively abra app volume rm 1312.net # delete specific volume - abra app volume rm 1312.net my_volume`, - Aliases: []string{"rm"}, + abra app volume rm 1312.net my_volume`), + Aliases: []string{i18n.G("rm")}, Args: cobra.MinimumNArgs(1), ValidArgsFunction: func( cmd *cobra.Command, @@ -116,7 +117,7 @@ Passing "--force/-f" will select all volumes for removal. Be careful.`, } if deployMeta.IsDeployed { - log.Fatalf("%s is still deployed. Run \"abra app undeploy %s\"", app.Name, app.Name) + log.Fatal(i18n.G("%s is still deployed. Run \"abra app undeploy %s\"", app.Name, app.Name)) } filters, err := app.Filters(false, true) @@ -141,15 +142,15 @@ Passing "--force/-f" will select all volumes for removal. Be careful.`, } if !exactMatch { - log.Fatalf("unable to remove volume: no volume with name '%s'?", volumeToDelete) + log.Fatal(i18n.G("unable to remove volume: no volume with name '%s'?", volumeToDelete)) } err := client.RemoveVolumes(cl, context.Background(), []string{fullVolumeToDeleteName}, internal.Force, 5) if err != nil { - log.Fatalf("removing volume %s failed: %s", volumeToDelete, err) + log.Fatal(i18n.G("removing volume %s failed: %s", volumeToDelete, err)) } - log.Infof("volume %s removed successfully", volumeToDelete) + log.Info(i18n.G("volume %s removed successfully", volumeToDelete)) return } @@ -157,8 +158,8 @@ Passing "--force/-f" will select all volumes for removal. Be careful.`, var volumesToRemove []string if !internal.Force && !internal.NoInput { volumesPrompt := &survey.MultiSelect{ - Message: "which volumes do you want to remove?", - Help: "'x' indicates selected, enter / return to confirm, ctrl-c to exit, vim mode is enabled", + Message: i18n.G("which volumes do you want to remove?"), + Help: i18n.G("'x' indicates selected, enter / return to confirm, ctrl-c to exit, vim mode is enabled"), VimMode: true, Options: volumeNames, Default: volumeNames, @@ -175,28 +176,28 @@ Passing "--force/-f" will select all volumes for removal. Be careful.`, if len(volumesToRemove) > 0 { err := client.RemoveVolumes(cl, context.Background(), volumesToRemove, internal.Force, 5) if err != nil { - log.Fatalf("removing volumes failed: %s", err) + log.Fatal(i18n.G("removing volumes failed: %s", err)) } - log.Infof("%d volumes removed successfully", len(volumesToRemove)) + log.Info(i18n.G("%d volumes removed successfully", len(volumesToRemove))) } else { - log.Info("no volumes removed") + log.Info(i18n.G("no volumes removed")) } }, } var AppVolumeCommand = &cobra.Command{ - Use: "volume [cmd] [args] [flags]", - Aliases: []string{"vl"}, - Short: "Manage app volumes", + Use: i18n.G("volume [cmd] [args] [flags]"), + Aliases: []string{i18n.G("vl")}, + Short: i18n.G("Manage app volumes"), } func init() { AppVolumeRemoveCommand.Flags().BoolVarP( &internal.Force, - "force", - "f", + i18n.G("force"), + i18n.G("f"), false, - "perform action without further prompt", + i18n.G("perform action without further prompt"), ) } diff --git a/cli/catalogue/catalogue.go b/cli/catalogue/catalogue.go index 9c7abd27..103c38c0 100644 --- a/cli/catalogue/catalogue.go +++ b/cli/catalogue/catalogue.go @@ -13,6 +13,7 @@ import ( "coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/formatter" gitPkg "coopcloud.tech/abra/pkg/git" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/recipe" "github.com/go-git/go-git/v5" @@ -20,10 +21,10 @@ import ( ) var CatalogueGenerateCommand = &cobra.Command{ - Use: "generate [recipe] [flags]", + Use: i18n.G("generate [recipe] [flags]"), Aliases: []string{"g"}, - Short: "Generate the recipe catalogue", - Long: `Generate a new copy of the recipe catalogue. + Short: i18n.G("Generate the recipe catalogue"), + Long: i18n.G(`Generate a new copy of the recipe catalogue. N.B. this command **will** wipe local unstaged changes from your local recipes if present. "--chaos/-C" on this command refers to the catalogue repository @@ -39,7 +40,7 @@ use those details. Push your new release to git.coopcloud.tech with "--publish/-p". This requires that you have permission to git push to these repositories and have your SSH -keys configured on your account.`, +keys configured on your account.`), Args: cobra.RangeArgs(0, 1), ValidArgsFunction: func( cmd *cobra.Command, @@ -85,7 +86,7 @@ keys configured on your account.`, var warnings []string catl := make(recipe.RecipeCatalogue) - catlBar := formatter.CreateProgressbar(barLength, "collecting catalogue metadata") + catlBar := formatter.CreateProgressbar(barLength, i18n.G("collecting catalogue metadata")) for _, recipeMeta := range repos { if recipeName != "" && recipeName != recipeMeta.Name { if !internal.Debug { @@ -171,7 +172,7 @@ keys configured on your account.`, } } - log.Infof("generated recipe catalogue: %s", config.RECIPES_JSON) + log.Info(i18n.G("generated recipe catalogue: %s", config.RECIPES_JSON)) cataloguePath := path.Join(config.ABRA_DIR, "catalogue") if publishChanges { @@ -183,11 +184,11 @@ keys configured on your account.`, if isClean { if !internal.Dry { - log.Fatalf("no changes discovered in %s, nothing to publish?", cataloguePath) + log.Fatal(i18n.G("no changes discovered in %s, nothing to publish?", cataloguePath)) } } - msg := "chore: publish new catalogue release changes" + msg := i18n.G("chore: publish new catalogue release changes") if err := gitPkg.Commit(cataloguePath, msg, internal.Dry); err != nil { log.Fatal(err) } @@ -219,19 +220,19 @@ keys configured on your account.`, if !internal.Dry && publishChanges { url := fmt.Sprintf("%s/%s/commit/%s", config.REPOS_BASE_URL, config.CATALOGUE_JSON_REPO_NAME, head.Hash()) - log.Infof("new changes published: %s", url) + log.Info(i18n.G("new changes published: %s", url)) } if internal.Dry { - log.Info("dry run: no changes published") + log.Info(i18n.G("dry run: no changes published")) } }, } // CatalogueCommand defines the `abra catalogue` command and sub-commands. var CatalogueCommand = &cobra.Command{ - Use: "catalogue [cmd] [args] [flags]", - Short: "Manage the recipe catalogue", + Use: i18n.G("catalogue [cmd] [args] [flags]"), + Short: i18n.G("Manage the recipe catalogue"), Aliases: []string{"c"}, } @@ -246,7 +247,7 @@ func init() { "publish", "p", false, - "publish changes to git.coopcloud.tech", + i18n.G("publish changes to git.coopcloud.tech"), ) CatalogueGenerateCommand.Flags().BoolVarP( @@ -254,7 +255,7 @@ func init() { "dry-run", "r", false, - "report changes that would be made", + i18n.G("report changes that would be made"), ) CatalogueGenerateCommand.Flags().BoolVarP( @@ -262,7 +263,7 @@ func init() { "skip-updates", "s", false, - "skip updating recipe repositories", + i18n.G("skip updating recipe repositories"), ) CatalogueGenerateCommand.Flags().BoolVarP( @@ -270,6 +271,6 @@ func init() { "chaos", "C", false, - "ignore uncommitted recipes changes", + i18n.G("ignore uncommitted recipes changes"), ) } diff --git a/cli/complete.go b/cli/complete.go index 7f520df9..3eeb2105 100644 --- a/cli/complete.go +++ b/cli/complete.go @@ -3,13 +3,14 @@ package cli import ( "os" + "coopcloud.tech/abra/pkg/i18n" "github.com/spf13/cobra" ) var AutocompleteCommand = &cobra.Command{ - Use: "autocomplete [bash|zsh|fish|powershell]", - Short: "Generate autocompletion script", - Long: `To load completions: + Use: i18n.G("autocomplete [bash|zsh|fish|powershell]"), + Short: i18n.G("Generate autocompletion script"), + Long: i18n.G(`To load completions: Bash: # Load autocompletion for the current Bash session @@ -43,7 +44,7 @@ PowerShell: # To load autocompletions for every new session, run: PS> abra autocomplete powershell > abra.ps1 - # and source this file from your PowerShell profile.`, + # and source this file from your PowerShell profile.`), DisableFlagsInUseLine: true, ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs), diff --git a/cli/internal/cli.go b/cli/internal/cli.go index 7c4825ad..be00b3f4 100644 --- a/cli/internal/cli.go +++ b/cli/internal/cli.go @@ -6,6 +6,7 @@ var ( NoInput bool Offline bool IgnoreEnvVersion bool + Locale string // NOTE(d1): sub-command specific Chaos bool diff --git a/cli/recipe/lint.go b/cli/recipe/lint.go index d885fe04..85d7279d 100644 --- a/cli/recipe/lint.go +++ b/cli/recipe/lint.go @@ -4,14 +4,15 @@ import ( "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/formatter" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/lint" "coopcloud.tech/abra/pkg/log" "github.com/spf13/cobra" ) var RecipeLintCommand = &cobra.Command{ - Use: "lint [flags]", - Short: "Lint a recipe", + Use: i18n.G("lint [flags]"), + Short: i18n.G("Lint a recipe"), Aliases: []string{"l"}, Args: cobra.MinimumNArgs(1), ValidArgsFunction: func( diff --git a/cli/run.go b/cli/run.go index 13dd8aad..25f4cdaa 100644 --- a/cli/run.go +++ b/cli/run.go @@ -1,6 +1,7 @@ package cli import ( + "errors" "fmt" "os" @@ -10,6 +11,8 @@ import ( "coopcloud.tech/abra/cli/recipe" "coopcloud.tech/abra/cli/server" "coopcloud.tech/abra/pkg/config" + "coopcloud.tech/abra/pkg/formatter" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/log" charmLog "github.com/charmbracelet/log" "github.com/spf13/cobra" @@ -18,19 +21,20 @@ import ( func Run(version, commit string) { rootCmd := &cobra.Command{ - Use: "abra [cmd] [args] [flags]", - Short: "The Co-op Cloud command-line utility belt 🎩🐇", + Use: i18n.G("abra [cmd] [args] [flags]"), + Short: i18n.G("The Co-op Cloud command-line utility belt 🎩🐇"), Version: fmt.Sprintf("%s-%s", version, commit[:7]), ValidArgs: []string{ - "app", - "autocomplete", - "catalogue", - "man", - "recipe", - "server", - "upgrade", + i18n.G("app"), + i18n.G("autocomplete"), + i18n.G("catalogue"), + i18n.G("man"), + i18n.G("recipe"), + i18n.G("server"), + i18n.G("upgrade"), }, - PersistentPreRun: func(cmd *cobra.Command, args []string) { + + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { dirs := []map[string]os.FileMode{ {config.ABRA_DIR: 0764}, {config.SERVERS_DIR: 0700}, @@ -42,7 +46,7 @@ func Run(version, commit string) { for path, perm := range dir { if err := os.Mkdir(path, perm); err != nil { if !os.IsExist(err) { - log.Fatal(err) + return errors.New(i18n.G("unable to create %s: %s", path, err)) } continue } @@ -62,24 +66,38 @@ func Run(version, commit string) { log.SetReportCaller(true) } - log.Debugf("abra version %s, commit %s", version, commit) + if internal.Locale != "" { + // FIXME(d1): get list of valid locales from pkg/locales/* + switch internal.Locale { + case "es": + default: + return errors.New(i18n.G("unsupported --lang: %s (want: es)", internal.Locale)) + } + } + + log.Debug(i18n.G( + "abra version: %s, commit: %s, lang: %s", + version, formatter.SmallSHA(commit), internal.Locale, + )) + + return nil }, } rootCmd.CompletionOptions.DisableDefaultCmd = true manCommand := &cobra.Command{ - Use: "man [flags]", + Use: i18n.G("man [flags]"), Aliases: []string{"m"}, - Short: "Generate manpage", - Example: ` # generate the man pages into /usr/local/share/man/man1 + Short: i18n.G("Generate manpage"), + Example: i18n.G(` # generate the man pages into /usr/local/share/man/man1 abra_path=$(which abra) # pass abra absolute path to sudo below sudo $abra_path man sudo mandb # read the man pages man abra - man abra-app-deploy`, + man abra-app-deploy`), Run: func(cmd *cobra.Command, args []string) { header := &doc.GenManHeader{ Title: "ABRA", @@ -88,7 +106,7 @@ func Run(version, commit string) { manDir := "/usr/local/share/man/man1" if _, err := os.Stat(manDir); os.IsNotExist(err) { - log.Fatalf("unable to proceed, '%s' does not exist?") + log.Fatal(i18n.G("unable to proceed, %s does not exist?", manDir)) } err := doc.GenManTree(rootCmd, header, manDir) @@ -96,7 +114,7 @@ func Run(version, commit string) { log.Fatal(err) } - log.Info("don't forget to run 'sudo mandb'") + log.Info(i18n.G("don't forget to run 'sudo mandb'")) }, } @@ -105,7 +123,7 @@ func Run(version, commit string) { "debug", "d", false, - "show debug messages", + i18n.G("show debug messages"), ) rootCmd.PersistentFlags().BoolVarP( @@ -113,7 +131,7 @@ func Run(version, commit string) { "no-input", "n", false, - "toggle non-interactive mode", + i18n.G("toggle non-interactive mode"), ) rootCmd.PersistentFlags().BoolVarP( @@ -121,7 +139,7 @@ func Run(version, commit string) { "offline", "o", false, - "prefer offline & filesystem access", + i18n.G("prefer offline & filesystem access"), ) rootCmd.PersistentFlags().BoolVarP( @@ -129,7 +147,16 @@ func Run(version, commit string) { "ignore-env-version", "i", false, - "ignore .env version checkout", + i18n.G("ignore .env version checkout"), + ) + + rootCmd.PersistentFlags().StringVarP( + &internal.Locale, + "lang", + "l", + "", + // FIXME(d1): provide supported list of language via *.po file listing + i18n.G("force select language (supported: XXX)"), ) catalogue.CatalogueCommand.AddCommand( diff --git a/cli/server/add.go b/cli/server/add.go index 12ca137f..fedd48ea 100644 --- a/cli/server/add.go +++ b/cli/server/add.go @@ -13,14 +13,15 @@ import ( "coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/server" sshPkg "coopcloud.tech/abra/pkg/ssh" + "coopcloud.tech/abra/pkg/i18n" "github.com/spf13/cobra" ) var ServerAddCommand = &cobra.Command{ - Use: "add [[server] | --local] [flags]", + Use: i18n.G("add [[server] | --local] [flags]"), Aliases: []string{"a"}, - Short: "Add a new server", - Long: `Add a new server to your configuration so that it can be managed by Abra. + Short: i18n.G("Add a new server"), + Long: i18n.G(`Add a new server to your configuration so that it can be managed by Abra. Abra relies on the standard SSH command-line and ~/.ssh/config for client connection details. You must configure an entry per-host in your ~/.ssh/config @@ -35,8 +36,8 @@ for each server: If "--local" is passed, then Abra assumes that the current local server is intended as the target server. This is useful when you want to have your entire Co-op Cloud config located on the server itself, and not on your local -developer machine. The domain is then set to "default".`, - Example: " abra server add 1312.net", +developer machine. The domain is then set to "default".`), + Example: i18n.G(" abra server add 1312.net"), Args: cobra.RangeArgs(0, 1), ValidArgsFunction: func( cmd *cobra.Command, @@ -49,11 +50,11 @@ developer machine. The domain is then set to "default".`, }, Run: func(cmd *cobra.Command, args []string) { if len(args) > 0 && local { - log.Fatal("cannot use [server] and --local together") + log.Fatal(i18n.G("cannot use [server] and --local together")) } if len(args) == 0 && !local { - log.Fatal("missing argument or --local/-l flag") + log.Fatal(i18n.G("missing argument or --local/-l flag")) } name := "default" @@ -72,7 +73,7 @@ developer machine. The domain is then set to "default".`, log.Fatal(err) } - log.Debugf("attempting to create client for %s", name) + log.Debug(i18n.G("attempting to create client for %s", name)) if _, err := client.New(name, timeout); err != nil { cleanUp(name) @@ -80,9 +81,9 @@ developer machine. The domain is then set to "default".`, } if created { - log.Info("local server successfully added") + log.Info(i18n.G("local server successfully added")) } else { - log.Warn("local server already exists") + log.Warn(i18n.G("local server already exists")) } return @@ -96,27 +97,27 @@ developer machine. The domain is then set to "default".`, created, err := newContext(name) if err != nil { cleanUp(name) - log.Fatalf("unable to create local context: %s", err) + log.Fatal(i18n.G("unable to create local context: %s", err)) } - log.Debugf("attempting to create client for %s", name) + log.Debug(i18n.G("attempting to create client for %s", name)) if _, err := client.New(name, timeout); err != nil { cleanUp(name) - log.Fatalf("ssh %s error: %s", name, sshPkg.Fatal(name, err)) + log.Fatal(i18n.G("ssh %s error: %s", name, sshPkg.Fatal(name, err))) } if created { - log.Infof("%s successfully added", name) + log.Info(i18n.G("%s successfully added", name)) if _, err := dns.EnsureIPv4(name); err != nil { - log.Warnf("unable to resolve IPv4 for %s", name) + log.Warn(i18n.G("unable to resolve IPv4 for %s", name)) } return } - log.Warnf("%s already exists", name) + log.Warn(i18n.G("%s already exists", name)) }, } @@ -124,7 +125,7 @@ developer machine. The domain is then set to "default".`, // "server add" attempt. func cleanUp(name string) { if name != "default" { - log.Debugf("serverAdd: cleanUp: cleaning up context for %s", name) + log.Debug(i18n.G("serverAdd: cleanUp: cleaning up context for %s", name)) if err := client.DeleteContext(name); err != nil { log.Fatal(err) } @@ -133,16 +134,16 @@ func cleanUp(name string) { serverDir := filepath.Join(config.SERVERS_DIR, name) files, err := config.GetAllFilesInDirectory(serverDir) if err != nil { - log.Fatalf("serverAdd: cleanUp: unable to list files in %s: %s", serverDir, err) + log.Fatal(i18n.G("serverAdd: cleanUp: unable to list files in %s: %s", serverDir, err)) } if len(files) > 0 { - log.Debugf("serverAdd: cleanUp: %s is not empty, aborting cleanup", serverDir) + log.Debug(i18n.G("serverAdd: cleanUp: %s is not empty, aborting cleanup", serverDir)) return } if err := os.RemoveAll(serverDir); err != nil { - log.Fatalf("serverAdd: cleanUp: failed to remove %s: %s", serverDir, err) + log.Fatal(i18n.G("serverAdd: cleanUp: failed to remove %s: %s", serverDir, err)) } } @@ -159,12 +160,12 @@ func newContext(name string) (bool, error) { for _, context := range contexts { if context.Name == name { - log.Debugf("context for %s already exists", name) + log.Debug(i18n.G("context for %s already exists", name)) return false, nil } } - log.Debugf("creating context with domain %s", name) + log.Debugf(i18n.G("creating context with domain %s", name)) if err := client.CreateContext(name); err != nil { return false, nil @@ -180,7 +181,7 @@ func createServerDir(name string) (bool, error) { return false, err } - log.Debugf("server dir for %s already created", name) + log.Debug(i18n.G("server dir for %s already created", name)) return false, nil } @@ -198,6 +199,6 @@ func init() { "local", "l", false, - "use local server", + i18n.G("use local server"), ) } diff --git a/cli/server/list.go b/cli/server/list.go index dd3fd211..48f38a10 100644 --- a/cli/server/list.go +++ b/cli/server/list.go @@ -10,13 +10,14 @@ import ( "coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/log" "github.com/docker/cli/cli/connhelper/ssh" + "coopcloud.tech/abra/pkg/i18n" "github.com/spf13/cobra" ) var ServerListCommand = &cobra.Command{ - Use: "list [flags]", + Use: i18n.G("list [flags]"), Aliases: []string{"ls"}, - Short: "List managed servers", + Short: i18n.G("List managed servers"), Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { dockerContextStore := contextPkg.NewDefaultDockerContextStore() @@ -78,7 +79,7 @@ var ServerListCommand = &cobra.Command{ if internal.MachineReadable { out, err := formatter.ToJSON(headers, rows) if err != nil { - log.Fatal("unable to render to JSON: %s", err) + log.Fatal(i18n.G("unable to render to JSON: %s", err)) } fmt.Println(out) @@ -98,6 +99,6 @@ func init() { "machine", "m", false, - "print machine-readable output", + i18n.G("print machine-readable output"), ) } diff --git a/cli/server/prune.go b/cli/server/prune.go index 7a4e5c25..4f21bbce 100644 --- a/cli/server/prune.go +++ b/cli/server/prune.go @@ -7,17 +7,18 @@ import ( "coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/log" "github.com/docker/docker/api/types/filters" + "coopcloud.tech/abra/pkg/i18n" "github.com/spf13/cobra" ) var ServerPruneCommand = &cobra.Command{ - Use: "prune [flags]", + Use: i18n.G("prune [flags]"), Aliases: []string{"p"}, - Short: "Prune resources on a server", - Long: `Prunes unused containers, networks, and dangling images. + Short: i18n.G("Prune resources on a server"), + Long: i18n.G(`Prunes unused containers, networks, and dangling images. Use "--volumes/-v" to remove volumes that are not associated with a deployed -app. This can result in unwanted data loss if not used carefully.`, +app. This can result in unwanted data loss if not used carefully.`), Args: cobra.ExactArgs(1), ValidArgsFunction: func( cmd *cobra.Command, @@ -41,18 +42,18 @@ app. This can result in unwanted data loss if not used carefully.`, } cntSpaceReclaimed := formatter.ByteCountSI(cr.SpaceReclaimed) - log.Infof("containers pruned: %d; space reclaimed: %s", len(cr.ContainersDeleted), cntSpaceReclaimed) + log.Info(i18n.G("containers pruned: %d; space reclaimed: %s", len(cr.ContainersDeleted), cntSpaceReclaimed)) nr, err := cl.NetworksPrune(cmd.Context(), filterArgs) if err != nil { log.Fatal(err) } - log.Infof("networks pruned: %d", len(nr.NetworksDeleted)) + log.Info(i18n.G("networks pruned: %d", len(nr.NetworksDeleted))) pruneFilters := filters.NewArgs() if allFilter { - log.Debugf("removing all images, not only dangling ones") + log.Debug(i18n.G("removing all images, not only dangling ones")) pruneFilters.Add("dangling", "false") } @@ -62,7 +63,7 @@ app. This can result in unwanted data loss if not used carefully.`, } imgSpaceReclaimed := formatter.ByteCountSI(ir.SpaceReclaimed) - log.Infof("images pruned: %d; space reclaimed: %s", len(ir.ImagesDeleted), imgSpaceReclaimed) + log.Info(i18n.G("images pruned: %d; space reclaimed: %s", len(ir.ImagesDeleted), imgSpaceReclaimed)) if volumesFilter { vr, err := cl.VolumesPrune(cmd.Context(), filterArgs) @@ -71,7 +72,7 @@ app. This can result in unwanted data loss if not used carefully.`, } volSpaceReclaimed := formatter.ByteCountSI(vr.SpaceReclaimed) - log.Infof("volumes pruned: %d; space reclaimed: %s", len(vr.VolumesDeleted), volSpaceReclaimed) + log.Info(i18n.G("volumes pruned: %d; space reclaimed: %s", len(vr.VolumesDeleted), volSpaceReclaimed)) } return @@ -89,7 +90,7 @@ func init() { "all", "a", false, - "remove all unused images", + i18n.G("remove all unused images"), ) ServerPruneCommand.Flags().BoolVarP( @@ -97,6 +98,6 @@ func init() { "volumes", "v", false, - "remove volumes", + i18n.G("remove volumes"), ) } diff --git a/cli/server/remove.go b/cli/server/remove.go index 4e79643f..584556bd 100644 --- a/cli/server/remove.go +++ b/cli/server/remove.go @@ -9,18 +9,19 @@ import ( "coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/log" + "coopcloud.tech/abra/pkg/i18n" "github.com/spf13/cobra" ) var ServerRemoveCommand = &cobra.Command{ - Use: "remove [flags]", + Use: i18n.G("remove [flags]"), Aliases: []string{"rm"}, - Short: "Remove a managed server", - Long: `Remove a managed server. + Short: i18n.G("Remove a managed server"), + Long: i18n.G(`Remove a managed server. Abra will remove the internal bookkeeping ($ABRA_DIR/servers/...) and underlying client connection context. This server will then be lost in time, -like tears in rain.`, +like tears in rain.`), Args: cobra.ExactArgs(1), ValidArgsFunction: func( cmd *cobra.Command, @@ -39,7 +40,7 @@ like tears in rain.`, log.Fatal(err) } - log.Infof("%s is now lost in time, like tears in rain", serverName) + log.Info(i18n.G("%s is now lost in time, like tears in rain", serverName)) return }, diff --git a/cli/server/server.go b/cli/server/server.go index a9876aba..ac174580 100644 --- a/cli/server/server.go +++ b/cli/server/server.go @@ -1,10 +1,13 @@ package server -import "github.com/spf13/cobra" +import ( + "coopcloud.tech/abra/pkg/i18n" + "github.com/spf13/cobra" +) // ServerCommand defines the `abra server` command and its subcommands var ServerCommand = &cobra.Command{ - Use: "server [cmd] [args] [flags]", + Use: i18n.G("server [cmd] [args] [flags]"), Aliases: []string{"s"}, - Short: "Manage servers", + Short: i18n.G("Manage servers"), } diff --git a/cli/updater/updater.go b/cli/updater/updater.go index e0979107..000f5717 100644 --- a/cli/updater/updater.go +++ b/cli/updater/updater.go @@ -2,6 +2,7 @@ package updater import ( "context" + "errors" "fmt" "os" "strconv" @@ -21,6 +22,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" dockerclient "github.com/docker/docker/client" + "coopcloud.tech/abra/pkg/i18n" "github.com/spf13/cobra" "coopcloud.tech/abra/pkg/log" @@ -30,14 +32,14 @@ const SERVER = "localhost" // NotifyCommand checks for available upgrades. var NotifyCommand = &cobra.Command{ - Use: "notify [flags]", + Use: i18n.G("notify [flags]"), Aliases: []string{"n"}, - Short: "Check for available upgrades", - Long: `Notify on new versions for deployed apps. + Short: i18n.G("Check for available upgrades"), + Long: i18n.G(`Notify on new versions for deployed apps. If a new patch/minor version is available, a notification is printed. -Use "--major/-m" to include new major versions.`, +Use "--major/-m" to include new major versions.`), Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { cl, err := client.New("default") @@ -69,10 +71,10 @@ Use "--major/-m" to include new major versions.`, // UpgradeCommand upgrades apps. var UpgradeCommand = &cobra.Command{ - Use: "upgrade [[stack] [recipe] | --all] [flags]", + Use: i18n.G("upgrade [[stack] [recipe] | --all] [flags]"), Aliases: []string{"u"}, - Short: "Upgrade apps", - Long: `Upgrade an app by specifying stack name and recipe. + Short: i18n.G("Upgrade apps"), + Long: i18n.G(`Upgrade an app by specifying stack name and recipe. Use "--all" to upgrade every deployed app. @@ -83,7 +85,7 @@ available, the app is upgraded. To include major versions use the "--major/-m" flag. You probably don't want that as it will break things. Only apps that are not deployed with "--chaos/-C" are upgraded, to update chaos deployments use the "--chaos/-C" flag. Use it -with care.`, +with care.`), Args: cobra.RangeArgs(0, 2), // TODO(d1): complete stack/recipe // ValidArgsFunction: func( @@ -98,7 +100,7 @@ with care.`, } if !updateAll && len(args) != 2 { - log.Fatal("missing arguments or --all/-a flag") + log.Fatal(i18n.G("missing arguments or --all/-a flag")) } if !updateAll { @@ -150,7 +152,7 @@ func getLabel(cl *dockerclient.Client, stackName string, label string) (string, } } - log.Debugf("no %s label found for %s", label, stackName) + log.Debug(i18n.G("no %s label found for %s", label, stackName)) return "", nil } @@ -171,7 +173,7 @@ func getBoolLabel(cl *dockerclient.Client, stackName string, label string) (bool return value, nil } - log.Debugf("boolean label %s could not be found for %s, set default to false.", label, stackName) + log.Debug(i18n.G("boolean label %s could not be found for %s, set default to false.", label, stackName)) return false, nil } @@ -192,12 +194,12 @@ func getEnv(cl *dockerclient.Client, stackName string) (envfile.AppEnv, error) { for _, envString := range envList { splitString := strings.SplitN(envString, "=", 2) if len(splitString) != 2 { - log.Debugf("can't separate key from value: %s (this variable is probably unset)", envString) + log.Debug(i18n.G("can't separate key from value: %s (this variable is probably unset)", envString)) continue } k := splitString[0] v := splitString[1] - log.Debugf("for %s read env %s with value: %s from docker service", stackName, k, v) + log.Debugf(i18n.G("for %s read env %s with value: %s from docker service", stackName, k, v)) envMap[k] = v } } @@ -219,14 +221,14 @@ func getLatestUpgrade(cl *dockerclient.Client, stackName string, recipeName stri } if len(availableUpgrades) == 0 { - log.Debugf("no available upgrades for %s", stackName) + log.Debugf(i18n.G("no available upgrades for %s", stackName)) return "", nil } var chosenUpgrade string if len(availableUpgrades) > 0 { chosenUpgrade = availableUpgrades[len(availableUpgrades)-1] - log.Infof("%s (%s) can be upgraded from version %s to %s", stackName, recipeName, deployedVersion, chosenUpgrade) + log.Info(i18n.G("%s (%s) can be upgraded from version %s to %s", stackName, recipeName, deployedVersion, chosenUpgrade)) } return chosenUpgrade, nil @@ -234,7 +236,7 @@ func getLatestUpgrade(cl *dockerclient.Client, stackName string, recipeName stri // getDeployedVersion returns the currently deployed version of an app. func getDeployedVersion(cl *dockerclient.Client, stackName string, recipeName string) (string, error) { - log.Debugf("retrieve deployed version whether %s is already deployed", stackName) + log.Debug(i18n.G("retrieve deployed version whether %s is already deployed", stackName)) deployMeta, err := stack.IsDeployed(context.Background(), cl, stackName) if err != nil { @@ -242,11 +244,11 @@ func getDeployedVersion(cl *dockerclient.Client, stackName string, recipeName st } if !deployMeta.IsDeployed { - return "", fmt.Errorf("%s is not deployed?", stackName) + return "", errors.New(i18n.G("%s is not deployed?", stackName)) } if deployMeta.Version == "unknown" { - return "", fmt.Errorf("failed to determine deployed version of %s", stackName) + return "", errors.New(i18n.G("failed to determine deployed version of %s", stackName)) } return deployMeta.Version, nil @@ -268,7 +270,7 @@ func getAvailableUpgrades(cl *dockerclient.Client, stackName string, recipeName } if len(versions) == 0 { - log.Warnf("no published releases for %s in the recipe catalogue?", recipeName) + log.Warn(i18n.G("no published releases for %s in the recipe catalogue?", recipeName)) return nil, nil } @@ -294,7 +296,7 @@ func getAvailableUpgrades(cl *dockerclient.Client, stackName string, recipeName } } - log.Debugf("available updates for %s: %s", stackName, availableUpgrades) + log.Debug(i18n.G("available updates for %s: %s", stackName, availableUpgrades)) return availableUpgrades, nil } diff --git a/cli/upgrade.go b/cli/upgrade.go index aafa1310..74bb52c2 100644 --- a/cli/upgrade.go +++ b/cli/upgrade.go @@ -7,22 +7,23 @@ import ( "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/log" + "coopcloud.tech/abra/pkg/i18n" "github.com/spf13/cobra" ) // UpgradeCommand upgrades abra in-place. var UpgradeCommand = &cobra.Command{ - Use: "upgrade [flags]", + Use: i18n.G("upgrade [flags]"), Aliases: []string{"u"}, - Short: "Upgrade abra", - Long: `Upgrade abra in-place with the latest stable or release candidate. + Short: i18n.G("Upgrade abra"), + Long: i18n.G(`Upgrade abra in-place with the latest stable or release candidate. By default, the latest stable release is downloaded. Use "--rc/-r" to install the latest release candidate. Please bear in mind that it may contain absolutely catastrophic deal-breaker bugs. Thank you very much -for the testing efforts 💗`, - Example: " abra upgrade --rc", +for the testing efforts 💗`), + Example: i18n.G(" abra upgrade --rc"), Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { mainURL := "https://install.abra.coopcloud.tech" @@ -33,7 +34,7 @@ for the testing efforts 💗`, c = exec.Command("bash", "-c", fmt.Sprintf("wget -q -O- %s | bash -s -- --rc", releaseCandidateURL)) } - log.Debugf("attempting to run %s", c) + log.Debugf(i18n.G("attempting to run %s", c)) if err := internal.RunCmd(c); err != nil { log.Fatal(err) @@ -51,6 +52,6 @@ func init() { "rc", "r", false, - "install release candidate (may contain bugs)", + i18n.G("install release candidate (may contain bugs)"), ) } diff --git a/go.mod b/go.mod index be78dc17..8af1e328 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,6 @@ require ( require ( dario.cat/mergo v1.0.2 // indirect - github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 // indirect github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect github.com/BurntSushi/toml v1.5.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect @@ -52,14 +51,12 @@ require ( github.com/cyphar/filepath-securejoin v0.4.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/docker/distribution v2.8.3+incompatible // indirect - github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect github.com/docker/go-connections v0.6.0 // indirect github.com/docker/go-metrics v0.0.1 // indirect github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.6.2 // indirect @@ -85,11 +82,9 @@ require ( github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/miekg/pkcs11 v1.1.1 // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/go-archive v0.1.0 // indirect github.com/moby/sys/atomicwriter v0.1.0 // indirect - github.com/moby/sys/mountinfo v0.7.2 // indirect github.com/moby/sys/user v0.4.0 // indirect github.com/moby/sys/userns v0.1.0 // indirect github.com/morikuni/aec v1.0.0 // indirect @@ -100,7 +95,6 @@ require ( github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/runc v1.1.13 // indirect github.com/opencontainers/runtime-spec v1.1.0 // indirect - github.com/pelletier/go-toml v1.9.5 // indirect github.com/pjbgf/sha1cd v0.4.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.6.2 // indirect diff --git a/go.sum b/go.sum index ed1015b9..ceab1712 100644 --- a/go.sum +++ b/go.sum @@ -22,21 +22,13 @@ cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIA cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -coopcloud.tech/tagcmp v0.0.0-20230809071031-eb3e7758d4eb h1:Ws6WEwKXeaYEkfdkX6AqX1XLPuaCeyStEtxbmEJPllk= -coopcloud.tech/tagcmp v0.0.0-20230809071031-eb3e7758d4eb/go.mod h1:ESVm0wQKcbcFi06jItF3rI7enf4Jt2PvbkWpDDHk1DQ= -coopcloud.tech/tagcmp v0.0.0-20250427094623-9ea3bbbde8e5 h1:tphJCjFJw9fdjyKnbU0f7f3z5KtYE8VbUcAfu+oHKg8= -coopcloud.tech/tagcmp v0.0.0-20250427094623-9ea3bbbde8e5/go.mod h1:ESVm0wQKcbcFi06jItF3rI7enf4Jt2PvbkWpDDHk1DQ= coopcloud.tech/tagcmp v0.0.0-20250818180036-0ec1b205b5ca h1:gSD53tBAsbIGq4SnFfq+mEep6foekQ2a5ea7b38qkm0= coopcloud.tech/tagcmp v0.0.0-20250818180036-0ec1b205b5ca/go.mod h1:ESVm0wQKcbcFi06jItF3rI7enf4Jt2PvbkWpDDHk1DQ= -dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= -dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= git.coopcloud.tech/toolshed/godotenv v1.5.2-0.20250103171850-4d0ca41daa5c h1:oeKnUB79PKYD8D0/unYuu7MRcWryQQWOns8+JL+acrs= git.coopcloud.tech/toolshed/godotenv v1.5.2-0.20250103171850-4d0ca41daa5c/go.mod h1:fQuhwrpg6qb9NlFXKYi/LysWu1wxjraS8sxyW12CUF0= -github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= -github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk= github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ= @@ -57,8 +49,6 @@ github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= -github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= @@ -89,8 +79,6 @@ github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb0 github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw= -github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw= github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= @@ -98,7 +86,6 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/logrus-bugsnag v0.0.0-20170309145241-6dbc35f2c30d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= -github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -133,11 +120,8 @@ github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dR github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= -github.com/bugsnag/bugsnag-go v1.0.5-0.20150529004307-13fd6b8acda0 h1:s7+5BfS4WFJoVF9pnB8kBk03S7pZXRdKamnV0FOl5Sc= github.com/bugsnag/bugsnag-go v1.0.5-0.20150529004307-13fd6b8acda0/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= -github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembjv71DPz3uX/V/6MMlSyD9JBQ6kQ= github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= -github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= @@ -145,29 +129,18 @@ github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/charmbracelet/bubbletea v1.3.4 h1:kCg7B+jSCFPLYRA52SDZjr51kG/fMUEoPoZrkaDHyoI= -github.com/charmbracelet/bubbletea v1.3.4/go.mod h1:dtcUCyCGEX3g9tosuYiut3MXgY/Jsv9nKVdibKKRRXo= github.com/charmbracelet/bubbletea v1.3.6 h1:VkHIxPJQeDt0aFJIsVxw8BQdh/F/L2KKZGsK6et5taU= github.com/charmbracelet/bubbletea v1.3.6/go.mod h1:oQD9VCRQFF8KplacJLo28/jofOI2ToOfGYeFgBBxHOc= -github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs= -github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk= -github.com/charmbracelet/colorprofile v0.3.1 h1:k8dTHMd7fgw4bnFd7jXTLZrSU/CQrKnL3m+AxCzDz40= -github.com/charmbracelet/colorprofile v0.3.1/go.mod h1:/GkGusxNs8VB/RSOh3fu0TJmQ4ICMMPApIIVn0KszZ0= github.com/charmbracelet/colorprofile v0.3.2 h1:9J27WdztfJQVAQKX2WOlSSRB+5gaKqqITmrvb1uTIiI= github.com/charmbracelet/colorprofile v0.3.2/go.mod h1:mTD5XzNeWHj8oqHb+S1bssQb7vIHbepiebQ2kPKVKbI= github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= -github.com/charmbracelet/log v0.4.1 h1:6AYnoHKADkghm/vt4neaNEXkxcXLSV2g1rdyFDOpTyk= -github.com/charmbracelet/log v0.4.1/go.mod h1:pXgyTsqsVu4N9hGdHmQ0xEA4RsXof402LX9ZgiITn2I= github.com/charmbracelet/log v0.4.2 h1:hYt8Qj6a8yLnvR+h7MwsJv/XvmBJXiueUcI3cIxsyig= github.com/charmbracelet/log v0.4.2/go.mod h1:qifHGX/tc7eluv2R6pWIpyHDDrrb/AG71Pf2ysQu5nw= -github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE= -github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q= github.com/charmbracelet/x/ansi v0.10.1 h1:rL3Koar5XvX0pHGfovN03f5cxLbCF2YvLeyz7D2jVDQ= github.com/charmbracelet/x/ansi v0.10.1/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE= github.com/charmbracelet/x/cellbuf v0.0.13 h1:/KBBKHuVRbq1lYx5BzEHBAFBP8VcQzJejZ/IA3iR28k= @@ -191,10 +164,7 @@ github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJ github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 h1:lkAMpLVBDaj17e85keuznYcH5rqI438v41pKcBl4ZxQ= github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA= -github.com/cloudflare/circl v1.6.0 h1:cr5JKic4HI+LkINy2lg3W2jF8sHCVTBncJr5gIIq7qk= -github.com/cloudflare/circl v1.6.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= @@ -316,7 +286,6 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo= github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= @@ -347,8 +316,6 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/cli v28.0.1+incompatible h1:g0h5NQNda3/CxIsaZfH4Tyf6vpxFth7PYl3hgCPOKzs= -github.com/docker/cli v28.0.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v28.3.3+incompatible h1:fp9ZHAr1WWPGdIWBM1b3zLtgCF+83gRdVMTJsUeiyAo= github.com/docker/cli v28.3.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= @@ -357,8 +324,6 @@ github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4Kfc github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v28.0.1+incompatible h1:FCHjSRdXhNRFjlHMTv4jUNlIBbTeRjrWfeFuJp7jpo0= -github.com/docker/docker v28.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v28.3.3+incompatible h1:Dypm25kh4rmk49v1eiVbsAtpAsYURjYkaKubwuBdxEI= github.com/docker/docker v28.3.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= @@ -367,8 +332,6 @@ github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0= github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c/go.mod h1:CADgU4DSXK5QUlFslkQu2yW2TKzFZcXq/leZfM0UH5Q= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= -github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94= github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE= github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= @@ -413,8 +376,6 @@ github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoD github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw= github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= @@ -430,8 +391,6 @@ github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UN github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.14.0 h1:/MD3lCrGjCen5WfEAzKg00MJJffKhC8gzS80ycmCi60= -github.com/go-git/go-git/v5 v5.14.0/go.mod h1:Z5Xhoia5PcWA3NF8vRLURn9E5FRhSl7dGj9ItW3Wk5k= github.com/go-git/go-git/v5 v5.16.2 h1:fT6ZIOjE5iEnkzKyxTHK1W4HGAsPhqEqiSAssSO77hM= github.com/go-git/go-git/v5 v5.16.2/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -447,8 +406,6 @@ github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KE github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -464,11 +421,8 @@ github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8 github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-sql-driver/mysql v1.3.0 h1:pgwjLi/dvffoP9aabwkT3AKpXQM93QARkjFhDDqC1UE= github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= -github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= @@ -522,7 +476,6 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519c93 h1:jc2UWq7CbdszqeH6qu1ougXMIUBfSy8Pbh/anURYbGI= github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519c93/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -575,13 +528,9 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= -github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -592,13 +541,10 @@ github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVH github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= -github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48= github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog= github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= @@ -615,9 +561,7 @@ github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jinzhu/gorm v0.0.0-20170222002820-5409931a1bb8 h1:CZkYfurY6KGhVtlalI4QwQ6T0Cu6iuY3e0x5RLu96WE= github.com/jinzhu/gorm v0.0.0-20170222002820-5409931a1bb8/go.mod h1:Vla75njaFJ8clLU1W44h34PjIkijhjHIYnZxMqCdxqo= -github.com/jinzhu/inflection v0.0.0-20170102125226-1c35d901db3d h1:jRQLvyVGL+iVtDElaEIDdKwpPqUIZJfzkNLV34htpEc= github.com/jinzhu/inflection v0.0.0-20170102125226-1c35d901db3d/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= @@ -670,7 +614,6 @@ github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/magiconair/properties v1.5.3/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -710,8 +653,6 @@ github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0 github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v0.0.0-20150613213606-2caf8efc9366/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= @@ -725,8 +666,6 @@ github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtl github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= -github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= -github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg= github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4= github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU= @@ -734,8 +673,6 @@ github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiT github.com/moby/sys/signal v0.7.1 h1:PrQxdvxcGijdo6UXXo/lU/TvHUWyPhj7UOpSo8tuvk0= github.com/moby/sys/signal v0.7.1/go.mod h1:Se1VGehYokAkrSQwL4tDzHvETwUZlnY7S5XtQ50mQp8= github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= -github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo= -github.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs= github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= @@ -817,15 +754,10 @@ github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqi github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= -github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= -github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= -github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4= -github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A= github.com/pjbgf/sha1cd v0.4.0 h1:NXzbL1RvjTUi6kgYZCX3fPwwl27Q1LJndxtUDVfJGRY= github.com/pjbgf/sha1cd v0.4.0/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -843,8 +775,6 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk= -github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg= github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc= github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE= github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -852,8 +782,6 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1: github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= -github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= @@ -862,8 +790,6 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k= -github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18= github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE= github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8= github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -877,8 +803,6 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= -github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= @@ -890,7 +814,6 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= -github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -901,8 +824,6 @@ github.com/schollz/progressbar/v3 v3.18.0/go.mod h1:IsO3lpbaGuzh8zIMzgY3+J8l4C8G github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= @@ -923,10 +844,8 @@ github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:s github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v0.0.0-20150508191742-4d07383ffe94/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= -github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.1/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= @@ -935,7 +854,6 @@ github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHN github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= github.com/spf13/jwalterweatherman v0.0.0-20141219030609-3d60171a6431/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.0/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -943,12 +861,10 @@ github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bd github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M= github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v0.0.0-20150530192845-be5ff3e4840c/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= -github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -1023,47 +939,27 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 h1:Hf9xI/XLML9ElpiHVDNwvqI0hIFlzV8dgIr35kV1kRU= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0/go.mod h1:NfchwuyNoMcZ5MLHwPrODwUF1HWCXWrL31s8gSAdIKY= -go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= -go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.35.0 h1:QcFwRrZLc82r8wODjvyCbP7Ifp3UANaBSmhDSFjnqSc= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.35.0/go.mod h1:CXIWhUomyWBG/oY2/r/kLp6K/cmx9e/7DLpBuuGdLCA= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0 h1:zG8GlgXCJQd5BU98C0hZnBbElszTmUgCNCfYneaDL0A= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0/go.mod h1:hOfBCz8kv/wuq73Mx2H2QnWokh/kHZxkh6SNF2bdKtw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0fikVry1IsiUnXjf7QFvoNN3Xw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 h1:m639+BofXTvcY1q8CGs4ItwQarYtJPOWmVobfM1HpVI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0/go.mod h1:LjReUci/F4BUyv+y4dwnq3h/26iNOeC3wAIqgvTIZVo= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU= -go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= -go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= -go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY= -go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg= go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= -go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o= -go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w= go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= -go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= -go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= -go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1090,8 +986,6 @@ golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1104,10 +998,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw= -golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM= -golang.org/x/exp v0.0.0-20250811191247-51f88131bc50 h1:3yiSh9fhy5/RhCSntf4Sy0Tnx50DmMpQ4MQdKKk4yg4= -golang.org/x/exp v0.0.0-20250811191247-51f88131bc50/go.mod h1:rT6SFzZ7oxADUDx58pcaKFTcZ+inxAa9fTrYx/uVYwg= golang.org/x/exp v0.0.0-20250813145105-42675adae3e6 h1:SbTAbRFnd5kjQXbczszQ0hdk3ctwYf3qBNH9jIsGclE= golang.org/x/exp v0.0.0-20250813145105-42675adae3e6/go.mod h1:4QTo5u+SEIbbKW1RacMZq1YEfOBqeXa19JeshGi+zc4= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= @@ -1173,8 +1063,6 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= -golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1194,8 +1082,6 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= -golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1275,17 +1161,12 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= -golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1297,8 +1178,6 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1307,8 +1186,6 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1404,12 +1281,8 @@ google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200527145253-8367513e4ece/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto/googleapis/api v0.0.0-20250313205543-e70fdf4c4cb4 h1:IFnXJq3UPB3oBREOodn1v1aGQeZYQclEmvWRMN0PSsY= -google.golang.org/genproto/googleapis/api v0.0.0-20250313205543-e70fdf4c4cb4/go.mod h1:c8q6Z6OCqnfVIqUFJkCzKcrj8eCvUrz+K4KRzSTuANg= google.golang.org/genproto/googleapis/api v0.0.0-20250811230008-5f3141c8851a h1:DMCgtIAIQGZqJXMVzJF4MV8BlWoJh2ZuFiRdAleyr58= google.golang.org/genproto/googleapis/api v0.0.0-20250811230008-5f3141c8851a/go.mod h1:y2yVLIE/CSMCPXaHnSKXxu1spLPnglFLegmgdY23uuE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 h1:iK2jbkWL86DXjEx0qiHcRE9dE4/Ahua5k6V8OWFb//c= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= google.golang.org/genproto/googleapis/rpc v0.0.0-20250811230008-5f3141c8851a h1:tPE/Kp+x9dMSwUm/uM0JKK0IfdiJkwAbSMSeZBXXJXc= google.golang.org/genproto/googleapis/rpc v0.0.0-20250811230008-5f3141c8851a/go.mod h1:gw1tLEfykwDz2ET4a12jcXt4couGAm7IwsVaTy0Sflo= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= @@ -1431,8 +1304,6 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg= -google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -1448,13 +1319,10 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= -google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A= google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/cenkalti/backoff.v2 v2.2.1 h1:eJ9UAg01/HIHG987TwxvnzK2MgxXq97YY6rYDpY9aII= gopkg.in/cenkalti/backoff.v2 v2.2.1/go.mod h1:S0QdOvT2AlerfSBkp0O+dk+bbIMaNbEmVk876gPCthU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1470,7 +1338,6 @@ gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKW gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/rethinkdb/rethinkdb-go.v6 v6.2.1 h1:d4KQkxAaAiRY2h5Zqis161Pv91A37uZyJOx73duwUwM= gopkg.in/rethinkdb/rethinkdb-go.v6 v6.2.1/go.mod h1:WbjuEoo1oadwzQ4apSDU+JTvmllEHtsNHS6y7vFc7iw= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= @@ -1491,7 +1358,6 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= diff --git a/locales/default.pot b/locales/default.pot deleted file mode 100644 index 39987c8b..00000000 --- a/locales/default.pot +++ /dev/null @@ -1,12 +0,0 @@ -msgid "" -msgstr "" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Language: \n" -"X-Generator: xgotext\n" - -#: app.go:11 -msgid "Manage apps" -msgstr "" \ No newline at end of file diff --git a/locales/es/LC_MESSAGES/default.po b/locales/es/LC_MESSAGES/default.po deleted file mode 100644 index a50fdda0..00000000 --- a/locales/es/LC_MESSAGES/default.po +++ /dev/null @@ -1,20 +0,0 @@ -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-08-04 14:15+0000\n" -"PO-Revision-Date: 2025-08-04 14:15+0000\n" -"Last-Translator: 3wordchant <3wc.coopcloud@doesthisthing.work>\n" -"Language-Team: Spanish \n" -"Language: es\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: ENCODING\n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.12.2\n" - -#: app.go:11 -msgid "Manage apps" -msgstr "Gestionar aplicaciones" diff --git a/pkg/autocomplete/autocomplete.go b/pkg/autocomplete/autocomplete.go index aafea741..33730a23 100644 --- a/pkg/autocomplete/autocomplete.go +++ b/pkg/autocomplete/autocomplete.go @@ -1,12 +1,12 @@ package autocomplete import ( - "fmt" "sort" "coopcloud.tech/abra/pkg/app" appPkg "coopcloud.tech/abra/pkg/app" "coopcloud.tech/abra/pkg/recipe" + "coopcloud.tech/abra/pkg/i18n" "github.com/spf13/cobra" ) @@ -14,7 +14,7 @@ import ( func AppNameComplete() ([]string, cobra.ShellCompDirective) { appFiles, err := app.LoadAppFiles("") if err != nil { - err := fmt.Sprintf("autocomplete failed: %s", err) + err := i18n.G("autocomplete failed: %s", err) return []string{err}, cobra.ShellCompDirectiveError } @@ -29,7 +29,7 @@ func AppNameComplete() ([]string, cobra.ShellCompDirective) { func ServiceNameComplete(appName string) ([]string, cobra.ShellCompDirective) { serviceNames, err := app.GetAppServiceNames(appName) if err != nil { - err := fmt.Sprintf("autocomplete failed: %s", err) + err := i18n.G("autocomplete failed: %s", err) return []string{err}, cobra.ShellCompDirectiveError } @@ -40,7 +40,7 @@ func ServiceNameComplete(appName string) ([]string, cobra.ShellCompDirective) { func RecipeNameComplete() ([]string, cobra.ShellCompDirective) { catl, err := recipe.ReadRecipeCatalogue(false) if err != nil { - err := fmt.Sprintf("autocomplete failed: %s", err) + err := i18n.G("autocomplete failed: %s", err) return []string{err}, cobra.ShellCompDirectiveError } @@ -56,7 +56,7 @@ func RecipeNameComplete() ([]string, cobra.ShellCompDirective) { func RecipeVersionComplete(recipeName string) ([]string, cobra.ShellCompDirective) { catl, err := recipe.ReadRecipeCatalogue(true) if err != nil { - err := fmt.Sprintf("autocomplete failed: %s", err) + err := i18n.G("autocomplete failed: %s", err) return []string{err}, cobra.ShellCompDirectiveError } @@ -74,7 +74,7 @@ func RecipeVersionComplete(recipeName string) ([]string, cobra.ShellCompDirectiv func ServerNameComplete() ([]string, cobra.ShellCompDirective) { files, err := app.LoadAppFiles("") if err != nil { - err := fmt.Sprintf("autocomplete failed: %s", err) + err := i18n.G("autocomplete failed: %s", err) return []string{err}, cobra.ShellCompDirectiveError } @@ -90,13 +90,13 @@ func ServerNameComplete() ([]string, cobra.ShellCompDirective) { func CommandNameComplete(appName string) ([]string, cobra.ShellCompDirective) { app, err := app.Get(appName) if err != nil { - err := fmt.Sprintf("autocomplete failed: %s", err) + err := i18n.G("autocomplete failed: %s", err) return []string{err}, cobra.ShellCompDirectiveError } cmdNames, err := appPkg.ReadAbraShCmdNames(app.Recipe.AbraShPath) if err != nil { - err := fmt.Sprintf("autocomplete failed: %s", err) + err := i18n.G("autocomplete failed: %s", err) return []string{err}, cobra.ShellCompDirectiveError } @@ -111,7 +111,7 @@ func SecretComplete(recipeName string) ([]string, cobra.ShellCompDirective) { config, err := r.GetComposeConfig(nil) if err != nil { - err := fmt.Sprintf("autocomplete failed: %s", err) + err := i18n.G("autocomplete failed: %s", err) return []string{err}, cobra.ShellCompDirectiveError } diff --git a/pkg/catalogue/catalogue.go b/pkg/catalogue/catalogue.go index 76859616..ba293364 100644 --- a/pkg/catalogue/catalogue.go +++ b/pkg/catalogue/catalogue.go @@ -1,6 +1,7 @@ package catalogue import ( + "errors" "fmt" "os" "path" @@ -10,13 +11,14 @@ import ( gitPkg "coopcloud.tech/abra/pkg/git" "coopcloud.tech/abra/pkg/log" "github.com/go-git/go-git/v5" + "coopcloud.tech/abra/pkg/i18n" ) // EnsureCatalogue ensures that the catalogue is cloned locally & present. func EnsureCatalogue() error { catalogueDir := path.Join(config.ABRA_DIR, "catalogue") if _, err := os.Stat(catalogueDir); err != nil && os.IsNotExist(err) { - log.Debugf("catalogue is missing, retrieving now") + log.Debug(i18n.G("catalogue is missing, retrieving now")) url := fmt.Sprintf("%s/%s.git", config.REPOS_BASE_URL, config.CATALOGUE_JSON_REPO_NAME) if err := gitPkg.Clone(catalogueDir, url); err != nil { @@ -35,8 +37,7 @@ func EnsureIsClean() error { } if !isClean { - msg := "%s has locally unstaged changes? please commit/remove your changes before proceeding" - return fmt.Errorf(msg, config.CATALOGUE_DIR) + return errors.New(i18n.G("%s has locally unstaged changes? please commit/remove your changes before proceeding", config.CATALOGUE_DIR)) } return nil @@ -55,8 +56,7 @@ func EnsureUpToDate() error { } if len(remotes) == 0 { - msg := "cannot ensure %s is up-to-date, no git remotes configured" - log.Debugf(msg, config.CATALOGUE_DIR) + log.Debug(i18n.G("cannot ensure %s is up-to-date, no git remotes configured", config.CATALOGUE_DIR)) return nil } @@ -81,7 +81,7 @@ func EnsureUpToDate() error { } } - log.Debugf("fetched latest git changes for %s", config.CATALOGUE_DIR) + log.Debug(i18n.G("fetched latest git changes for %s", config.CATALOGUE_DIR)) return nil } diff --git a/pkg/client/client.go b/pkg/client/client.go index 315a2732..c6631de8 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -4,7 +4,6 @@ package client import ( "context" "errors" - "fmt" "net/http" "os" "time" @@ -14,6 +13,7 @@ import ( sshPkg "coopcloud.tech/abra/pkg/ssh" commandconnPkg "coopcloud.tech/abra/pkg/upstream/commandconn" "github.com/docker/docker/client" + "coopcloud.tech/abra/pkg/i18n" ) // Conf is a Docker client configuration. @@ -41,7 +41,7 @@ func New(serverName string, opts ...Opt) (*client.Client, error) { if serverName != "default" { context, err := GetContext(serverName) if err != nil { - return nil, fmt.Errorf("unknown server, run \"abra server add %s\"?", serverName) + return nil, errors.New(i18n.G("unknown server, run \"abra server add %s\"?", serverName)) } ctxEndpoint, err := contextPkg.GetContextEndpoint(context) @@ -85,7 +85,7 @@ func New(serverName string, opts ...Opt) (*client.Client, error) { return nil, err } - log.Debugf("created client for %s", serverName) + log.Debug(i18n.G("created client for %s", serverName)) info, err := cl.Info(context.Background()) if err != nil { @@ -94,10 +94,10 @@ func New(serverName string, opts ...Opt) (*client.Client, error) { if info.Swarm.LocalNodeState == "inactive" { if serverName != "default" { - return cl, fmt.Errorf("swarm mode not enabled on %s?", serverName) + return cl, errors.New(i18n.G("swarm mode not enabled on %s?", serverName)) } - return cl, errors.New("swarm mode not enabled on local server?") + return cl, errors.New(i18n.G("swarm mode not enabled on local server?")) } return cl, nil diff --git a/pkg/client/configs.go b/pkg/client/configs.go index efe14ab4..282ea864 100644 --- a/pkg/client/configs.go +++ b/pkg/client/configs.go @@ -2,11 +2,12 @@ package client import ( "context" - "fmt" + "errors" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/client" + "coopcloud.tech/abra/pkg/i18n" ) func GetConfigs(cl *client.Client, ctx context.Context, server string, fs filters.Args) ([]swarm.Config, error) { @@ -31,7 +32,7 @@ func GetConfigNames(configs []swarm.Config) []string { func RemoveConfigs(cl *client.Client, ctx context.Context, configNames []string, force bool) error { for _, confName := range configNames { if err := cl.ConfigRemove(context.Background(), confName); err != nil { - return fmt.Errorf("conf %s: %s", confName, err) + return errors.New(i18n.G("conf %s: %s", confName, err)) } } return nil diff --git a/pkg/client/context.go b/pkg/client/context.go index 4408bda5..7bdddda2 100644 --- a/pkg/client/context.go +++ b/pkg/client/context.go @@ -10,6 +10,7 @@ import ( dConfig "github.com/docker/cli/cli/config" "github.com/docker/cli/cli/context/docker" contextStore "github.com/docker/cli/cli/context/store" + "coopcloud.tech/abra/pkg/i18n" ) type Context = contextStore.Metadata @@ -22,7 +23,7 @@ func CreateContext(contextName string) error { return err } - log.Debugf("created the %s context", contextName) + log.Debug(i18n.G("created the %s context", contextName)) return nil } @@ -62,7 +63,7 @@ func createContext(name string, host string) error { func DeleteContext(name string) error { if name == "default" { - return errors.New("context 'default' cannot be removed") + return errors.New(i18n.G("context 'default' cannot be removed")) } if _, err := GetContext(name); err != nil { diff --git a/pkg/client/registry.go b/pkg/client/registry.go index 36d0ea73..75d66674 100644 --- a/pkg/client/registry.go +++ b/pkg/client/registry.go @@ -2,11 +2,13 @@ package client import ( "context" + "errors" "fmt" "github.com/containers/image/docker" "github.com/containers/image/types" "github.com/distribution/reference" + "coopcloud.tech/abra/pkg/i18n" ) // GetRegistryTags retrieves all tags of an image from a container registry. @@ -15,7 +17,7 @@ func GetRegistryTags(img reference.Named) ([]string, error) { ref, err := docker.ParseReference(fmt.Sprintf("//%s", img)) if err != nil { - return tags, fmt.Errorf("failed to parse image %s, saw: %s", img, err.Error()) + return tags, errors.New(i18n.G("failed to parse image %s, saw: %s", img, err.Error())) } ctx := context.Background() diff --git a/pkg/client/volumes.go b/pkg/client/volumes.go index c7af7619..2b62f864 100644 --- a/pkg/client/volumes.go +++ b/pkg/client/volumes.go @@ -2,6 +2,7 @@ package client import ( "context" + "errors" "fmt" "time" @@ -9,6 +10,7 @@ import ( "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/volume" "github.com/docker/docker/client" + "coopcloud.tech/abra/pkg/i18n" ) func GetVolumes(cl *client.Client, ctx context.Context, server string, fs filters.Args) ([]*volume.Volume, error) { @@ -54,9 +56,9 @@ func retryFunc(retries int, fn func() error) error { } if i+1 < retries { sleep := time.Duration(i+1) * time.Duration(i+1) - log.Infof("%s: waiting %d seconds before next retry", err, sleep) + log.Infof(i18n.G("%s: waiting %d seconds before next retry", err, sleep)) time.Sleep(sleep * time.Second) } } - return fmt.Errorf("%d retries failed", retries) + return errors.New(i18n.G("%d retries failed", retries)) } diff --git a/pkg/config/abra.go b/pkg/config/abra.go index e0a5d452..f80f1b3c 100644 --- a/pkg/config/abra.go +++ b/pkg/config/abra.go @@ -6,6 +6,7 @@ import ( "path/filepath" "coopcloud.tech/abra/pkg/log" + "coopcloud.tech/abra/pkg/i18n" "gopkg.in/yaml.v3" ) @@ -16,13 +17,13 @@ func LoadAbraConfig() Abra { wd, _ := os.Getwd() configFile := findAbraConfig(wd) if configFile == "" { - log.Debugf("no config file found") + log.Debug(i18n.G("no config file found")) return Abra{} } data, err := os.ReadFile(configFile) if err != nil { // Do nothing, when an error occurs - log.Debugf("error reading config file: %s", err) + log.Debug(i18n.G("error reading config file: %s", err)) return Abra{} } @@ -30,10 +31,10 @@ func LoadAbraConfig() Abra { err = yaml.Unmarshal(data, &config) if err != nil { // Do nothing, when an error occurs - log.Debugf("error loading config file: %s", err) + log.Debug(i18n.G("error loading config file: %s", err)) return Abra{} } - log.Debugf("config file loaded from: %s", configFile) + log.Debug(i18n.G("config file loaded from: %s", configFile)) config.configPath = filepath.Dir(configFile) return config } @@ -73,26 +74,24 @@ type Abra struct { // 3. use $HOME/.abra when above two options failed func (a Abra) GetAbraDir() string { if dir, exists := os.LookupEnv("ABRA_DIR"); exists && dir != "" { - log.Debug("read abra dir from $ABRA_DIR") + log.Debug(i18n.G("read abra dir from $ABRA_DIR")) return dir } if a.AbraDir != "" { - log.Debug("read abra dir from config file") + log.Debug(i18n.G("read abra dir from config file")) if path.IsAbs(a.AbraDir) { return a.AbraDir } // Make the path absolute return path.Join(a.configPath, a.AbraDir) } - log.Debug("using default abra dir") + log.Debug(i18n.G("using default abra dir")) return os.ExpandEnv("$HOME/.abra") } func (a Abra) GetServersDir() string { return path.Join(a.GetAbraDir(), "servers") } func (a Abra) GetRecipesDir() string { return path.Join(a.GetAbraDir(), "recipes") } func (a Abra) GetLogsDir() string { return path.Join(a.GetAbraDir(), "logs") } -func (a Abra) GetVendorDir() string { return path.Join(a.GetAbraDir(), "vendor") } -func (a Abra) GetBackupDir() string { return path.Join(a.GetAbraDir(), "backups") } func (a Abra) GetCatalogueDir() string { return path.Join(a.GetAbraDir(), "catalogue") } var config = LoadAbraConfig() @@ -102,8 +101,6 @@ var ( SERVERS_DIR = config.GetServersDir() RECIPES_DIR = config.GetRecipesDir() LOGS_DIR = config.GetLogsDir() - VENDOR_DIR = config.GetVendorDir() - BACKUP_DIR = config.GetBackupDir() CATALOGUE_DIR = config.GetCatalogueDir() RECIPES_JSON = path.Join(config.GetCatalogueDir(), "recipes.json") REPOS_BASE_URL = "https://git.coopcloud.tech/coop-cloud" diff --git a/pkg/config/env.go b/pkg/config/env.go index c07a1e98..ba988adf 100644 --- a/pkg/config/env.go +++ b/pkg/config/env.go @@ -1,7 +1,7 @@ package config import ( - "fmt" + "errors" "io/fs" "io/ioutil" "os" @@ -10,6 +10,7 @@ import ( "strings" "coopcloud.tech/abra/pkg/log" + "coopcloud.tech/abra/pkg/i18n" ) const MAX_SANITISED_APP_NAME_LENGTH = 45 @@ -33,7 +34,7 @@ func GetServers() ([]string, error) { } } - log.Debugf("retrieved %v servers: %s", len(filtered), filtered) + log.Debug(i18n.G("retrieved %v servers: %s", len(filtered), filtered)) return filtered, nil } @@ -46,7 +47,7 @@ func ReadServerNames() ([]string, error) { return nil, err } - log.Debugf("read %s from %s", strings.Join(serverNames, ","), SERVERS_DIR) + log.Debug(i18n.G("read %s from %s", strings.Join(serverNames, ","), SERVERS_DIR)) return serverNames, nil } @@ -70,7 +71,7 @@ func GetAllFilesInDirectory(directory string) ([]fs.FileInfo, error) { realPath, err := filepath.EvalSymlinks(filePath) if err != nil { - log.Warnf("broken symlink in your abra config folders: %s", filePath) + log.Warnf(i18n.G("broken symlink in your abra config folders: %s", filePath)) } else { realFile, err := os.Stat(realPath) if err != nil { @@ -94,7 +95,7 @@ func GetAllFoldersInDirectory(directory string) ([]string, error) { return nil, err } if len(files) == 0 { - return nil, fmt.Errorf("directory is empty: %s", directory) + return nil, errors.New(i18n.G("directory is empty: %s", directory)) } for _, file := range files { @@ -103,7 +104,7 @@ func GetAllFoldersInDirectory(directory string) ([]string, error) { filePath := path.Join(directory, file.Name()) realDir, err := filepath.EvalSymlinks(filePath) if err != nil { - log.Warnf("broken symlink in your abra config folders: %s", filePath) + log.Warnf(i18n.G("broken symlink in your abra config folders: %s", filePath)) } else if stat, err := os.Stat(realDir); err == nil && stat.IsDir() { // path is a directory folders = append(folders, file.Name()) diff --git a/pkg/container/container.go b/pkg/container/container.go index 16316218..1ec1a36d 100644 --- a/pkg/container/container.go +++ b/pkg/container/container.go @@ -2,6 +2,7 @@ package container import ( "context" + "errors" "fmt" "strings" @@ -12,6 +13,7 @@ import ( containerTypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/client" + "coopcloud.tech/abra/pkg/i18n" ) // GetContainer retrieves a container. If noInput is false and the retrievd @@ -26,7 +28,7 @@ func GetContainer(c context.Context, cl *client.Client, filters filters.Args, no if len(containers) == 0 { filter := filters.Get("name")[0] - return types.Container{}, fmt.Errorf("no containers matching the %v filter found?", filter) + return types.Container{}, errors.New(i18n.G("no containers matching the %v filter found?", filter)) } if len(containers) > 1 { @@ -35,19 +37,19 @@ func GetContainer(c context.Context, cl *client.Client, filters filters.Args, no containerName := strings.Join(container.Names, " ") trimmed := strings.TrimPrefix(containerName, "/") created := formatter.HumanDuration(container.Created) - containersRaw = append(containersRaw, fmt.Sprintf("%s (created %v)", trimmed, created)) + containersRaw = append(containersRaw, i18n.G("%s (created %v)", trimmed, created)) } if noInput { - err := fmt.Errorf("expected 1 container but found %v: %s", len(containers), strings.Join(containersRaw, " ")) + err := errors.New(i18n.G("expected 1 container but found %v: %s", len(containers), strings.Join(containersRaw, " "))) return types.Container{}, err } - log.Warnf("ambiguous container list received, prompting for input") + log.Warnf(i18n.G("ambiguous container list received, prompting for input")) var response string prompt := &survey.Select{ - Message: "which container are you looking for?", + Message: i18n.G("which container are you looking for?"), Options: containersRaw, } @@ -64,7 +66,7 @@ func GetContainer(c context.Context, cl *client.Client, filters filters.Args, no } } - log.Fatal("failed to match chosen container") + log.Fatal(i18n.G("failed to match chosen container")) } return containers[0], nil @@ -79,5 +81,6 @@ func GetContainerFromStackAndService(cl *client.Client, stack, service string) ( if err != nil { return types.Container{}, err } + return container, nil } diff --git a/pkg/context/context.go b/pkg/context/context.go index 9842f23c..aa3f6fa3 100644 --- a/pkg/context/context.go +++ b/pkg/context/context.go @@ -8,6 +8,7 @@ import ( "github.com/docker/cli/cli/context" contextStore "github.com/docker/cli/cli/context/store" cliflags "github.com/docker/cli/cli/flags" + "coopcloud.tech/abra/pkg/i18n" ) func NewDefaultDockerContextStore() *command.ContextStoreWithDefault { @@ -30,7 +31,7 @@ func NewDefaultDockerContextStore() *command.ContextStoreWithDefault { func GetContextEndpoint(ctx contextStore.Metadata) (string, error) { endpointmeta, ok := ctx.Endpoints["docker"].(context.EndpointMetaBase) if !ok { - err := errors.New("context lacks Docker endpoint") + err := errors.New(i18n.G("context lacks Docker endpoint")) return "", err } return endpointmeta.Host, nil diff --git a/pkg/dns/dns.go b/pkg/dns/dns.go index 40497d66..145b8885 100644 --- a/pkg/dns/dns.go +++ b/pkg/dns/dns.go @@ -1,19 +1,21 @@ package dns import ( - "fmt" + "errors" "net" + + "coopcloud.tech/abra/pkg/i18n" ) // EnsureIPv4 ensures that an ipv4 address is set for a domain name func EnsureIPv4(domainName string) (string, error) { ipv4, err := net.ResolveIPAddr("ip4", domainName) if err != nil { - return "", fmt.Errorf("%s: unable to resolve IPv4 address: %s", domainName, err) + return "", errors.New(i18n.G("%s: unable to resolve IPv4 address: %s", domainName, err)) } if ipv4 == nil { - return "", fmt.Errorf("%s: no IPv4 available", domainName) + return "", errors.New(i18n.G("%s: no IPv4 available", domainName)) } return ipv4.String(), nil @@ -33,7 +35,7 @@ func EnsureDomainsResolveSameIPv4(domainName, server string) (string, error) { } if domainIPv4 == "" { - return ipv4, fmt.Errorf("cannot resolve ipv4 for %s?", domainName) + return ipv4, errors.New(i18n.G("cannot resolve ipv4 for %s?", domainName)) } serverIPv4, err := EnsureIPv4(server) @@ -42,12 +44,16 @@ func EnsureDomainsResolveSameIPv4(domainName, server string) (string, error) { } if serverIPv4 == "" { - return ipv4, fmt.Errorf("cannot resolve ipv4 for %s?", server) + return ipv4, errors.New(i18n.G("cannot resolve ipv4 for %s?", server)) } if domainIPv4 != serverIPv4 { - err := "app domain %s (%s) does not appear to resolve to app server %s (%s)?" - return ipv4, fmt.Errorf(err, domainName, domainIPv4, server, serverIPv4) + return ipv4, errors.New( + i18n.G( + "app domain %s (%s) does not appear to resolve to app server %s (%s)?", + domainName, domainIPv4, server, serverIPv4, + ), + ) } return ipv4, nil diff --git a/pkg/envfile/envfile.go b/pkg/envfile/envfile.go index 0e3bd80f..1e72675a 100644 --- a/pkg/envfile/envfile.go +++ b/pkg/envfile/envfile.go @@ -2,13 +2,14 @@ package envfile import ( "bufio" - "fmt" + "errors" "os" "regexp" "strings" "coopcloud.tech/abra/pkg/log" "git.coopcloud.tech/toolshed/godotenv" + "coopcloud.tech/abra/pkg/i18n" ) // AppEnv is a map of the values in an apps env config @@ -38,7 +39,7 @@ func ReadEnvWithModifiers(filePath string) (AppEnv, AppModifiers, error) { return nil, mods, err } - log.Debugf("read %s from %s", envVars, filePath) + log.Debug(i18n.G("read %s from %s", envVars, filePath)) return envVars, mods, nil } @@ -69,16 +70,16 @@ func ReadAbraShEnvVars(abraSh string) (map[string]string, error) { envVarDef := splitVals[len(splitVals)-1] keyVal := strings.Split(envVarDef, "=") if len(keyVal) != 2 { - return envVars, fmt.Errorf("couldn't parse %s", txt) + return envVars, errors.New(i18n.G("couldn't parse %s", txt)) } envVars[keyVal[0]] = keyVal[1] } } if len(envVars) > 0 { - log.Debugf("read %s from %s", envVars, abraSh) + log.Debug(i18n.G("read %s from %s", envVars, abraSh)) } else { - log.Debugf("read 0 env var exports from %s", abraSh) + log.Debug(i18n.G("read 0 env var exports from %s", abraSh)) } return envVars, nil diff --git a/pkg/formatter/formatter.go b/pkg/formatter/formatter.go index 3c4d1400..5482f352 100644 --- a/pkg/formatter/formatter.go +++ b/pkg/formatter/formatter.go @@ -11,6 +11,7 @@ import ( "github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss/table" "github.com/docker/go-units" + "coopcloud.tech/abra/pkg/i18n" "golang.org/x/term" "coopcloud.tech/abra/pkg/config" @@ -42,7 +43,7 @@ func RemoveSha(str string) string { func HumanDuration(timestamp int64) string { date := time.Unix(timestamp, 0) now := time.Now().UTC() - return units.HumanDuration(now.Sub(date)) + " ago" + return units.HumanDuration(now.Sub(date)) + i18n.G(" ago") } // CreateTable prepares a table layout for output. @@ -76,7 +77,7 @@ func CreateTable() (*table.Table, error) { func PrintTable(t *table.Table) error { if isAbraCI, ok := os.LookupEnv("ABRA_CI"); ok && isAbraCI == "1" { // NOTE(d1): no width limits for CI testing since we test against outputs - log.Debug("detected ABRA_CI=1") + log.Debug(i18n.G("detected ABRA_CI=1")) fmt.Println(t) return nil } @@ -130,7 +131,7 @@ func CreateOverview(header string, rows [][]string) string { } if len(row) > 2 { - panic("CreateOverview: only accepts rows of len == 2") + panic(i18n.G("CreateOverview: only accepts rows of len == 2")) } lenOffset := 4 @@ -234,7 +235,7 @@ func StripTagMeta(image string) string { } if originalImage != image { - log.Debugf("stripped %s to %s for parsing", originalImage, image) + log.Debug(i18n.G("stripped %s to %s for parsing", originalImage, image)) } return image diff --git a/pkg/git/add.go b/pkg/git/add.go index d5bc3d14..eb660b3a 100644 --- a/pkg/git/add.go +++ b/pkg/git/add.go @@ -3,6 +3,7 @@ package git import ( "coopcloud.tech/abra/pkg/log" "github.com/go-git/go-git/v5" + "coopcloud.tech/abra/pkg/i18n" ) // Add adds a file to the git index. @@ -18,7 +19,7 @@ func Add(repoPath, path string, dryRun bool) error { } if dryRun { - log.Debugf("dry run: adding %s", path) + log.Debug(i18n.G("dry run: adding %s", path)) } else { worktree.Add(path) } diff --git a/pkg/git/branch.go b/pkg/git/branch.go index 1125bd3a..6a42c561 100644 --- a/pkg/git/branch.go +++ b/pkg/git/branch.go @@ -1,11 +1,13 @@ package git import ( + "errors" "fmt" "coopcloud.tech/abra/pkg/log" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" + "coopcloud.tech/abra/pkg/i18n" ) // Check if a branch exists in a repo. Use this and not repository.Branch(), @@ -63,7 +65,7 @@ func GetDefaultBranch(repo *git.Repository, repoPath string) (plumbing.Reference if !HasBranch(repo, "master") { if !HasBranch(repo, "main") { - return "", fmt.Errorf("failed to select default branch in %s", repoPath) + return "", errors.New(i18n.G("failed to select default branch in %s", repoPath)) } branch = "main" } @@ -90,11 +92,11 @@ func CheckoutDefaultBranch(repo *git.Repository, repoPath string) (plumbing.Refe } if err := worktree.Checkout(checkOutOpts); err != nil { - log.Debugf("failed to check out %s in %s", branch, repoPath) + log.Debug(i18n.G("failed to check out %s in %s", branch, repoPath)) return branch, err } - log.Debugf("successfully checked out %v in %s", branch, repoPath) + log.Debug(i18n.G("successfully checked out %v in %s", branch, repoPath)) return branch, nil } diff --git a/pkg/git/clone.go b/pkg/git/clone.go index 87145f54..9c10eb78 100644 --- a/pkg/git/clone.go +++ b/pkg/git/clone.go @@ -2,6 +2,7 @@ package git import ( "context" + "errors" "fmt" "os" "os/signal" @@ -10,6 +11,7 @@ import ( "coopcloud.tech/abra/pkg/log" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" + "coopcloud.tech/abra/pkg/i18n" ) // gitCloneIgnoreErr checks whether we can ignore a git clone error or not. @@ -44,7 +46,7 @@ func Clone(dir, url string) error { go func() { if _, err := os.Stat(dir); os.IsNotExist(err) { - log.Debugf("git clone: %s", url) + log.Debug(i18n.G("git clone: %s", url)) _, err := git.PlainCloneContext(ctx, dir, false, &git.CloneOptions{ URL: url, @@ -54,16 +56,16 @@ func Clone(dir, url string) error { }) if err != nil && gitCloneIgnoreErr(err) { - log.Debugf("git clone: %s cloned successfully", dir) + log.Debug(i18n.G("git clone: %s cloned successfully", dir)) errCh <- nil } if err := ctx.Err(); err != nil { - errCh <- fmt.Errorf("git clone %s: cancelled due to interrupt", dir) + errCh <- errors.New(i18n.G("git clone %s: cancelled due to interrupt", dir)) } if err != nil { - log.Debug("git clone: main branch failed, attempting master branch") + log.Debug(i18n.G("git clone: main branch failed, attempting master branch")) _, err := git.PlainCloneContext(ctx, dir, false, &git.CloneOptions{ URL: url, @@ -73,7 +75,7 @@ func Clone(dir, url string) error { }) if err != nil && gitCloneIgnoreErr(err) { - log.Debugf("git clone: %s cloned successfully", dir) + log.Debug(i18n.G("git clone: %s cloned successfully", dir)) errCh <- nil } @@ -82,9 +84,9 @@ func Clone(dir, url string) error { } } - log.Debugf("git clone: %s cloned successfully", dir) + log.Debug(i18n.G("git clone: %s cloned successfully", dir)) } else { - log.Debugf("git clone: %s already exists", dir) + log.Debug(i18n.G("git clone: %s already exists", dir)) } errCh <- nil @@ -95,9 +97,9 @@ func Clone(dir, url string) error { cancelCtx() fmt.Println() // NOTE(d1): newline after ^C if err := os.RemoveAll(dir); err != nil { - return fmt.Errorf("unable to clean up git clone of %s: %s", dir, err) + return errors.New(i18n.G("unable to clean up git clone of %s: %s", dir, err)) } - return fmt.Errorf("git clone %s: cancelled due to interrupt", dir) + return errors.New(i18n.G("git clone %s: cancelled due to interrupt", dir)) case err := <-errCh: return err } diff --git a/pkg/git/commit.go b/pkg/git/commit.go index 7775e518..a7ff9f29 100644 --- a/pkg/git/commit.go +++ b/pkg/git/commit.go @@ -1,16 +1,17 @@ package git import ( - "fmt" + "errors" "coopcloud.tech/abra/pkg/log" "github.com/go-git/go-git/v5" + "coopcloud.tech/abra/pkg/i18n" ) // Commit runs a git commit func Commit(repoPath, commitMessage string, dryRun bool) error { if commitMessage == "" { - return fmt.Errorf("no commit message specified?") + return errors.New(i18n.G("no commit message specified?")) } commitRepo, err := git.PlainOpen(repoPath) @@ -38,9 +39,9 @@ func Commit(repoPath, commitMessage string, dryRun bool) error { if err != nil { return err } - log.Debug("git changes commited") + log.Debug(i18n.G("git changes commited")) } else { - log.Debug("dry run: no changes commited") + log.Debug(i18n.G("dry run: no changes commited")) } return nil diff --git a/pkg/git/common.go b/pkg/git/common.go index ff4eb7d7..e41f2124 100644 --- a/pkg/git/common.go +++ b/pkg/git/common.go @@ -1,14 +1,16 @@ package git import ( - "fmt" + "errors" "os" + + "coopcloud.tech/abra/pkg/i18n" ) // EnsureGitRepo ensures a git repo .git folder exists func EnsureGitRepo(repoPath string) error { if _, err := os.Stat(repoPath); os.IsNotExist(err) { - return fmt.Errorf("no .git directory in %s?", repoPath) + return errors.New(i18n.G("no .git directory in %s?", repoPath)) } return nil } diff --git a/pkg/git/diff.go b/pkg/git/diff.go index 6242d654..2e9a3377 100644 --- a/pkg/git/diff.go +++ b/pkg/git/diff.go @@ -5,6 +5,7 @@ import ( "os/exec" "coopcloud.tech/abra/pkg/log" + "coopcloud.tech/abra/pkg/i18n" ) // getGitDiffArgs builds the `git diff` invocation args. It removes the usage @@ -26,7 +27,7 @@ func getGitDiffArgs(repoPath string) []string { // skips if it cannot find the command on the system. func DiffUnstaged(path string) error { if _, err := exec.LookPath("git"); err != nil { - log.Warnf("unable to locate git command, cannot output diff") + log.Warnf(i18n.G("unable to locate git command, cannot output diff")) return nil } diff --git a/pkg/git/init.go b/pkg/git/init.go index 5adf37b1..ad7e6f0a 100644 --- a/pkg/git/init.go +++ b/pkg/git/init.go @@ -1,40 +1,41 @@ package git import ( - "fmt" + "errors" "coopcloud.tech/abra/pkg/log" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/object" + "coopcloud.tech/abra/pkg/i18n" ) // Init inits a new repo and commits all the stuff if you want func Init(repoPath string, commit bool, gitName, gitEmail string) error { repo, err := git.PlainInit(repoPath, false) if err != nil { - return fmt.Errorf("git init: %s", err) + return errors.New(i18n.G("git init: %s", err)) } if err = SwitchToMain(repo); err != nil { - return fmt.Errorf("git branch rename: %s", err) + return errors.New(i18n.G("git branch rename: %s", err)) } - log.Debugf("initialised new git repo in %s", repoPath) + log.Debug(i18n.G("initialised new git repo in %s", repoPath)) if commit { commitRepo, err := git.PlainOpen(repoPath) if err != nil { - return fmt.Errorf("git open: %s", err) + return errors.New(i18n.G("git open: %s", err)) } commitWorktree, err := commitRepo.Worktree() if err != nil { - return fmt.Errorf("git worktree: %s", err) + return errors.New(i18n.G("git worktree: %s", err)) } if err := commitWorktree.AddWithOptions(&git.AddOptions{All: true}); err != nil { - return fmt.Errorf("git add: %s", err) + return errors.New(i18n.G("git add: %s", err)) } var author *object.Signature @@ -43,10 +44,10 @@ func Init(repoPath string, commit bool, gitName, gitEmail string) error { } if _, err = commitWorktree.Commit("init", &git.CommitOptions{Author: author}); err != nil { - return fmt.Errorf("git commit: %s", err) + return errors.New(i18n.G("git commit: %s", err)) } - log.Debugf("init committed all files for new git repo in %s", repoPath) + log.Debug(i18n.G("init committed all files for new git repo in %s", repoPath)) } return nil @@ -56,20 +57,20 @@ func Init(repoPath string, commit bool, gitName, gitEmail string) error { func SwitchToMain(repo *git.Repository) error { ref := plumbing.NewSymbolicReference(plumbing.HEAD, plumbing.ReferenceName("refs/heads/main")) if err := repo.Storer.SetReference(ref); err != nil { - return fmt.Errorf("set reference: %s", err) + return errors.New(i18n.G("set reference: %s", err)) } cfg, err := repo.Config() if err != nil { - return fmt.Errorf("repo config: %s", err) + return errors.New(i18n.G("repo config: %s", err)) } cfg.Init.DefaultBranch = "main" if err := repo.SetConfig(cfg); err != nil { - return fmt.Errorf("repo set config: %s", err) + return errors.New(i18n.G("repo set config: %s", err)) } - log.Debug("set 'main' as the default branch") + log.Debug(i18n.G("set 'main' as the default branch")) return nil } diff --git a/pkg/git/push.go b/pkg/git/push.go index 9d279e65..77b64e7c 100644 --- a/pkg/git/push.go +++ b/pkg/git/push.go @@ -4,12 +4,13 @@ import ( "coopcloud.tech/abra/pkg/log" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/config" + "coopcloud.tech/abra/pkg/i18n" ) // Push pushes the latest changes & optionally tags to the default remote func Push(repoDir string, remote string, tags bool, dryRun bool) error { if dryRun { - log.Debugf("dry run: no git changes pushed in %s", repoDir) + log.Debug(i18n.G("dry run: no git changes pushed in %s", repoDir)) return nil } @@ -27,7 +28,7 @@ func Push(repoDir string, remote string, tags bool, dryRun bool) error { return err } - log.Debugf("git changes pushed") + log.Debug(i18n.G("git changes pushed")) if tags { opts.RefSpecs = append(opts.RefSpecs, config.RefSpec("+refs/tags/*:refs/tags/*")) @@ -36,7 +37,7 @@ func Push(repoDir string, remote string, tags bool, dryRun bool) error { return err } - log.Debugf("git tags pushed") + log.Debug(i18n.G("git tags pushed")) } return nil diff --git a/pkg/git/read.go b/pkg/git/read.go index b2991357..8e08ee99 100644 --- a/pkg/git/read.go +++ b/pkg/git/read.go @@ -2,7 +2,6 @@ package git import ( "errors" - "fmt" "io/ioutil" "os" "os/user" @@ -13,6 +12,7 @@ import ( "github.com/go-git/go-git/v5" gitConfigPkg "github.com/go-git/go-git/v5/config" "github.com/go-git/go-git/v5/plumbing/format/gitignore" + "coopcloud.tech/abra/pkg/i18n" ) // IsClean checks if a repo has unstaged changes @@ -23,12 +23,12 @@ func IsClean(repoPath string) (bool, error) { return false, git.ErrRepositoryNotExists } - return false, fmt.Errorf("unable to open %s: %s", repoPath, err) + return false, errors.New(i18n.G("unable to open %s: %s", repoPath, err)) } worktree, err := repo.Worktree() if err != nil { - return false, fmt.Errorf("unable to open worktree of %s: %s", repoPath, err) + return false, errors.New(i18n.G("unable to open worktree of %s: %s", repoPath, err)) } patterns, err := GetExcludesFiles() @@ -42,14 +42,14 @@ func IsClean(repoPath string) (bool, error) { status, err := worktree.Status() if err != nil { - return false, fmt.Errorf("unable to query status of %s: %s", repoPath, err) + return false, errors.New(i18n.G("unable to query status of %s: %s", repoPath, err)) } if status.String() != "" { noNewline := strings.TrimSuffix(status.String(), "\n") - log.Debugf("git status: %s: %s", repoPath, noNewline) + log.Debug(i18n.G("git status: %s: %s", repoPath, noNewline)) } else { - log.Debugf("git status: %s: clean", repoPath) + log.Debug(i18n.G("git status: %s: clean", repoPath)) } return status.IsClean(), nil @@ -85,7 +85,7 @@ func parseGitConfig() (*gitConfigPkg.Config, error) { globalGitConfig := filepath.Join(usr.HomeDir, ".gitconfig") if _, err := os.Stat(globalGitConfig); err != nil { if os.IsNotExist(err) { - log.Debugf("no %s exists, not reading any global gitignore config", globalGitConfig) + log.Debug(i18n.G("no %s exists, not reading any global gitignore config", globalGitConfig)) return cfg, nil } return cfg, err @@ -127,7 +127,7 @@ func parseExcludesFile(excludesfile string) ([]gitignore.Pattern, error) { if _, err := os.Stat(excludesfile); err != nil { if os.IsNotExist(err) { - log.Debugf("no %s exists, skipping reading gitignore paths", excludesfile) + log.Debug(i18n.G("no %s exists, skipping reading gitignore paths", excludesfile)) return ps, nil } return ps, err @@ -146,7 +146,7 @@ func parseExcludesFile(excludesfile string) ([]gitignore.Pattern, error) { } } - log.Debugf("read global ignore paths: %s", strings.Join(pathsRaw, " ")) + log.Debug(i18n.G("read global ignore paths: %s", strings.Join(pathsRaw, " "))) return ps, nil } diff --git a/pkg/git/remote.go b/pkg/git/remote.go index 5d7d7af4..1a96b232 100644 --- a/pkg/git/remote.go +++ b/pkg/git/remote.go @@ -6,12 +6,13 @@ import ( "coopcloud.tech/abra/pkg/log" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/config" + "coopcloud.tech/abra/pkg/i18n" ) // CreateRemote creates a new git remote in a repository func CreateRemote(repo *git.Repository, name, url string, dryRun bool) error { if dryRun { - log.Debugf("dry run: remote %s (%s) not created", name, url) + log.Debug(i18n.G("dry run: remote %s (%s) not created", name, url)) return nil } diff --git a/pkg/i18n/i18n.go b/pkg/i18n/i18n.go new file mode 100644 index 00000000..a3f01b92 --- /dev/null +++ b/pkg/i18n/i18n.go @@ -0,0 +1,34 @@ +package i18n + +import ( + "embed" + "fmt" + "os" + + "github.com/leonelquinteros/gotext" +) + +//go:embed locales +var assetFS embed.FS + +func GetLocale() string { + return os.Getenv("LANG") +} + +func LoadLocale() *gotext.Po { + locale := GetLocale() + + localePath := fmt.Sprintf("locales/%s/LC_MESSAGES/default.po", locale) + + b, err := assetFS.ReadFile(localePath) + if err != nil { + panic(fmt.Sprintf("i18n: unable to load %s: %s", localePath, err)) + } + + po := gotext.NewPo() + po.Parse(b) + + return po +} + +var G = LoadLocale().Get diff --git a/pkg/i18n/locales/default.pot b/pkg/i18n/locales/default.pot new file mode 100644 index 00000000..b4823b69 --- /dev/null +++ b/pkg/i18n/locales/default.pot @@ -0,0 +1,3582 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "Project-Id-Version: \n" + "Report-Msgid-Bugs-To: EMAIL\n" + "POT-Creation-Date: 2025-08-23 14:02+0200\n" + "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" + "Last-Translator: FULL NAME \n" + "Language-Team: LANGUAGE \n" + "Language: \n" + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" + +#: ./pkg/dns/dns.go:52 +#, c-format +msgid "app domain %s (%s) does not appear to resolve to app server %s (%s)?" +msgstr "" + +#: ./cli/app/new.go:324 +msgid "no server provided" +msgstr "" + +#: ./cli/app/backup.go:49 +#, c-format +msgid "including SHOW_ALL=%v in backupbot exec invocation" +msgstr "" + +#: ./cli/upgrade.go:55 +msgid "install release candidate (may contain bugs)" +msgstr "" + +#: ./pkg/server/server.go:25 +#, c-format +msgid "successfully created %s" +msgstr "" + +#: ./cli/app/restore.go:118 +msgid "restore specific volumes" +msgstr "" + +#: ./cli/app/services.go:67 +msgid "SERVICE (SHORT)" +msgstr "" + +#: ./cli/app/restart.go:68 +msgid "cannot use [service] and --all-services/-a together" +msgstr "" + +#: ./cli/app/volume.go:190 +msgid "volume [cmd] [args] [flags]" +msgstr "" + +#: ./cli/app/secret.go:374 +msgid "List all secrets" +msgstr "" + +#: ./cli/app/new.go:266 +msgid "Specify app domain" +msgstr "" + +#: ./cli/app/check.go:17 +msgid "check [flags]" +msgstr "" + +#: ./cli/app/cp.go:85 +msgid "one of / arguments must take $SERVICE:$PATH form" +msgstr "" + +#: ./cli/upgrade.go:16 +msgid "upgrade [flags]" +msgstr "" + +#: ./pkg/recipe/git.go:262 +#, c-format +msgid "unable to fetch tags in %s: %s" +msgstr "" + +#: ./pkg/recipe/recipe.go:458 +#, c-format +msgid "recipe %s does not exist?" +msgstr "" + +#: ./cli/app/list.go:288 +msgid "status" +msgstr "" + +#: ./pkg/secret/secret.go:207 +#, c-format +msgid "skipping generation of %s (generate=false)" +msgstr "" + +#: ./pkg/recipe/recipe.go:207 +#, c-format +msgid "sample env: %s, " +msgstr "" + +#: ./cli/app/volume.go:78 +msgid "Remove volumes associated with an app.\n" + "\n" + "The app in question must be undeployed before you try to remove volumes. See\n" + "\"abra app undeploy \" for more.\n" + "\n" + "The command is interactive and will show a multiple select input which allows\n" + "you to make a seclection. Use the \"?\" key to see more help on navigating this\n" + "interface.\n" + "\n" + "Passing \"--force/-f\" will select all volumes for removal. Be careful." +msgstr "" + +#: ./pkg/recipe/git.go:187 +#, c-format +msgid "unable to check git clean status in %s: %s" +msgstr "" + +#: ./pkg/recipe/recipe.go:330 +#, c-format +msgid "%s: image meta is empty?" +msgstr "" + +#: ./cli/app/rollback.go:28 +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" + "versions are supported values for \"[version]\".\n" + "\n" + "It is possible to \"--force/-f\" an downgrade if you want to re-deploy a specific\n" + "version.\n" + "\n" + "Only the deployed version is consulted when trying to determine what downgrades\n" + "are available. The live deployment version is the \"source of truth\" in this\n" + "case. The stored .env version is not consulted.\n" + "\n" + "A downgrade can be destructive, please ensure you have a copy of your app data\n" + "beforehand. See \"abra app backup\" for more." +msgstr "" + +#: ./cli/app/secret.go:373 ./cli/app/cmd.go:197 ./cli/app/backup.go:16 ./cli/app/volume.go:20 ./cli/app/list.go:44 +msgid "ls" +msgstr "" + +#: ./cli/app/secret.go:459 ./cli/app/secret.go:555 ./cli/app/ps.go:198 ./cli/app/list.go:311 +msgid "machine" +msgstr "" + +#: ./cli/app/volume.go:21 +msgid "List volumes associated with an app" +msgstr "" + +#: ./cli/app/list.go:153 +#, c-format +msgid "unable to retrieve tags for %s: %s" +msgstr "" + +#: ./cli/app/list.go:177 +msgid "latest" +msgstr "" + +#: ./cli/app/list.go:296 ./cli/app/list.go:303 ./cli/run.go:32 +msgid "recipe" +msgstr "" + +#: ./cli/upgrade.go:18 +msgid "Upgrade abra" +msgstr "" + +#: ./cli/app/undeploy.go:155 +msgid "prune" +msgstr "" + +#: ./cli/app/deploy.go:28 +msgid "deploy [version] [flags]" +msgstr "" + +#: ./cli/app/cp.go:72 +#, c-format +msgid "retrieved %s as target container on %s" +msgstr "" + +#: ./cli/app/remove.go:73 ./cli/app/volume.go:120 +#, c-format +msgid "%s is still deployed. Run \"abra app undeploy %s\"" +msgstr "" + +#: ./cli/server/add.go:137 +#, c-format +msgid "serverAdd: cleanUp: unable to list files in %s: %s" +msgstr "" + +#: ./pkg/upstream/container/hijack.go:156 +msgid "[hijack] End of stdin" +msgstr "" + +#: ./pkg/upstream/convert/service.go:462 +#, c-format +msgid "undefined config %q" +msgstr "" + +#: ./pkg/recipe/git.go:52 +#, c-format +msgid "can not redeploy chaos version (%s) without --chaos" +msgstr "" + +#: ./cli/app/secret.go:260 +msgid "remove [[secret] | --all] [flags]" +msgstr "" + +#: ./cli/app/new.go:315 +msgid "Select app server:" +msgstr "" + +#: ./cli/app/cp.go:245 +#, c-format +msgid "copy: %s" +msgstr "" + +#: ./cli/app/logs.go:20 +msgid "Tail app logs" +msgstr "" + +#: ./cli/app/backup.go:263 +msgid "path" +msgstr "" + +#: ./cli/app/list.go:216 +msgid "DOMAIN" +msgstr "" + +#: ./pkg/client/context.go:66 +msgid "context 'default' cannot be removed" +msgstr "" + +#: ./pkg/dns/dns.go:18 +#, c-format +msgid "%s: no IPv4 available" +msgstr "" + +#: ./pkg/ssh/ssh.go:20 +#, c-format +msgid "connection timed out for %s" +msgstr "" + +#: ./pkg/recipe/git.go:225 ./pkg/recipe/git.go:406 ./pkg/git/branch.go:95 +#, c-format +msgid "failed to check out %s in %s" +msgstr "" + +#: ./pkg/recipe/recipe.go:199 +#, c-format +msgid "{name: %s, " +msgstr "" + +#: ./pkg/recipe/recipe.go:208 +#, c-format +msgid "abra.sh: %s}" +msgstr "" + +#: ./pkg/git/read.go:31 +#, c-format +msgid "unable to open worktree of %s: %s" +msgstr "" + +#: ./pkg/container/container.go:69 +msgid "failed to match chosen container" +msgstr "" + +#: ./cli/app/backup.go:242 +msgid "show all paths" +msgstr "" + +#: ./cli/catalogue/catalogue.go:191 +msgid "chore: publish new catalogue release changes" +msgstr "" + +#: ./cli/upgrade.go:37 ./pkg/secret/pass.go:23 ./pkg/secret/pass.go:45 +#, c-format +msgid "attempting to run %s" +msgstr "" + +#: ./pkg/upstream/convert/service.go:652 +#, c-format +msgid "unknown restart policy: %s" +msgstr "" + +#: ./cli/app/secret.go:468 ./cli/app/secret.go:492 ./cli/app/secret.go:532 ./cli/app/ps.go:29 ./cli/app/undeploy.go:156 ./cli/app/new.go:364 ./cli/app/backup.go:264 +msgid "p" +msgstr "" + +#: ./cli/app/cmd.go:67 +msgid "requires at least 3 arguments" +msgstr "" + +#: ./cli/app/upgrade.go:323 +#, c-format +msgid "parsing deployment version failed: %s" +msgstr "" + +#: ./cli/app/cp.go:164 +#, c-format +msgid "copy %s from local to %s on container" +msgstr "" + +#: ./cli/app/config.go:36 +#, c-format +msgid "cannot find app with name %s" +msgstr "" + +#: ./cli/run.go:134 +msgid "toggle non-interactive mode" +msgstr "" + +#: ./pkg/upstream/convert/service.go:813 +#, c-format +msgid "invalid credential spec: cannot specify both %s and %s" +msgstr "" + +#: ./cli/app/secret.go:478 ./cli/app/secret.go:518 ./cli/app/secret.go:542 ./cli/app/secret.go:550 ./cli/app/restore.go:134 ./cli/app/ps.go:209 ./cli/app/cmd.go:275 ./cli/app/new.go:382 ./cli/app/check.go:90 ./cli/app/restart.go:157 ./cli/app/deploy.go:329 ./cli/app/cp.go:381 ./cli/app/backup.go:290 ./cli/app/backup.go:306 ./cli/app/labels.go:138 ./cli/catalogue/catalogue.go:274 +msgid "ignore uncommitted recipes changes" +msgstr "" + +#: ./cli/app/new.go:343 +msgid "specify server for new app" +msgstr "" + +#: ./cli/app/logs.go:96 +msgid "only tail stderr" +msgstr "" + +#: ./cli/app/logs.go:104 +msgid "tail logs since YYYY-MM-DDTHH:MM:SSZ" +msgstr "" + +#: ./pkg/lint/recipe.go:68 +msgid "compose config has expected version" +msgstr "" + +#: ./pkg/recipe/git.go:434 +#, c-format +msgid "%s service is missing image tag?" +msgstr "" + +#: ./pkg/recipe/recipe.go:462 +#, c-format +msgid "recipe metadata retrieved for %s" +msgstr "" + +#: ./cli/app/secret.go:145 +msgid "Insert secret" +msgstr "" + +#: ./cli/app/new.go:355 +msgid "domain" +msgstr "" + +#: ./cli/app/list.go:299 +msgid "show apps of a specific recipe" +msgstr "" + +#: ./cli/run.go:31 +msgid "man" +msgstr "" + +#: ./cli/server/prune.go:17 +msgid "Prune resources on a server" +msgstr "" + +#: ./cli/server/add.go:141 +#, c-format +msgid "serverAdd: cleanUp: %s is not empty, aborting cleanup" +msgstr "" + +#: ./pkg/upstream/convert/volume.go:90 +msgid "invalid bind source, source cannot be empty" +msgstr "" + +#: ./pkg/recipe/git.go:151 +#, c-format +msgid "read %s as tags for recipe %s" +msgstr "" + +#: ./cli/app/secret.go:144 +msgid "i" +msgstr "" + +#: ./cli/app/check.go:19 +msgid "Ensure an app is well configured" +msgstr "" + +#: ./cli/app/deploy.go:29 ./cli/app/backup.go:66 +msgid "d" +msgstr "" + +#: ./cli/app/deploy.go:101 +#, c-format +msgid "get deploy version: %s" +msgstr "" + +#: ./cli/app/remove.go:19 +msgid "remove [flags]" +msgstr "" + +#: ./cli/app/backup.go:17 +msgid "List the contents of a snapshot" +msgstr "" + +#: ./cli/complete.go:13 +msgid "To load completions:\n" + "\n" + "Bash:\n" + " # Load autocompletion for the current Bash session\n" + " $ source <(abra autocomplete bash)\n" + "\n" + " # To load autocompletion for each session, execute once:\n" + " # Linux:\n" + " $ abra autocomplete bash | sudo tee /etc/bash_completion.d/abra\n" + " # macOS:\n" + " $ abra autocomplete bash | sudo tee $(brew --prefix)/etc/bash_completion.d/abra\n" + "\n" + "Zsh:\n" + " # If shell autocompletion is not already enabled in your environment,\n" + " # you will need to enable it. You can execute the following once:\n" + "\n" + " $ echo \"autoload -U compinit; compinit\" >> ~/.zshrc\n" + "\n" + " # To load autocompletions for each session, execute once:\n" + " $ abra autocomplete zsh > \"${fpath[1]}/_abra\"\n" + "\n" + " # You will need to start a new shell for this setup to take effect.\n" + "\n" + "fish:\n" + " $ abra autocomplete fish | source\n" + "\n" + " # To load autocompletions for each session, execute once:\n" + " $ abra autocomplete fish > ~/.config/fish/completions/abra.fish\n" + "\n" + "PowerShell:\n" + " PS> abra autocomplete powershell | Out-String | Invoke-Expression\n" + "\n" + " # To load autocompletions for every new session, run:\n" + " PS> abra autocomplete powershell > abra.ps1\n" + " # and source this file from your PowerShell profile." +msgstr "" + +#: ./pkg/recipe/git.go:251 +#, c-format +msgid "unable to open git work tree in %s: %s" +msgstr "" + +#: ./cli/app/secret.go:102 +msgid "no secrets generated" +msgstr "" + +#: ./cli/app/upgrade.go:329 ./cli/app/upgrade.go:368 +#, c-format +msgid "parsing recipe version failed: %s" +msgstr "" + +#: ./cli/app/upgrade.go:443 ./cli/app/new.go:356 ./cli/app/rollback.go:332 ./cli/app/deploy.go:343 +msgid "D" +msgstr "" + +#: ./pkg/lint/recipe.go:90 +msgid "tag all images with stable tags" +msgstr "" + +#: ./pkg/lint/recipe.go:154 +msgid "traefik routing enabled" +msgstr "" + +#: ./pkg/upstream/commandconn/connection.go:38 +msgid "ssh host connection is not valid" +msgstr "" + +#: ./pkg/git/init.go:73 +msgid "set 'main' as the default branch" +msgstr "" + +#: ./cli/app/secret.go:394 ./cli/app/ps.go:182 ./cli/app/list.go:221 +msgid "VERSION" +msgstr "" + +#: ./cli/app/secret.go:462 ./cli/app/secret.go:558 ./cli/app/ps.go:201 ./cli/app/list.go:314 ./cli/server/list.go:102 +msgid "print machine-readable output" +msgstr "" + +#: ./cli/app/secret.go:475 ./cli/app/secret.go:515 ./cli/app/secret.go:539 ./cli/app/secret.go:547 ./cli/app/restore.go:131 ./cli/app/ps.go:206 ./cli/app/cmd.go:272 ./cli/app/new.go:379 ./cli/app/check.go:87 ./cli/app/restart.go:154 ./cli/app/deploy.go:326 ./cli/app/cp.go:378 ./cli/app/backup.go:287 ./cli/app/backup.go:303 ./cli/app/labels.go:135 +msgid "chaos" +msgstr "" + +#: ./cli/app/upgrade.go:445 ./cli/app/rollback.go:334 ./cli/app/deploy.go:345 +msgid "disable public DNS checks" +msgstr "" + +#: ./cli/run.go:78 +#, c-format +msgid "abra version: %s, commit: %s, lang: %s" +msgstr "" + +#: ./pkg/catalogue/catalogue.go:40 +#, c-format +msgid "%s has locally unstaged changes? please commit/remove your changes before proceeding" +msgstr "" + +#: ./pkg/upstream/commandconn/commandconn.go:141 +msgid "commandconn: failed to wait" +msgstr "" + +#: ./pkg/upstream/convert/service.go:780 +#, c-format +msgid "unknown mode: %s" +msgstr "" + +#: ./cli/app/upgrade.go:290 +#, c-format +msgid "please select an upgrade (version: %s, chaos: %s):" +msgstr "" + +#: ./pkg/service/service.go:41 +#, c-format +msgid "no services deployed matching label '%s'?" +msgstr "" + +#: ./pkg/lint/recipe.go:97 +msgid "use semver-like tags" +msgstr "" + +#: ./pkg/upstream/container/hijack.go:135 +#, c-format +msgid "error receiveStdout: %s" +msgstr "" + +#: ./pkg/ui/deploy.go:341 +#, c-format +msgid "%s: %s (retries: %v, healthcheck: %s)" +msgstr "" + +#: ./pkg/config/env.go:74 ./pkg/config/env.go:107 +#, c-format +msgid "broken symlink in your abra config folders: %s" +msgstr "" + +#: ./pkg/git/common.go:13 +#, c-format +msgid "no .git directory in %s?" +msgstr "" + +#: ./pkg/git/init.go:70 +#, c-format +msgid "repo set config: %s" +msgstr "" + +#: ./cli/app/cmd.go:22 +msgid "command [service | --local] [[args] [flags] | [flags] -- [args]]" +msgstr "" + +#: ./cli/app/run.go:22 ./cli/app/upgrade.go:459 ./cli/app/backup.go:296 ./cli/app/list.go:297 +msgid "r" +msgstr "" + +#: ./cli/app/upgrade.go:442 ./cli/app/rollback.go:331 ./cli/app/deploy.go:342 +msgid "no-domain-checks" +msgstr "" + +#: ./cli/app/deploy.go:296 +#, c-format +msgid "version: taking version from cli arg: %s" +msgstr "" + +#: ./cli/catalogue/catalogue.go:258 +msgid "report changes that would be made" +msgstr "" + +#: ./cli/server/add.go:107 +#, c-format +msgid "ssh %s error: %s" +msgstr "" + +#: ./pkg/client/client.go:44 +#, c-format +msgid "unknown server, run \"abra server add %s\"?" +msgstr "" + +#: ./pkg/lint/recipe.go:52 +#, c-format +msgid "%s: skip condition: %s" +msgstr "" + +#: ./cli/app/new.go:358 +msgid "domain name for app" +msgstr "" + +#: ./cli/app/secret.go:366 +msgid "no secrets to remove?" +msgstr "" + +#: ./cli/app/secret.go:394 +msgid "CREATED ON SERVER" +msgstr "" + +#: ./pkg/client/client.go:88 +#, c-format +msgid "created client for %s" +msgstr "" + +#: ./pkg/lint/recipe.go:96 +msgid "tags use semver-like format" +msgstr "" + +#: ./cli/app/secret.go:134 +#, c-format +msgid "generated secrets %s shown again, please take note of them %s" +msgstr "" + +#: ./cli/app/cmd.go:108 +#, c-format +msgid "%s does not exist for %s?" +msgstr "" + +#: ./cli/app/env.go:15 +msgid "env [flags]" +msgstr "" + +#: ./cli/app/list.go:322 +msgid "show apps of a specific server" +msgstr "" + +#: ./cli/app/labels.go:53 +msgid "DEPLOYED LABELS" +msgstr "" + +#: ./cli/app/restore.go:18 +msgid "Restore a snapshot" +msgstr "" + +#: ./cli/app/restart.go:108 +#, c-format +msgid "attempting to scale %s to 0" +msgstr "" + +#: ./cli/app/remove.go:94 +msgid "no configs to remove" +msgstr "" + +#: ./pkg/ssh/ssh.go:22 +#, c-format +msgid "ssh auth: permission denied for %s" +msgstr "" + +#: ./pkg/secret/pass.go:51 +#, c-format +msgid "%s removed from pass store" +msgstr "" + +#: ./pkg/upstream/convert/volume.go:116 +msgid "volume options are incompatible with type tmpfs" +msgstr "" + +#: ./pkg/recipe/compose.go:58 +#, c-format +msgid "COMPOSE_FILE detected (%s), loading %s" +msgstr "" + +#: ./pkg/recipe/recipe.go:361 +#, c-format +msgid "%s: marker string %s not found" +msgstr "" + +#: ./cli/app/upgrade.go:458 +msgid "releasenotes" +msgstr "" + +#: ./cli/app/undeploy.go:128 ./cli/server/prune.go:45 +#, c-format +msgid "containers pruned: %d; space reclaimed: %s" +msgstr "" + +#: ./cli/app/cp.go:253 +#, c-format +msgid "untar: %s" +msgstr "" + +#: ./cli/app/labels.go:102 +msgid "LABELS OVERVIEW" +msgstr "" + +#: ./cli/server/list.go:20 +msgid "List managed servers" +msgstr "" + +#: ./pkg/upstream/commandconn/commandconn.go:162 +#, c-format +msgid "command %v did not exit after %v: stderr=%q" +msgstr "" + +#: ./pkg/recipe/compose.go:248 +msgid "no existing label found, automagic insertion not supported yet" +msgstr "" + +#: ./cli/app/new.go:309 +#, c-format +msgid "single server detected, choosing %s automatically" +msgstr "" + +#: ./cli/app/remove.go:141 +msgid "no volumes to remove" +msgstr "" + +#: ./cli/app/backup.go:234 ./cli/app/backup.go:258 +msgid "list specific snapshot" +msgstr "" + +#: ./cli/app/volume.go:145 +#, c-format +msgid "unable to remove volume: no volume with name '%s'?" +msgstr "" + +#: ./pkg/recipe/compose.go:159 +#, c-format +msgid "parsed %s from %s" +msgstr "" + +#: ./cli/app/secret.go:261 ./cli/app/remove.go:20 ./cli/app/volume.go:93 +msgid "rm" +msgstr "" + +#: ./cli/app/cmd.go:251 +msgid "run command locally" +msgstr "" + +#: ./cli/app/new.go:135 +#, c-format +msgid "%s sanitised as %s for new app" +msgstr "" + +#: ./cli/app/volume.go:184 +msgid "no volumes removed" +msgstr "" + +#: ./pkg/upstream/convert/service.go:414 +#, c-format +msgid "undefined secret %q" +msgstr "" + +#: ./cli/app/secret.go:267 +msgid " abra app secret rm 1312.net oauth_key" +msgstr "" + +#: ./cli/app/cp.go:145 ./cli/app/cp.go:184 +#, c-format +msgid "create remote directory: %s" +msgstr "" + +#: ./pkg/formatter/formatter.go:46 +msgid " ago" +msgstr "" + +#: ./cli/app/upgrade.go:30 +msgid "up" +msgstr "" + +#: ./pkg/lint/recipe.go:111 +msgid "fill out all the metadata" +msgstr "" + +#: ./pkg/git/init.go:21 +#, c-format +msgid "git branch rename: %s" +msgstr "" + +#: ./pkg/git/init.go:29 +#, c-format +msgid "git open: %s" +msgstr "" + +#: ./cli/app/secret.go:124 ./cli/app/secret.go:424 ./cli/server/list.go:82 +#, c-format +msgid "unable to render to JSON: %s" +msgstr "" + +#: ./cli/app/restore.go:74 +#, c-format +msgid "including CONTAINER=%s in backupbot exec invocation" +msgstr "" + +#: ./cli/app/run.go:105 +msgid "do not request a TTY" +msgstr "" + +#: ./cli/app/new.go:118 +#, c-format +msgid "failed to retrieve latest commit for %s: %s" +msgstr "" + +#: ./cli/app/remove.go:148 +#, c-format +msgid "file: %s removed" +msgstr "" + +#: ./cli/app/backup.go:250 +msgid "include timestamps" +msgstr "" + +#: ./pkg/upstream/convert/volume.go:56 +#, c-format +msgid "undefined volume %q" +msgstr "" + +#: ./cli/app/restore.go:110 +msgid "restore specific services" +msgstr "" + +#: ./cli/app/restore.go:126 +msgid "enable pre/post-hook command execution" +msgstr "" + +#: ./cli/app/restart.go:22 +msgid "re" +msgstr "" + +#: ./cli/app/labels.go:74 +msgid "RECIPE LABELS" +msgstr "" + +#: ./pkg/upstream/container/exec.go:43 +msgid "exec ID empty" +msgstr "" + +#: ./pkg/recipe/git.go:178 +#, c-format +msgid "successfully checked %s out to %s in %s" +msgstr "" + +#: ./pkg/git/init.go:38 +#, c-format +msgid "git add: %s" +msgstr "" + +#: ./cli/app/new.go:340 ./cli/app/new.go:347 ./cli/app/list.go:319 ./cli/app/list.go:326 ./cli/run.go:33 +msgid "server" +msgstr "" + +#: ./cli/app/app.go:11 +msgid "Manage apps" +msgstr "" + +#: ./pkg/secret/secret.go:119 +msgid "not generating app secrets, none enabled in recipe config" +msgstr "" + +#: ./pkg/upstream/convert/service.go:834 +#, c-format +msgid "invalid credential spec: spec specifies config %v, but no such config can be found" +msgstr "" + +#: ./cli/run.go:29 +msgid "autocomplete" +msgstr "" + +#: ./cli/app/run.go:113 +msgid "run command as user" +msgstr "" + +#: ./cli/app/volume.go:161 +msgid "which volumes do you want to remove?" +msgstr "" + +#: ./cli/updater/updater.go:231 +#, c-format +msgid "%s (%s) can be upgraded from version %s to %s" +msgstr "" + +#: ./cli/app/upgrade.go:208 ./cli/app/deploy.go:166 +#, c-format +msgid "%s missing from %s.env" +msgstr "" + +#: ./cli/app/list.go:222 +msgid "UPGRADE" +msgstr "" + +#: ./cli/app/list.go:223 +msgid "AUTOUPDATE" +msgstr "" + +#: ./cli/app/labels.go:25 +msgid "Show deployment labels" +msgstr "" + +#: ./cli/updater/updater.go:76 +msgid "Upgrade apps" +msgstr "" + +#: ./pkg/recipe/compose.go:249 +#, c-format +msgid "add '- \"%s\"' manually to the 'app' service in %s" +msgstr "" + +#: ./cli/app/secret.go:483 ./cli/app/secret.go:523 ./cli/app/backup.go:239 +msgid "all" +msgstr "" + +#: ./cli/app/backup.go:117 +#, c-format +msgid "including VOLUMES=%v in backupbot exec invocation" +msgstr "" + +#: ./cli/server/remove.go:17 +msgid "remove [flags]" +msgstr "" + +#: ./pkg/client/registry.go:20 +#, c-format +msgid "failed to parse image %s, saw: %s" +msgstr "" + +#: ./pkg/secret/pass.go:15 ./pkg/secret/pass.go:37 +msgid "pass command not found on $PATH, is it installed?" +msgstr "" + +#: ./pkg/git/read.go:45 +#, c-format +msgid "unable to query status of %s: %s" +msgstr "" + +#: ./cli/app/upgrade.go:269 ./cli/app/deploy.go:231 +#, c-format +msgid "attempting to run post deploy commands, saw: %s" +msgstr "" + +#: ./cli/app/rollback.go:26 +msgid "rl" +msgstr "" + +#: ./cli/app/cp.go:32 +msgid " # copy myfile.txt to the root of the app service\n" + " abra app cp 1312.net myfile.txt app:/\n" + "\n" + " # copy that file back to your current working directory locally\n" + " abra app cp 1312.net app:/myfile.txt ./" +msgstr "" + +#: ./cli/app/config.go:19 +msgid " abra config 1312.net" +msgstr "" + +#: ./cli/run.go:93 +msgid " # generate the man pages into /usr/local/share/man/man1\n" + " abra_path=$(which abra) # pass abra absolute path to sudo below\n" + " sudo $abra_path man\n" + " sudo mandb\n" + "\n" + " # read the man pages\n" + " man abra\n" + " man abra-app-deploy" +msgstr "" + +#: ./pkg/ssh/ssh.go:18 +#, c-format +msgid "could not resolve hostname for %s" +msgstr "" + +#: ./pkg/ui/deploy.go:333 +msgid "rolled back" +msgstr "" + +#: ./pkg/recipe/git.go:458 +#, c-format +msgid "collected %s for %s" +msgstr "" + +#: ./cli/app/secret.go:57 +msgid "cannot use '[secret] [version]' and '--all' together" +msgstr "" + +#: ./cli/app/cmd.go:196 ./cli/app/backup.go:15 ./cli/app/volume.go:19 +msgid "list [flags]" +msgstr "" + +#: ./cli/app/rollback.go:145 +#, c-format +msgid "choosing %s as version to rollback" +msgstr "" + +#: ./cli/server/add.go:23 +msgid "Add a new server" +msgstr "" + +#: ./cli/app/secret.go:106 ./cli/app/new.go:187 +msgid "VALUE" +msgstr "" + +#: ./cli/app/secret.go:500 ./cli/app/upgrade.go:435 ./cli/app/rollback.go:324 ./cli/app/deploy.go:335 ./cli/app/remove.go:156 ./cli/app/volume.go:199 +msgid "f" +msgstr "" + +#: ./cli/app/cmd.go:259 +msgid "request remote user" +msgstr "" + +#: ./cli/app/upgrade.go:285 +#, c-format +msgid "please select an upgrade (version: %s):" +msgstr "" + +#: ./cli/app/new.go:70 ./cli/app/deploy.go:262 +msgid "cannot use [version] and --chaos together" +msgstr "" + +#: ./cli/app/remove.go:116 +#, c-format +msgid "secret: %s removed" +msgstr "" + +#: ./cli/complete.go:12 +msgid "Generate autocompletion script" +msgstr "" + +#: ./pkg/recipe/recipe.go:368 +#, c-format +msgid "%s: end marker %s not found" +msgstr "" + +#: ./pkg/recipe/recipe.go:555 +#, c-format +msgid "fetching repo metadata from %s" +msgstr "" + +#: ./cli/app/secret.go:216 +#, c-format +msgid "reading secret from file: %s" +msgstr "" + +#: ./cli/app/secret.go:246 +#, c-format +msgid "deleted %s successfully from server" +msgstr "" + +#: ./cli/app/new.go:290 +msgid "Generate app secrets?" +msgstr "" + +#: ./pkg/upstream/convert/service.go:604 +msgid "test and disable can't be set at the same time" +msgstr "" + +#: ./pkg/recipe/recipe.go:201 +#, c-format +msgid "dirty: %v, " +msgstr "" + +#: ./cli/app/services.go:21 +msgid "services [flags]" +msgstr "" + +#: ./pkg/lint/recipe.go:148 +msgid "include \"deploy: labels: ...\" stanza" +msgstr "" + +#: ./pkg/lint/recipe.go:177 +msgid "replace lightweight tag with annotated tag" +msgstr "" + +#: ./pkg/upstream/container/hijack.go:172 +#, c-format +msgid "couldn't send EOF: %s" +msgstr "" + +#: ./pkg/git/clone.go:89 +#, c-format +msgid "git clone: %s already exists" +msgstr "" + +#: ./cli/app/restore.go:102 +msgid "target path" +msgstr "" + +#: ./cli/app/new.go:47 +msgid "new [recipe] [version] [flags]" +msgstr "" + +#: ./cli/app/new.go:49 +msgid "Create a new app" +msgstr "" + +#: ./cli/app/remove.go:59 +msgid "aborting as requested" +msgstr "" + +#: ./cli/app/volume.go:71 +#, c-format +msgid "no volumes created for %s" +msgstr "" + +#: ./cli/catalogue/catalogue.go:250 +msgid "publish changes to git.coopcloud.tech" +msgstr "" + +#: ./cli/run.go:92 +msgid "Generate manpage" +msgstr "" + +#: ./cli/server/prune.go:56 +msgid "removing all images, not only dangling ones" +msgstr "" + +#: ./cli/app/secret.go:143 +msgid "insert [flags]" +msgstr "" + +#: ./cli/app/undeploy.go:158 +msgid "prune unused containers, networks, and dangling images" +msgstr "" + +#: ./pkg/upstream/commandconn/commandconn.go:49 +#, c-format +msgid "commandconn: starting %s with %v" +msgstr "" + +#: ./cli/app/secret.go:263 +msgid "This command removes a secret from an app environment.\n" + "\n" + "Arbitrary secret removal is not supported. Secrets that are removed must\n" + "match those configured in the recipe beforehand." +msgstr "" + +#: ./cli/app/cmd.go:265 +msgid "T" +msgstr "" + +#: ./cli/app/check.go:20 +msgid "Compare env vars in both the app \".env\" and recipe \".env.sample\" file.\n" + "\n" + "The goal is to ensure that recipe \".env.sample\" env vars are defined in your\n" + "app \".env\" file. Only env var definitions in the \".env.sample\" which are\n" + "uncommented, e.g. \"FOO=bar\" are checked. If an app \".env\" file does not include\n" + "these env vars, then \"check\" will complain.\n" + "\n" + "Recipe maintainers may or may not provide defaults for env vars within their\n" + "recipes regardless of commenting or not (e.g. through the use of\n" + "${FOO:} syntax). \"check\" does not confirm or deny this for you." +msgstr "" + +#: ./cli/server/add.go:128 +#, c-format +msgid "serverAdd: cleanUp: cleaning up context for %s" +msgstr "" + +#: ./cli/app/undeploy.go:104 +msgid "undeploy succeeded 🟢" +msgstr "" + +#: ./cli/app/deploy.go:290 +#, c-format +msgid "version: taking chaos version: %s" +msgstr "" + +#: ./cli/app/deploy.go:311 +#, c-format +msgid "version: taking deployed version: %s" +msgstr "" + +#: ./cli/app/labels.go:23 +msgid "labels [flags]" +msgstr "" + +#: ./cli/updater/updater.go:35 +msgid "notify [flags]" +msgstr "" + +#: ./pkg/upstream/container/exec.go:113 +#, c-format +msgid "Error hijack: %s" +msgstr "" + +#: ./pkg/recipe/git.go:274 +#, c-format +msgid "unable to git pull in %s: %s" +msgstr "" + +#: ./pkg/git/diff.go:30 +msgid "unable to locate git command, cannot output diff" +msgstr "" + +#: ./cli/catalogue/catalogue.go:227 +msgid "dry run: no changes published" +msgstr "" + +#: ./cli/updater/updater.go:155 +#, c-format +msgid "no %s label found for %s" +msgstr "" + +#: ./pkg/lint/recipe.go:504 +msgid "invalid lightweight tag detected" +msgstr "" + +#: ./cli/app/secret.go:510 +msgid "trim input" +msgstr "" + +#: ./cli/app/restore.go:68 +#, c-format +msgid "including VOLUMES=%s in backupbot exec invocation" +msgstr "" + +#: ./cli/app/upgrade.go:362 +#, c-format +msgid "parsing deployed version failed: %s" +msgstr "" + +#: ./cli/app/cp.go:272 +msgid "can't copy dir to file" +msgstr "" + +#: ./pkg/upstream/convert/volume.go:113 +msgid "bind options are incompatible with type tmpfs" +msgstr "" + +#: ./pkg/recipe/compose.go:233 +#, c-format +msgid "%s is already set, nothing to do?" +msgstr "" + +#: ./cli/app/restart.go:132 +#, c-format +msgid "%s has been scaled to 0" +msgstr "" + +#: ./cli/app/remove.go:21 +msgid "Remove all app data, locally and remotely" +msgstr "" + +#: ./pkg/lint/recipe.go:203 +#, c-format +msgid "\n" + "lint %s: %s" +msgstr "" + +#: ./pkg/git/clone.go:100 +#, c-format +msgid "unable to clean up git clone of %s: %s" +msgstr "" + +#: ./cli/app/restore.go:52 ./cli/app/backup.go:44 ./cli/app/backup.go:102 +#, c-format +msgid "including SNAPSHOT=%s in backupbot exec invocation" +msgstr "" + +#: ./cli/app/new.go:211 +#, c-format +msgid "secrets are %s shown again, please save them %s" +msgstr "" + +#: ./pkg/dns/dns.go:38 ./pkg/dns/dns.go:47 +#, c-format +msgid "cannot resolve ipv4 for %s?" +msgstr "" + +#: ./pkg/recipe/git.go:156 +#, c-format +msgid "attempting to checkout '%s' as chaos commit" +msgstr "" + +#: ./pkg/recipe/recipe.go:147 +#, c-format +msgid "invalid recipe: %s" +msgstr "" + +#: ./cli/app/ps.go:30 +msgid "Check app deployment status" +msgstr "" + +#: ./cli/app/new.go:372 ./cli/app/logs.go:102 ./cli/app/backup.go:272 ./cli/app/list.go:289 +msgid "S" +msgstr "" + +#: ./cli/app/backup.go:180 +msgid "List all snapshots" +msgstr "" + +#: ./cli/server/add.go:163 +#, c-format +msgid "context for %s already exists" +msgstr "" + +#: ./cli/server/add.go:184 +#, c-format +msgid "server dir for %s already created" +msgstr "" + +#: ./pkg/lint/recipe.go:124 +msgid "long secret names" +msgstr "" + +#: ./pkg/catalogue/catalogue.go:59 ./pkg/recipe/git.go:245 +#, c-format +msgid "cannot ensure %s is up-to-date, no git remotes configured" +msgstr "" + +#: ./pkg/secret/secret.go:212 +#, c-format +msgid "attempting to generate and store %s on %s" +msgstr "" + +#: ./cli/app/deploy.go:96 +#, c-format +msgid "%s is already deployed" +msgstr "" + +#: ./cli/catalogue/catalogue.go:24 +msgid "generate [recipe] [flags]" +msgstr "" + +#: ./cli/server/add.go:114 +#, c-format +msgid "unable to resolve IPv4 for %s" +msgstr "" + +#: ./pkg/upstream/container/hijack.go:132 +msgid "[hijack] end of stdout" +msgstr "" + +#: ./pkg/ui/deploy.go:88 +#, c-format +msgid "status: %s, " +msgstr "" + +#: ./pkg/recipe/recipe.go:206 +#, c-format +msgid "readme: %s, " +msgstr "" + +#: ./pkg/git/read.go:52 +#, c-format +msgid "git status: %s: clean" +msgstr "" + +#: ./cli/app/labels.go:24 +msgid "lb" +msgstr "" + +#: ./cli/app/upgrade.go:240 ./cli/app/rollback.go:202 ./cli/app/deploy.go:203 +#, c-format +msgid "set waiting timeout to %d second(s)" +msgstr "" + +#: ./cli/app/cmd.go:46 +msgid "requires at least 2 arguments with --local/-l" +msgstr "" + +#: ./cli/app/secret.go:25 +msgid "g" +msgstr "" + +#: ./cli/app/secret.go:154 +msgid " # insert regular secret\n" + " abra app secret insert 1312.net my_secret v1 mySuperSecret\n" + "\n" + " # insert secret as file\n" + " abra app secret insert 1312.net my_secret v1 secret.txt -f" +msgstr "" + +#: ./cli/app/secret.go:443 ./cli/app/restore.go:108 ./cli/app/new.go:341 ./cli/app/logs.go:94 ./cli/app/backup.go:179 ./cli/app/backup.go:232 ./cli/app/backup.go:256 ./cli/app/list.go:320 +msgid "s" +msgstr "" + +#: ./cli/app/new.go:199 +#, c-format +msgid "%s created (version: %s)" +msgstr "" + +#: ./cli/server/add.go:146 +#, c-format +msgid "serverAdd: cleanUp: failed to remove %s: %s" +msgstr "" + +#: ./cli/server/server.go:10 +msgid "server [cmd] [args] [flags]" +msgstr "" + +#: ./pkg/upstream/convert/volume.go:93 +msgid "volume options are incompatible with type bind" +msgstr "" + +#: ./cli/catalogue/catalogue.go:235 +msgid "Manage the recipe catalogue" +msgstr "" + +#: ./cli/run.go:142 +msgid "prefer offline & filesystem access" +msgstr "" + +#: ./cli/server/server.go:12 +msgid "Manage servers" +msgstr "" + +#: ./pkg/service/service.go:61 ./pkg/service/service.go:115 +msgid "which service are you looking for?" +msgstr "" + +#: ./pkg/upstream/commandconn/commandconn.go:239 +#, c-format +msgid "commandConn.Close: CloseRead: %v" +msgstr "" + +#: ./pkg/upstream/convert/service.go:72 +#, c-format +msgid "secret not found: %s" +msgstr "" + +#: ./pkg/git/read.go:50 +#, c-format +msgid "git status: %s: %s" +msgstr "" + +#: ./pkg/git/push.go:40 +msgid "git tags pushed" +msgstr "" + +#: ./cli/app/undeploy.go:22 +msgid "undeploy [flags]" +msgstr "" + +#: ./cli/app/new.go:371 ./cli/app/backup.go:271 +msgid "secrets" +msgstr "" + +#: ./cli/app/backup.go:67 +msgid "Download a snapshot" +msgstr "" + +#: ./cli/run.go:30 +msgid "catalogue" +msgstr "" + +#: ./cli/app/secret.go:362 +#, c-format +msgid "%s doesn't exist on server?" +msgstr "" + +#: ./cli/app/cmd.go:23 +msgid "cmd" +msgstr "" + +#: ./cli/app/rollback.go:142 +msgid "unknown deployed version, unable to downgrade" +msgstr "" + +#: ./cli/app/config.go:42 +msgid "which editor do you wish to use?" +msgstr "" + +#: ./cli/updater/updater.go:74 +msgid "upgrade [[stack] [recipe] | --all] [flags]" +msgstr "" + +#: ./pkg/service/service.go:57 ./pkg/service/service.go:111 +msgid "ambiguous service list received, prompting for input" +msgstr "" + +#: ./pkg/upstream/convert/volume.go:133 +msgid "volume options are incompatible with type npipe" +msgstr "" + +#: ./cli/app/secret.go:502 +msgid "treat input as a file" +msgstr "" + +#: ./cli/app/restart.go:133 +#, c-format +msgid "attempting to scale %s to 1" +msgstr "" + +#: ./cli/app/cp.go:29 +msgid "cp [flags]" +msgstr "" + +#: ./pkg/git/init.go:34 +#, c-format +msgid "git worktree: %s" +msgstr "" + +#: ./pkg/container/container.go:31 +#, c-format +msgid "no containers matching the %v filter found?" +msgstr "" + +#: ./cli/app/restore.go:116 ./cli/app/backup.go:280 +msgid "v" +msgstr "" + +#: ./cli/app/new.go:284 +#, c-format +msgid "%s has no secrets to generate, skipping..." +msgstr "" + +#: ./pkg/lint/recipe.go:481 +#, c-format +msgid "secret %s is longer than 12 characters" +msgstr "" + +#: ./pkg/upstream/commandconn/commandconn.go:263 +#, c-format +msgid "unimplemented call: SetWriteDeadline(%v)" +msgstr "" + +#: ./pkg/upstream/convert/volume.go:130 +msgid "invalid npipe source, source cannot be empty" +msgstr "" + +#: ./pkg/git/init.go:17 +#, c-format +msgid "git init: %s" +msgstr "" + +#: ./cli/app/rollback.go:27 +msgid "Roll an app back to a previous version" +msgstr "" + +#: ./cli/app/check.go:18 +msgid "chk" +msgstr "" + +#: ./cli/app/cp.go:108 +#, c-format +msgid "local %s " +msgstr "" + +#: ./pkg/upstream/container/tty.go:66 +msgid "failed to resize tty, using default size" +msgstr "" + +#: ./pkg/ui/deploy.go:83 +#, c-format +msgid "err: %v, " +msgstr "" + +#: ./pkg/recipe/compose.go:153 +#, c-format +msgid "unable to parse %s, skipping" +msgstr "" + +#: ./cli/app/secret.go:394 +msgid "GENERATED NAME" +msgstr "" + +#: ./cli/app/upgrade.go:461 +msgid "only show release notes" +msgstr "" + +#: ./cli/app/rollback.go:25 +msgid "rollback [version] [flags]" +msgstr "" + +#: ./cli/app/deploy.go:30 +msgid "Deploy an app" +msgstr "" + +#: ./cli/updater/updater.go:299 +#, c-format +msgid "available updates for %s: %s" +msgstr "" + +#: ./pkg/lint/recipe.go:155 +msgid "include \"traefik.enable=true\" deploy label" +msgstr "" + +#: ./pkg/lint/recipe.go:261 ./pkg/recipe/files.go:17 +#, c-format +msgid "unable to discover .env.sample for %s" +msgstr "" + +#: ./pkg/ui/deploy.go:121 +#, c-format +msgid "^%s" +msgstr "" + +#: ./cli/app/secret.go:146 +msgid "This command inserts a secret into an app environment.\n" + "\n" + "Arbitrary secret insertion is not supported. Secrets that are inserted must\n" + "match those configured in the recipe beforehand.\n" + "\n" + "This can be useful when you want to manually generate secrets for an app\n" + "environment. Typically, you can let Abra generate them for you on app creation\n" + "(see \"abra app new --secrets/-S\" for more)." +msgstr "" + +#: ./cli/app/cmd.go:249 ./cli/app/logs.go:19 +msgid "l" +msgstr "" + +#: ./cli/app/restart.go:143 +#, c-format +msgid "%s has been scaled to 1" +msgstr "" + +#: ./cli/updater/updater.go:273 +#, c-format +msgid "no published releases for %s in the recipe catalogue?" +msgstr "" + +#: ./pkg/upstream/container/hijack.go:82 +#, c-format +msgid "unable to set IO streams as raw terminal: %s" +msgstr "" + +#: ./pkg/recipe/git.go:378 +#, c-format +msgid "git: opening repository in %s" +msgstr "" + +#: ./pkg/recipe/compose.go:171 ./pkg/recipe/compose.go:237 +#, c-format +msgid "updating %s to %s in %s" +msgstr "" + +#: ./pkg/formatter/formatter.go:80 +msgid "detected ABRA_CI=1" +msgstr "" + +#: ./cli/app/remove.go:136 ./cli/app/volume.go:179 +#, c-format +msgid "removing volumes failed: %s" +msgstr "" + +#: ./cli/app/logs.go:101 +msgid "since" +msgstr "" + +#: ./cli/app/backup.go:215 +msgid "Manage app backups" +msgstr "" + +#: ./cli/server/prune.go:18 +msgid "Prunes unused containers, networks, and dangling images.\n" + "\n" + "Use \"--volumes/-v\" to remove volumes that are not associated with a deployed\n" + "app. This can result in unwanted data loss if not used carefully." +msgstr "" + +#: ./pkg/upstream/container/hijack.go:100 +#, c-format +msgid "invalid detach escape keys, using default: %s" +msgstr "" + +#: ./pkg/recipe/git.go:50 +#, c-format +msgid "ensuring env version %s" +msgstr "" + +#: ./cli/app/run.go:110 ./cli/app/cmd.go:256 +msgid "user" +msgstr "" + +#: ./cli/app/config.go:18 +msgid "Edit app config" +msgstr "" + +#: ./cli/app/volume.go:77 +msgid "Remove volume(s) associated with an app" +msgstr "" + +#: ./cli/recipe/lint.go:15 +msgid "Lint a recipe" +msgstr "" + +#: ./cli/app/ps.go:180 ./cli/app/list.go:219 +msgid "STATUS" +msgstr "" + +#: ./cli/app/upgrade.go:392 ./cli/app/rollback.go:275 +#, c-format +msgid "'%s' is not a known version for %s" +msgstr "" + +#: ./cli/app/backup.go:298 +msgid "number of retry attempts" +msgstr "" + +#: ./cli/app/volume.go:47 +msgid "ON SERVER" +msgstr "" + +#: ./cli/app/secret.go:24 +msgid "generate [[secret] [version] | --all] [flags]" +msgstr "" + +#: ./cli/upgrade.go:19 +msgid "Upgrade abra in-place with the latest stable or release candidate.\n" + "\n" + "By default, the latest stable release is downloaded.\n" + "\n" + "Use \"--rc/-r\" to install the latest release candidate. Please bear in mind that\n" + "it may contain absolutely catastrophic deal-breaker bugs. Thank you very much\n" + "for the testing efforts 💗" +msgstr "" + +#: ./cli/server/add.go:57 +msgid "missing argument or --local/-l flag" +msgstr "" + +#: ./cli/app/secret.go:484 ./cli/app/secret.go:524 ./cli/app/restart.go:162 ./cli/app/app.go:10 ./cli/app/backup.go:240 +msgid "a" +msgstr "" + +#: ./cli/app/upgrade.go:32 +msgid "Upgrade an app.\n" + "\n" + "Unlike \"abra app deploy\", chaos operations are not supported here. Only recipe\n" + "versions are supported values for \"[version]\".\n" + "\n" + "It is possible to \"--force/-f\" an upgrade if you want to re-deploy a specific\n" + "version.\n" + "\n" + "Only the deployed version is consulted when trying to determine what upgrades\n" + "are available. The live deployment version is the \"source of truth\" in this\n" + "case. The stored .env version is not consulted.\n" + "\n" + "An upgrade can be destructive, please ensure you have a copy of your app data\n" + "beforehand. See \"abra app backup\" for more." +msgstr "" + +#: ./cli/app/upgrade.go:453 ./cli/app/rollback.go:342 ./cli/app/deploy.go:353 +msgid "disable converge logic checks" +msgstr "" + +#: ./cli/app/cp.go:197 +#, c-format +msgid "remote: %s does not exist" +msgstr "" + +#: ./cli/server/add.go:53 +msgid "cannot use [server] and --local together" +msgstr "" + +#: ./pkg/upstream/convert/volume.go:136 +msgid "tmpfs options are incompatible with type npipe" +msgstr "" + +#: ./pkg/ui/deploy.go:82 +#, c-format +msgid "{decoder: %v, " +msgstr "" + +#: ./pkg/dns/dns.go:14 +#, c-format +msgid "%s: unable to resolve IPv4 address: %s" +msgstr "" + +#: ./cli/app/ps.go:181 +msgid "IMAGE" +msgstr "" + +#: ./cli/app/run.go:24 +msgid " # run with args/flags\n" + " abra app run 1312.net app -- ls -lha\n" + "\n" + " # run without args/flags\n" + " abra app run 1312.net app bash --user nobody\n" + "\n" + " # run with both kinds of args/flags \n" + " abra app run 1312.net app --user nobody -- ls -lha" +msgstr "" + +#: ./cli/app/remove.go:50 +#, c-format +msgid "ALERTA ALERTA: deleting %s data and config (local/remote)" +msgstr "" + +#: ./pkg/service/service.go:95 +#, c-format +msgid "no services matching the %v filter found?" +msgstr "" + +#: ./pkg/ui/deploy.go:86 +#, c-format +msgid "reader: %v, " +msgstr "" + +#: ./cli/app/secret.go:507 +msgid "trim" +msgstr "" + +#: ./cli/app/deploy.go:31 +msgid "Deploy an app.\n" + "\n" + "This command supports chaos operations. Use \"--chaos/-C\" to deploy your recipe\n" + "checkout as-is. Recipe commit hashes are also supported as values for\n" + "\"[version]\". Please note, \"upgrade\"/\"rollback\" do not support chaos operations." +msgstr "" + +#: ./cli/app/deploy.go:107 +#, c-format +msgid "ensure recipe: %s" +msgstr "" + +#: ./cli/server/prune.go:93 +msgid "remove all unused images" +msgstr "" + +#: ./pkg/lint/recipe.go:76 +msgid "wire up healthchecks" +msgstr "" + +#: ./pkg/ui/deploy.go:84 +#, c-format +msgid "id: %s, " +msgstr "" + +#: ./cli/server/add.go:100 +#, c-format +msgid "unable to create local context: %s" +msgstr "" + +#: ./pkg/lint/recipe.go:82 +msgid "all images use a tag" +msgstr "" + +#: ./cli/app/secret.go:230 +#, c-format +msgid "%s successfully stored on server" +msgstr "" + +#: ./cli/app/secret.go:253 +#, c-format +msgid "deleted %s successfully from local pass store" +msgstr "" + +#: ./cli/app/list.go:216 +msgid "RECIPE" +msgstr "" + +#: ./cli/server/add.go:168 +#, c-format +msgid "creating context with domain %s" +msgstr "" + +#: ./pkg/recipe/git.go:160 +#, c-format +msgid "unable to resolve '%s': %s" +msgstr "" + +#: ./pkg/recipe/recipe.go:205 +#, c-format +msgid "compose: %s, " +msgstr "" + +#: ./cli/app/cmd.go:137 +#, c-format +msgid "%s does not exist locally, use /bin/sh as fallback" +msgstr "" + +#: ./cli/app/env.go:41 +msgid "ENV OVERVIEW" +msgstr "" + +#: ./cli/upgrade.go:26 +msgid " abra upgrade --rc" +msgstr "" + +#: ./pkg/lint/recipe.go:496 +#, c-format +msgid "unable to list local tags for %s" +msgstr "" + +#: ./pkg/recipe/git.go:410 +#, c-format +msgid "git checkout: %s in %s" +msgstr "" + +#: ./cli/app/cmd.go:131 ./cli/app/cmd.go:176 +msgid "did not detect any command arguments" +msgstr "" + +#: ./cli/app/rollback.go:120 +msgid "no available downgrades" +msgstr "" + +#: ./cli/app/restart.go:164 +msgid "restart all services" +msgstr "" + +#: ./cli/app/remove.go:139 +#, c-format +msgid "%d volume(s) removed successfully" +msgstr "" + +#: ./cli/app/backup.go:266 +msgid "volumes path" +msgstr "" + +#: ./cli/server/add.go:40 +msgid " abra server add 1312.net" +msgstr "" + +#: ./pkg/lint/recipe.go:110 +msgid "README.md metadata filled in" +msgstr "" + +#: ./pkg/git/clone.go:59 ./pkg/git/clone.go:78 ./pkg/git/clone.go:87 +#, c-format +msgid "git clone: %s cloned successfully" +msgstr "" + +#: ./cli/app/secret.go:106 ./cli/app/secret.go:394 ./cli/app/new.go:187 ./cli/app/volume.go:47 +msgid "NAME" +msgstr "" + +#: ./cli/app/secret.go:210 +#, c-format +msgid "no secret %s available for recipe %s?" +msgstr "" + +#: ./cli/app/cmd.go:101 +msgid "cannot use --local & --user together" +msgstr "" + +#: ./cli/app/cmd.go:119 +#, c-format +msgid "--local detected, running %s on local work station" +msgstr "" + +#: ./cli/app/upgrade.go:318 +#, c-format +msgid "parsing chosen upgrade version failed: %s" +msgstr "" + +#: ./cli/app/restart.go:161 +msgid "all-services" +msgstr "" + +#: ./cli/run.go:90 +msgid "man [flags]" +msgstr "" + +#: ./pkg/lint/recipe.go:162 +msgid "all services have images" +msgstr "" + +#: ./cli/catalogue/catalogue.go:266 +msgid "skip updating recipe repositories" +msgstr "" + +#: ./cli/run.go:49 +#, c-format +msgid "unable to create %s: %s" +msgstr "" + +#: ./pkg/recipe/compose.go:123 +#, c-format +msgid "considering %s config(s) for tag update" +msgstr "" + +#: ./pkg/recipe/recipe.go:203 +#, c-format +msgid "git url: %s, " +msgstr "" + +#: ./pkg/formatter/formatter.go:134 +msgid "CreateOverview: only accepts rows of len == 2" +msgstr "" + +#: ./cli/app/labels.go:27 +msgid " abra app labels 1312.net" +msgstr "" + +#: ./pkg/lint/recipe.go:118 +msgid "upload your recipe to git.coopcloud.tech/coop-cloud/..." +msgstr "" + +#: ./pkg/secret/secret.go:130 +#, c-format +msgid "%s not enabled in recipe config, skipping" +msgstr "" + +#: ./cli/app/run.go:21 +msgid "run [[args] [flags] | [flags] -- [args]]" +msgstr "" + +#: ./cli/app/cmd.go:168 +#, c-format +msgid "no service %s for %s?" +msgstr "" + +#: ./cli/app/upgrade.go:266 ./cli/app/deploy.go:229 +#, c-format +msgid "run the following post-deploy commands: %s" +msgstr "" + +#: ./cli/app/new.go:374 +msgid "automatically generate secrets" +msgstr "" + +#: ./pkg/upstream/commandconn/commandconn.go:65 +#, c-format +msgid "commandconn (%s):" +msgstr "" + +#: ./cli/app/secret.go:499 +msgid "file" +msgstr "" + +#: ./cli/app/undeploy.go:88 +msgid "initialising undeploy" +msgstr "" + +#: ./pkg/lint/recipe.go:132 ./pkg/lint/recipe.go:139 ./pkg/lint/recipe.go:146 ./pkg/lint/recipe.go:153 ./pkg/lint/recipe.go:161 ./pkg/lint/recipe.go:168 ./pkg/lint/recipe.go:175 +msgid "error" +msgstr "" + +#: ./pkg/recipe/recipe.go:435 +#, c-format +msgid "detected versions %s for %s" +msgstr "" + +#: ./cli/app/upgrade.go:434 ./cli/app/rollback.go:323 ./cli/app/deploy.go:334 ./cli/app/remove.go:155 ./cli/app/volume.go:198 +msgid "force" +msgstr "" + +#: ./cli/app/cp.go:273 +msgid "destination directory does not exist" +msgstr "" + +#: ./cli/app/backup.go:136 +msgid "Create a new snapshot" +msgstr "" + +#: ./cli/server/add.go:111 +#, c-format +msgid "%s successfully added" +msgstr "" + +#: ./pkg/lint/recipe.go:75 +msgid "healthcheck enabled for all services" +msgstr "" + +#: ./pkg/config/env.go:98 +#, c-format +msgid "directory is empty: %s" +msgstr "" + +#: ./pkg/config/abra.go:88 +msgid "using default abra dir" +msgstr "" + +#: ./pkg/recipe/files.go:36 +#, c-format +msgid "%s release notes:" +msgstr "" + +#: ./cli/app/new.go:24 +msgid "Creates a new app from a default recipe.\n" + "\n" + "This new app configuration is stored in your $ABRA_DIR directory under the\n" + "appropriate server.\n" + "\n" + "This command does not deploy your app for you. You will need to run \"abra app\n" + "deploy \" to do so.\n" + "\n" + "You can see what recipes are available (i.e. values for the [recipe] argument)\n" + "by running \"abra recipe ls\".\n" + "\n" + "Recipe commit hashes are supported values for \"[version]\".\n" + "\n" + "Passing the \"--secrets/-S\" flag will automatically generate secrets for your\n" + "app and store them encrypted at rest on the chosen target server. These\n" + "generated secrets are only visible at generation time, so please take care to\n" + "store them somewhere safe.\n" + "\n" + "You can use the \"--pass/-P\" to store these generated passwords locally in a\n" + "pass store (see passwordstore.org for more). The pass command must be available\n" + "on your $PATH." +msgstr "" + +#: ./cli/catalogue/catalogue.go:187 +#, c-format +msgid "no changes discovered in %s, nothing to publish?" +msgstr "" + +#: ./cli/server/add.go:202 +msgid "use local server" +msgstr "" + +#: ./pkg/recipe/git.go:398 +#, c-format +msgid "processing %s for %s" +msgstr "" + +#: ./pkg/recipe/recipe.go:202 +#, c-format +msgid "dir: %s, " +msgstr "" + +#: ./pkg/git/init.go:65 +#, c-format +msgid "repo config: %s" +msgstr "" + +#: ./pkg/git/push.go:13 +#, c-format +msgid "dry run: no git changes pushed in %s" +msgstr "" + +#: ./pkg/formatter/formatter.go:238 +#, c-format +msgid "stripped %s to %s for parsing" +msgstr "" + +#: ./cli/app/restart.go:29 +msgid " # restart a single app service\n" + " abra app restart 1312.net app\n" + "\n" + " # restart all app services\n" + " abra app restart 1312.net -a" +msgstr "" + +#: ./cli/app/deploy.go:36 +msgid " # standard deployment\n" + " abra app deploy 1312.net\n" + "\n" + " # chaos deployment\n" + " abra app deploy 1312.net --chaos\n" + " \n" + " # deploy specific version\n" + " abra app deploy 1312.net 2.0.0+1.2.3\n" + "\n" + " # deploy a specific git hash\n" + " abra app deploy 1312.net 886db76d" +msgstr "" + +#: ./cli/app/list.go:46 +msgid "Generate a report of all managed apps.\n" + "\n" + "Use \"--status/-S\" flag to query all servers for the live deployment status." +msgstr "" + +#: ./cli/app/list.go:148 +#, c-format +msgid "unable to clone %s: %s" +msgstr "" + +#: ./cli/catalogue/catalogue.go:234 +msgid "catalogue [cmd] [args] [flags]" +msgstr "" + +#: ./pkg/client/context.go:26 +#, c-format +msgid "created the %s context" +msgstr "" + +#: ./pkg/secret/pass.go:29 +#, c-format +msgid "%s inserted into pass store" +msgstr "" + +#: ./pkg/config/abra.go:26 +#, c-format +msgid "error reading config file: %s" +msgstr "" + +#: ./cli/app/upgrade.go:149 +msgid "unknown deployed version, unable to upgrade" +msgstr "" + +#: ./cli/app/backup.go:107 +#, c-format +msgid "including INCLUDE_PATH=%s in backupbot exec invocation" +msgstr "" + +#: ./cli/app/secret.go:526 +msgid "remove all secrets" +msgstr "" + +#: ./cli/catalogue/catalogue.go:175 +#, c-format +msgid "generated recipe catalogue: %s" +msgstr "" + +#: ./pkg/context/context.go:34 +msgid "context lacks Docker endpoint" +msgstr "" + +#: ./pkg/lint/recipe.go:163 +msgid "ensure \"image: ...\" set on all services" +msgstr "" + +#: ./pkg/recipe/compose.go:38 +#, c-format +msgid "COMPOSE_FILE detected, loading %s" +msgstr "" + +#: ./pkg/recipe/recipe.go:406 +#, c-format +msgid "read recipe catalogue from file system cache in %s" +msgstr "" + +#: ./cli/app/new.go:275 +msgid "no domain provided" +msgstr "" + +#: ./cli/app/secret.go:442 +msgid "secret [cmd] [args] [flags]" +msgstr "" + +#: ./cli/updater/updater.go:197 +#, c-format +msgid "can't separate key from value: %s (this variable is probably unset)" +msgstr "" + +#: ./pkg/lint/recipe.go:55 +#, c-format +msgid "skipping %s based on skip condition" +msgstr "" + +#: ./pkg/recipe/compose.go:59 +#, c-format +msgid "retrieved %s configs for %s" +msgstr "" + +#: ./pkg/git/commit.go:14 +msgid "no commit message specified?" +msgstr "" + +#: ./cli/app/cp.go:117 ./cli/app/cp.go:199 ./cli/app/cp.go:210 +#, c-format +msgid "remote path: %s" +msgstr "" + +#: ./pkg/lint/recipe.go:89 +msgid "no unstable tags" +msgstr "" + +#: ./pkg/lint/recipe.go:133 +msgid ".env.sample provided" +msgstr "" + +#: ./pkg/catalogue/catalogue.go:21 +msgid "catalogue is missing, retrieving now" +msgstr "" + +#: ./pkg/secret/secret.go:139 +#, c-format +msgid "secret %s is > %d chars when combined with %s" +msgstr "" + +#: ./pkg/recipe/recipe.go:175 +#, c-format +msgid "failed to check git status of %s: %s" +msgstr "" + +#: ./pkg/git/init.go:47 +#, c-format +msgid "git commit: %s" +msgstr "" + +#: ./cli/run.go:74 +#, c-format +msgid "unsupported --lang: %s (want: es)" +msgstr "" + +#: ./pkg/git/init.go:60 +#, c-format +msgid "set reference: %s" +msgstr "" + +#: ./cli/app/ps.go:56 ./cli/app/upgrade.go:423 ./cli/app/undeploy.go:59 ./cli/app/services.go:49 ./cli/app/restart.go:93 ./cli/app/logs.go:58 ./cli/updater/updater.go:247 +#, c-format +msgid "%s is not deployed?" +msgstr "" + +#: ./cli/app/volume.go:153 +#, c-format +msgid "volume %s removed successfully" +msgstr "" + +#: ./pkg/lint/recipe.go:212 +#, c-format +msgid "recipe '%s' failed lint checks:\n" + "%s" +msgstr "" + +#: ./pkg/recipe/compose.go:29 +#, c-format +msgid "no COMPOSE_FILE detected, loading default: %s" +msgstr "" + +#: ./pkg/container/container.go:48 +msgid "ambiguous container list received, prompting for input" +msgstr "" + +#: ./cli/app/upgrade.go:274 ./cli/app/undeploy.go:107 ./cli/app/new.go:224 ./cli/app/rollback.go:227 ./cli/app/deploy.go:236 +#, c-format +msgid "writing recipe version failed: %s" +msgstr "" + +#: ./cli/app/rollback.go:270 +#, c-format +msgid "current deployment '%s' is not a known version for %s" +msgstr "" + +#: ./pkg/service/service.go:103 ./pkg/container/container.go:40 +#, c-format +msgid "%s (created %v)" +msgstr "" + +#: ./cli/app/cmd.go:24 +msgid "Run app commands" +msgstr "" + +#: ./cli/app/cmd.go:171 +#, c-format +msgid "running command %s within the context of %s_%s" +msgstr "" + +#: ./cli/app/volume.go:192 +msgid "Manage app volumes" +msgstr "" + +#: ./cli/app/list.go:45 +msgid "List all managed apps" +msgstr "" + +#: ./cli/updater/updater.go:224 +#, c-format +msgid "no available upgrades for %s" +msgstr "" + +#: ./pkg/git/init.go:50 +#, c-format +msgid "init committed all files for new git repo in %s" +msgstr "" + +#: ./cli/app/new.go:366 +msgid "store secrets in a local pass store" +msgstr "" + +#: ./cli/app/rollback.go:280 ./cli/app/rollback.go:284 +#, c-format +msgid "%s is not a downgrade for %s?" +msgstr "" + +#: ./cli/server/remove.go:20 +msgid "Remove a managed server.\n" + "\n" + "Abra will remove the internal bookkeeping ($ABRA_DIR/servers/...) and\n" + "underlying client connection context. This server will then be lost in time,\n" + "like tears in rain." +msgstr "" + +#: ./pkg/recipe/git.go:241 +#, c-format +msgid "unable to read remotes in %s: %s" +msgstr "" + +#: ./pkg/recipe/recipe.go:549 +msgid "collecting recipe listing" +msgstr "" + +#: ./cli/app/backup.go:274 +msgid "include secrets" +msgstr "" + +#: ./cli/run.go:34 +msgid "upgrade" +msgstr "" + +#: ./cli/updater/updater.go:37 +msgid "Check for available upgrades" +msgstr "" + +#: ./cli/app/secret.go:467 ./cli/app/secret.go:491 ./cli/app/secret.go:531 ./cli/app/new.go:363 +msgid "pass" +msgstr "" + +#: ./cli/app/rollback.go:42 +msgid " # standard rollback\n" + " abra app rollback 1312.net\n" + "\n" + " # rollback to specific version\n" + " abra app rollback 1312.net 2.0.0+1.2.3" +msgstr "" + +#: ./cli/app/remove.go:53 +msgid "are you sure?" +msgstr "" + +#: ./cli/app/backup.go:134 +msgid "create [flags]" +msgstr "" + +#: ./pkg/upstream/convert/service.go:375 +#, c-format +msgid "undefined network %q" +msgstr "" + +#: ./pkg/git/add.go:22 +#, c-format +msgid "dry run: adding %s" +msgstr "" + +#: ./cli/run.go:159 +msgid "force select language (supported: XXX)" +msgstr "" + +#: ./cli/updater/updater.go:77 +msgid "Upgrade an app by specifying stack name and recipe. \n" + "\n" + "Use \"--all\" to upgrade every deployed app.\n" + "\n" + "For each app with auto updates enabled, the deployed version is compared with\n" + "the current recipe catalogue version. If a new patch/minor version is\n" + "available, the app is upgraded.\n" + "\n" + "To include major versions use the \"--major/-m\" flag. You probably don't want\n" + "that as it will break things. Only apps that are not deployed with \"--chaos/-C\"\n" + "are upgraded, to update chaos deployments use the \"--chaos/-C\" flag. Use it\n" + "with care." +msgstr "" + +#: ./pkg/upstream/convert/service.go:43 +#, c-format +msgid "duplicate secret target for %s not allowed" +msgstr "" + +#: ./pkg/git/clone.go:68 +msgid "git clone: main branch failed, attempting master branch" +msgstr "" + +#: ./cli/app/upgrade.go:29 +msgid "upgrade [version] [flags]" +msgstr "" + +#: ./cli/app/remove.go:89 +#, c-format +msgid "removing configs failed: %s" +msgstr "" + +#: ./cli/run.go:150 +msgid "ignore .env version checkout" +msgstr "" + +#: ./pkg/git/clone.go:49 +#, c-format +msgid "git clone: %s" +msgstr "" + +#: ./cli/server/remove.go:19 +msgid "Remove a managed server" +msgstr "" + +#: ./pkg/upstream/container/hijack.go:43 +#, c-format +msgid "unable to setup input stream: %s" +msgstr "" + +#: ./pkg/recipe/compose.go:191 +#, c-format +msgid "considering %s config(s) for label update" +msgstr "" + +#: ./pkg/container/container.go:52 +msgid "which container are you looking for?" +msgstr "" + +#: ./cli/app/secret.go:460 ./cli/app/secret.go:556 ./cli/app/ps.go:199 ./cli/app/list.go:312 +msgid "m" +msgstr "" + +#: ./cli/app/run.go:23 +msgid "Run a command inside a service container" +msgstr "" + +#: ./cli/app/run.go:102 +msgid "no-tty" +msgstr "" + +#: ./cli/app/remove.go:119 +msgid "no secrets to remove" +msgstr "" + +#: ./cli/server/add.go:86 +msgid "local server already exists" +msgstr "" + +#: ./pkg/lint/recipe.go:134 +msgid "create an example .env.sample" +msgstr "" + +#: ./cli/app/secret.go:444 +msgid "Manage app secrets" +msgstr "" + +#: ./cli/app/services.go:22 +msgid "sr" +msgstr "" + +#: ./cli/app/backup.go:178 +msgid "snapshots [flags]" +msgstr "" + +#: ./cli/server/add.go:76 ./cli/server/add.go:103 +#, c-format +msgid "attempting to create client for %s" +msgstr "" + +#: ./pkg/client/configs.go:35 +#, c-format +msgid "conf %s: %s" +msgstr "" + +#: ./pkg/recipe/recipe.go:130 +#, c-format +msgid "version seems invalid: %s" +msgstr "" + +#: ./pkg/web/web.go:45 +#, c-format +msgid "bad status: %s" +msgstr "" + +#: ./cli/run.go:109 +#, c-format +msgid "unable to proceed, %s does not exist?" +msgstr "" + +#: ./cli/app/restore.go:99 +msgid "target" +msgstr "" + +#: ./cli/app/remove.go:92 +#, c-format +msgid "%d config(s) removed successfully" +msgstr "" + +#: ./cli/server/remove.go:43 +#, c-format +msgid "%s is now lost in time, like tears in rain" +msgstr "" + +#: ./cli/recipe/lint.go:14 +msgid "lint [flags]" +msgstr "" + +#: ./pkg/recipe/compose.go:243 +#, c-format +msgid "synced label %s to service %s" +msgstr "" + +#: ./cli/app/cmd.go:51 +msgid "accepts at most 2 args with --local/-l" +msgstr "" + +#: ./cli/app/cmd.go:198 +msgid "List all available commands" +msgstr "" + +#: ./cli/catalogue/catalogue.go:223 +#, c-format +msgid "new changes published: %s" +msgstr "" + +#: ./cli/updater/updater.go:251 +#, c-format +msgid "failed to determine deployed version of %s" +msgstr "" + +#: ./pkg/client/volumes.go:63 +#, c-format +msgid "%d retries failed" +msgstr "" + +#: ./pkg/lint/recipe.go:140 +msgid "one service named 'app'" +msgstr "" + +#: ./pkg/envfile/envfile.go:82 +#, c-format +msgid "read 0 env var exports from %s" +msgstr "" + +#: ./pkg/config/abra.go:77 +msgid "read abra dir from $ABRA_DIR" +msgstr "" + +#: ./cli/app/secret.go:38 ./cli/app/secret.go:170 ./cli/app/secret.go:280 ./cli/app/upgrade.go:58 ./cli/app/rollback.go:58 ./cli/app/deploy.go:59 ./cli/app/logs.go:32 ./pkg/autocomplete/autocomplete.go:17 ./pkg/autocomplete/autocomplete.go:32 ./pkg/autocomplete/autocomplete.go:43 ./pkg/autocomplete/autocomplete.go:59 ./pkg/autocomplete/autocomplete.go:77 ./pkg/autocomplete/autocomplete.go:93 ./pkg/autocomplete/autocomplete.go:99 ./pkg/autocomplete/autocomplete.go:114 +#, c-format +msgid "autocomplete failed: %s" +msgstr "" + +#: ./cli/app/secret.go:136 +msgid "NOT" +msgstr "" + +#: ./cli/app/secret.go:437 +#, c-format +msgid "no secrets stored for %s" +msgstr "" + +#: ./cli/app/cmd.go:267 +msgid "disable remote TTY" +msgstr "" + +#: ./cli/app/new.go:207 +msgid "SECRETS OVERVIEW" +msgstr "" + +#: ./cli/app/logs.go:93 +msgid "stderr" +msgstr "" + +#: ./cli/server/add.go:21 +msgid "add [[server] | --local] [flags]" +msgstr "" + +#: ./pkg/lint/recipe.go:117 +msgid "git.coopcloud.tech repo exists" +msgstr "" + +#: ./cli/app/volume.go:191 +msgid "vl" +msgstr "" + +#: ./pkg/client/volumes.go:59 +#, c-format +msgid "%s: waiting %d seconds before next retry" +msgstr "" + +#: ./pkg/service/service.go:30 +msgid "no services deployed?" +msgstr "" + +#: ./pkg/lint/recipe.go:125 +msgid "reduce length of secret names to 12 chars" +msgstr "" + +#: ./pkg/lint/recipe.go:215 +#, c-format +msgid "linting successful, %s is well configured" +msgstr "" + +#: ./pkg/upstream/convert/service.go:122 +#, c-format +msgid "duplicate config target for %s not allowed" +msgstr "" + +#: ./pkg/upstream/convert/volume.go:44 +msgid "tmpfs options are incompatible with type volume" +msgstr "" + +#: ./pkg/config/env.go:37 +#, c-format +msgid "retrieved %v servers: %s" +msgstr "" + +#: ./cli/app/restart.go:23 +msgid "Restart an app" +msgstr "" + +#: ./cli/app/restart.go:64 +msgid "missing [service]" +msgstr "" + +#: ./cli/app/secret.go:75 +#, c-format +msgid "%s doesn't exist in the env config?" +msgstr "" + +#: ./cli/app/upgrade.go:31 +msgid "Upgrade an app" +msgstr "" + +#: ./cli/app/undeploy.go:135 ./cli/server/prune.go:52 +#, c-format +msgid "networks pruned: %d" +msgstr "" + +#: ./cli/updater/updater.go:239 +#, c-format +msgid "retrieve deployed version whether %s is already deployed" +msgstr "" + +#: ./pkg/recipe/git.go:191 +#, c-format +msgid "%s (%s) has locally unstaged changes?" +msgstr "" + +#: ./pkg/recipe/recipe.go:138 +#, c-format +msgid "removed dirty suffix from .env version: %s -> %s" +msgstr "" + +#: ./cli/app/ps.go:165 +#, c-format +msgid "unable to convert to JSON: %s" +msgstr "" + +#: ./cli/app/upgrade.go:437 ./cli/app/rollback.go:326 ./cli/app/deploy.go:337 ./cli/app/remove.go:158 ./cli/app/volume.go:201 +msgid "perform action without further prompt" +msgstr "" + +#: ./cli/app/upgrade.go:451 ./cli/app/rollback.go:340 ./cli/app/deploy.go:351 ./cli/app/cp.go:30 ./cli/app/backup.go:135 +msgid "c" +msgstr "" + +#: ./cli/app/restart.go:21 +msgid "restart [[service] | --all-services] [flags]" +msgstr "" + +#: ./pkg/lint/recipe.go:21 ./pkg/lint/recipe.go:67 ./pkg/lint/recipe.go:74 ./pkg/lint/recipe.go:81 ./pkg/lint/recipe.go:88 ./pkg/lint/recipe.go:95 ./pkg/lint/recipe.go:102 ./pkg/lint/recipe.go:109 ./pkg/lint/recipe.go:116 ./pkg/lint/recipe.go:123 +msgid "warn" +msgstr "" + +#: ./pkg/config/abra.go:20 +msgid "no config file found" +msgstr "" + +#: ./pkg/git/branch.go:99 +#, c-format +msgid "successfully checked out %v in %s" +msgstr "" + +#: ./cli/app/upgrade.go:415 ./cli/app/undeploy.go:51 ./cli/app/deploy.go:88 +#, c-format +msgid "checking whether %s is already deployed" +msgstr "" + +#: ./cli/app/restart.go:144 +#, c-format +msgid "%s service successfully restarted" +msgstr "" + +#: ./cli/app/config.go:16 +msgid "config [flags]" +msgstr "" + +#: ./cli/app/backup.go:54 +#, c-format +msgid "including TIMESTAMPS=%v in backupbot exec invocation" +msgstr "" + +#: ./pkg/lint/recipe.go:170 +msgid "vendor config versions in an abra.sh" +msgstr "" + +#: ./pkg/upstream/convert/service.go:153 ./pkg/upstream/convert/service.go:168 +#, c-format +msgid "config not found: %s" +msgstr "" + +#: ./pkg/ui/deploy.go:85 +#, c-format +msgid "name: %s, " +msgstr "" + +#: ./pkg/recipe/recipe.go:325 +#, c-format +msgid "%s: image meta has incorrect format: %s" +msgstr "" + +#: ./cli/app/secret.go:470 ./cli/app/secret.go:494 +msgid "store generated secrets in a local pass store" +msgstr "" + +#: ./cli/app/secret.go:534 +msgid "remove generated secrets from a local pass store" +msgstr "" + +#: ./cli/app/backup.go:231 ./cli/app/backup.go:255 +msgid "snapshot" +msgstr "" + +#: ./cli/updater/updater.go:176 +#, c-format +msgid "boolean label %s could not be found for %s, set default to false." +msgstr "" + +#: ./pkg/catalogue/catalogue.go:84 ./pkg/recipe/git.go:278 +#, c-format +msgid "fetched latest git changes for %s" +msgstr "" + +#: ./pkg/upstream/convert/volume.go:162 +msgid "volume type must be volume, bind, tmpfs or npipe" +msgstr "" + +#: ./pkg/recipe/compose.go:47 +#, c-format +msgid "COMPOSE_FILE (=\"%s\") parsing failed?" +msgstr "" + +#: ./pkg/git/branch.go:68 +#, c-format +msgid "failed to select default branch in %s" +msgstr "" + +#: ./cli/app/ps.go:183 ./cli/app/list.go:220 +msgid "CHAOS" +msgstr "" + +#: ./cli/app/new.go:48 +msgid "n" +msgstr "" + +#: ./cli/app/backup.go:282 +msgid "include volumes" +msgstr "" + +#: ./cli/app/list.go:49 +msgid " # list apps of all servers without live status\n" + " abra app ls\n" + "\n" + " # list apps of a specific server with live status\n" + " abra app ls -s 1312.net -S\n" + "\n" + " # list apps of all servers which match a specific recipe\n" + " abra app ls -r gitea" +msgstr "" + +#: ./cli/complete.go:11 +msgid "autocomplete [bash|zsh|fish|powershell]" +msgstr "" + +#: ./pkg/client/client.go:100 +msgid "swarm mode not enabled on local server?" +msgstr "" + +#: ./pkg/logs/logs.go:86 +#, c-format +msgid "tailLogs: unable to copy buffer: %s" +msgstr "" + +#: ./pkg/config/abra.go:37 +#, c-format +msgid "config file loaded from: %s" +msgstr "" + +#: ./cli/app/secret.go:307 +msgid "cannot use [secret] and --all/-a together" +msgstr "" + +#: ./cli/app/secret.go:508 ./cli/app/restore.go:100 ./cli/app/run.go:103 ./cli/app/backup.go:248 +msgid "t" +msgstr "" + +#: ./cli/app/backup.go:112 +#, c-format +msgid "including SECRETS=%v in backupbot exec invocation" +msgstr "" + +#: ./cli/updater/updater.go:38 +msgid "Notify on new versions for deployed apps.\n" + "\n" + "If a new patch/minor version is available, a notification is printed.\n" + "\n" + "Use \"--major/-m\" to include new major versions." +msgstr "" + +#: ./pkg/upstream/convert/volume.go:96 +msgid "tmpfs options are incompatible with type bind" +msgstr "" + +#: ./pkg/git/commit.go:42 +msgid "git changes commited" +msgstr "" + +#: ./cli/app/run.go:111 ./cli/app/cmd.go:257 +msgid "u" +msgstr "" + +#: ./cli/app/undeploy.go:24 +msgid "Undeploy an app" +msgstr "" + +#: ./cli/app/list.go:216 +msgid "SERVER" +msgstr "" + +#: ./pkg/client/client.go:97 +#, c-format +msgid "swarm mode not enabled on %s?" +msgstr "" + +#: ./cli/app/secret.go:486 +msgid "generate all secrets" +msgstr "" + +#: ./cli/app/deploy.go:180 +msgid "skipping domain checks" +msgstr "" + +#: ./cli/app/config.go:17 +msgid "cfg" +msgstr "" + +#: ./cli/server/prune.go:15 +msgid "prune [flags]" +msgstr "" + +#: ./pkg/recipe/compose.go:107 +#, c-format +msgid "%s has no version label? try running \"abra recipe sync %s\" first?" +msgstr "" + +#: ./cli/app/cmd.go:128 ./cli/app/cmd.go:174 +#, c-format +msgid "parsed following command arguments: %s" +msgstr "" + +#: ./cli/app/upgrade.go:450 ./cli/app/rollback.go:339 ./cli/app/deploy.go:350 +msgid "no-converge-checks" +msgstr "" + +#: ./pkg/lint/recipe.go:169 +msgid "config version are vendored" +msgstr "" + +#: ./pkg/ui/deploy.go:330 +msgid "succeeded" +msgstr "" + +#: ./pkg/git/read.go:149 +#, c-format +msgid "read global ignore paths: %s" +msgstr "" + +#: ./cli/app/secret.go:372 +msgid "list " +msgstr "" + +#: ./cli/app/undeploy.go:25 +msgid "This does not destroy any application data.\n" + "\n" + "However, you should remain vigilant, as your swarm installation will consider\n" + "any previously attached volumes as eligible for pruning once undeployed.\n" + "\n" + "Passing \"--prune/-p\" does not remove those volumes." +msgstr "" + +#: ./cli/app/new.go:236 +#, c-format +msgid "trimming %s to %s to avoid runtime limits" +msgstr "" + +#: ./cli/app/env.go:16 +msgid "e" +msgstr "" + +#: ./cli/app/backup.go:213 +msgid "backup [cmd] [args] [flags]" +msgstr "" + +#: ./pkg/secret/secret.go:62 ./pkg/secret/secret.go:80 +#, c-format +msgid "generated %s" +msgstr "" + +#: ./pkg/upstream/commandconn/commandconn.go:172 +#, c-format +msgid "command %v has exited with %v, please make sure the URL is valid, and Docker 18.09 or later is installed on the remote host: stderr=%s" +msgstr "" + +#: ./pkg/git/read.go:130 +#, c-format +msgid "no %s exists, skipping reading gitignore paths" +msgstr "" + +#: ./cli/app/secret.go:26 +msgid "Generate secrets" +msgstr "" + +#: ./cli/app/restore.go:17 +msgid "rs" +msgstr "" + +#: ./cli/run.go:117 +msgid "don't forget to run 'sudo mandb'" +msgstr "" + +#: ./pkg/service/service.go:77 ./pkg/service/service.go:131 +msgid "failed to match chosen service" +msgstr "" + +#: ./pkg/recipe/recipe.go:237 +#, c-format +msgid "%s: attempt recipe metadata parse" +msgstr "" + +#: ./cli/app/restore.go:124 +msgid "H" +msgstr "" + +#: ./cli/app/cmd.go:25 +msgid "Run an app specific command.\n" + "\n" + "These commands are bash functions, defined in the abra.sh of the recipe itself.\n" + "They can be run within the context of a service (e.g. app) or locally on your\n" + "work station by passing \"--local/-l\".\n" + "\n" + "N.B. If using the \"--\" style to pass arguments, flags (e.g. \"--local/-l\") must\n" + "be passed *before* the \"--\". It is possible to pass arguments without the \"--\"\n" + "as long as no dashes are present (i.e. \"foo\" works without \"--\", \"-foo\"\n" + "does not)." +msgstr "" + +#: ./cli/app/upgrade.go:402 ./cli/app/upgrade.go:406 +#, c-format +msgid "%s is not an upgrade for %s?" +msgstr "" + +#: ./cli/app/env.go:17 +msgid "Show app .env values" +msgstr "" + +#: ./cli/app/remove.go:22 +msgid "Remove everything related to an app which is already undeployed.\n" + "\n" + "By default, it will prompt for confirmation before proceeding. All secrets,\n" + "volumes and the local app env file will be deleted.\n" + "\n" + "Only run this command when you are sure you want to completely remove the app\n" + "and all associated app data. This is a destructive action, Be Careful!\n" + "\n" + "If you would like to delete specific volumes or secrets, please use removal\n" + "sub-commands under \"app volume\" and \"app secret\" instead.\n" + "\n" + "Please note, if you delete the local app env file without removing volumes and\n" + "secrets first, Abra will *not* be able to help you remove them afterwards.\n" + "\n" + "To delete everything without prompt, use the \"--force/-f\" or the \"--no-input/n\"\n" + "flag." +msgstr "" + +#: ./cli/updater/updater.go:202 +#, c-format +msgid "for %s read env %s with value: %s from docker service" +msgstr "" + +#: ./pkg/lint/recipe.go:491 ./pkg/recipe/git.go:236 ./pkg/git/read.go:26 +#, c-format +msgid "unable to open %s: %s" +msgstr "" + +#: ./pkg/git/remote.go:15 +#, c-format +msgid "dry run: remote %s (%s) not created" +msgstr "" + +#: ./cli/app/ps.go:119 ./cli/app/ps.go:120 ./cli/app/ps.go:121 ./cli/app/ps.go:122 ./cli/app/ps.go:123 ./cli/app/list.go:111 ./cli/app/list.go:112 ./cli/app/list.go:113 ./cli/app/list.go:114 ./cli/app/list.go:115 ./cli/app/list.go:175 ./cli/app/labels.go:71 +msgid "unknown" +msgstr "" + +#: ./cli/app/services.go:23 +msgid "Display all services of an app" +msgstr "" + +#: ./cli/app/cp.go:31 +msgid "Copy files to/from a deployed app service" +msgstr "" + +#: ./pkg/recipe/compose.go:72 +#, c-format +msgid "%s is missing a compose.yml or compose.*.yml file?" +msgstr "" + +#: ./cli/server/add.go:120 ./pkg/secret/secret.go:223 ./pkg/secret/secret.go:243 ./pkg/server/server.go:21 +#, c-format +msgid "%s already exists" +msgstr "" + +#: ./cli/app/restore.go:62 +#, c-format +msgid "including NONINTERACTIVE=%v in backupbot exec invocation" +msgstr "" + +#: ./cli/app/restore.go:107 +msgid "services" +msgstr "" + +#: ./cli/app/restore.go:16 +msgid "restore [flags]" +msgstr "" + +#: ./cli/app/backup.go:214 +msgid "b" +msgstr "" + +#: ./pkg/service/service.go:53 ./pkg/service/service.go:107 +#, c-format +msgid "expected 1 service but found %v: %s" +msgstr "" + +#: ./pkg/lint/recipe.go:69 +msgid "ensure 'version: \"3.8\"' in compose configs" +msgstr "" + +#: ./pkg/ssh/ssh.go:24 +#, c-format +msgid "unable to connect to %s, please check your SSH config" +msgstr "" + +#: ./cli/app/restore.go:79 +#, c-format +msgid "including NO_COMMANDS=%v in backupbot exec invocation" +msgstr "" + +#: ./cli/app/undeploy.go:23 +msgid "un" +msgstr "" + +#: ./cli/app/rollback.go:243 +#, c-format +msgid "please select a downgrade (version: %s, chaos: %s):" +msgstr "" + +#: ./cli/app/deploy.go:303 +#, c-format +msgid "version: can not redeploy chaos version %s" +msgstr "" + +#: ./cli/app/deploy.go:305 +#, c-format +msgid "version: taking version from .env file: %s" +msgstr "" + +#: ./cli/app/logs.go:18 +msgid "logs [service] [flags]" +msgstr "" + +#: ./pkg/lint/recipe.go:103 +msgid "has published catalogue version" +msgstr "" + +#: ./pkg/ui/deploy.go:87 +#, c-format +msgid "writer: %v, " +msgstr "" + +#: ./cli/app/secret.go:262 +msgid "Remove a secret" +msgstr "" + +#: ./cli/app/app.go:9 +msgid "app [cmd] [args] [flags]" +msgstr "" + +#: ./cli/run.go:25 +msgid "The Co-op Cloud command-line utility belt 🎩🐇" +msgstr "" + +#: ./pkg/ssh/ssh.go:26 +msgid "docker: is the daemon running / your user has docker permissions?" +msgstr "" + +#: ./pkg/envfile/envfile.go:73 +#, c-format +msgid "couldn't parse %s" +msgstr "" + +#: ./pkg/config/abra.go:81 +msgid "read abra dir from config file" +msgstr "" + +#: ./pkg/recipe/git.go:256 +#, c-format +msgid "unable to check out default branch in %s: %s" +msgstr "" + +#: ./pkg/recipe/recipe.go:204 +#, c-format +msgid "ssh url: %s, " +msgstr "" + +#: ./cli/app/restore.go:123 +msgid "hooks" +msgstr "" + +#: ./cli/app/cmd.go:248 +msgid "local" +msgstr "" + +#: ./cli/catalogue/catalogue.go:26 +msgid "Generate the recipe catalogue" +msgstr "" + +#: ./pkg/lint/recipe.go:22 +msgid "critical" +msgstr "" + +#: ./pkg/upstream/convert/service.go:774 +msgid "replicas can only be used with replicated mode" +msgstr "" + +#: ./pkg/container/container.go:44 +#, c-format +msgid "expected 1 container but found %v: %s" +msgstr "" + +#: ./cli/app/secret.go:53 +msgid "missing arguments [secret]/[version] or '--all'" +msgstr "" + +#: ./cli/app/secret.go:311 +msgid "no secret(s) specified?" +msgstr "" + +#: ./cli/app/ps.go:28 +msgid "ps [flags]" +msgstr "" + +#: ./cli/app/deploy.go:177 +msgid "skipping domain checks, no DOMAIN=... configured" +msgstr "" + +#: ./cli/app/backup.go:65 +msgid "download [flags]" +msgstr "" + +#: ./cli/app/backup.go:295 +msgid "retries" +msgstr "" + +#: ./cli/app/volume.go:88 +msgid " # delete volumes interactively\n" + " abra app volume rm 1312.net\n" + "\n" + " # delete specific volume\n" + " abra app volume rm 1312.net my_volume" +msgstr "" + +#: ./cli/app/volume.go:162 +msgid "'x' indicates selected, enter / return to confirm, ctrl-c to exit, vim mode is enabled" +msgstr "" + +#: ./cli/app/undeploy.go:143 ./cli/server/prune.go:66 +#, c-format +msgid "images pruned: %d; space reclaimed: %s" +msgstr "" + +#: ./cli/catalogue/catalogue.go:27 +msgid "Generate a new copy of the recipe catalogue.\n" + "\n" + "N.B. this command **will** wipe local unstaged changes from your local recipes\n" + "if present. \"--chaos/-C\" on this command refers to the catalogue repository\n" + "(\"$ABRA_DIR/catalogue\") and not the recipes. Please take care not to lose your\n" + "changes.\n" + "\n" + "It is possible to generate new metadata for a single recipe by passing\n" + "[recipe]. The existing local catalogue will be updated, not overwritten.\n" + "\n" + "It is quite easy to get rate limited by Docker Hub when running this command.\n" + "If you have a Hub account you can \"docker login\" and Abra will automatically\n" + "use those details.\n" + "\n" + "Push your new release to git.coopcloud.tech with \"--publish/-p\". This requires\n" + "that you have permission to git push to these repositories and have your SSH\n" + "keys configured on your account." +msgstr "" + +#: ./cli/app/labels.go:26 +msgid "Both local recipe and live deployment labels are shown." +msgstr "" + +#: ./cli/catalogue/catalogue.go:89 +msgid "collecting catalogue metadata" +msgstr "" + +#: ./pkg/secret/secret.go:126 +#, c-format +msgid "missing version for secret? (%s)" +msgstr "" + +#: ./pkg/secret/secret.go:268 +#, c-format +msgid "generated and stored %v on %s" +msgstr "" + +#: ./pkg/recipe/git.go:367 +#, c-format +msgid "detected %s as tags for recipe %s" +msgstr "" + +#: ./pkg/recipe/recipe.go:200 +#, c-format +msgid "version : %s, " +msgstr "" + +#: ./cli/app/ps.go:179 +msgid "SERVICE" +msgstr "" + +#: ./cli/app/upgrade.go:127 +msgid "no available upgrades" +msgstr "" + +#: ./cli/app/upgrade.go:397 +#, c-format +msgid "'%s' is not a known version" +msgstr "" + +#: ./cli/app/volume.go:182 +#, c-format +msgid "%d volumes removed successfully" +msgstr "" + +#: ./cli/app/list.go:291 +msgid "show app deployment status" +msgstr "" + +#: ./cli/run.go:28 +msgid "app" +msgstr "" + +#: ./pkg/lint/recipe.go:141 +msgid "name a servce 'app'" +msgstr "" + +#: ./pkg/lint/recipe.go:176 +msgid "only annotated tags used for recipe version" +msgstr "" + +#: ./cli/app/backup.go:167 +#, c-format +msgid "including RETRIES=%s in backupbot exec invocation" +msgstr "" + +#: ./cli/app/list.go:43 ./cli/server/list.go:18 +msgid "list [flags]" +msgstr "" + +#: ./cli/server/prune.go:75 +#, c-format +msgid "volumes pruned: %d; space reclaimed: %s" +msgstr "" + +#: ./cli/server/add.go:24 +msgid "Add a new server to your configuration so that it can be managed by Abra.\n" + "\n" + "Abra relies on the standard SSH command-line and ~/.ssh/config for client\n" + "connection details. You must configure an entry per-host in your ~/.ssh/config\n" + "for each server:\n" + "\n" + " Host 1312.net 1312\n" + " Hostname 1312.net\n" + " User antifa\n" + " Port 12345\n" + " IdentityFile ~/.ssh/antifa@somewhere\n" + "\n" + "If \"--local\" is passed, then Abra assumes that the current local server is\n" + "intended as the target server. This is useful when you want to have your entire\n" + "Co-op Cloud config located on the server itself, and not on your local\n" + "developer machine. The domain is then set to \"default\"." +msgstr "" + +#: ./pkg/lint/recipe.go:104 +msgid "publish a recipe version to the catalogue" +msgstr "" + +#: ./pkg/lint/recipe.go:147 +msgid "deploy labels stanza present" +msgstr "" + +#: ./pkg/upstream/convert/volume.go:47 +msgid "bind options are incompatible with type volume" +msgstr "" + +#: ./pkg/envfile/envfile.go:42 ./pkg/envfile/envfile.go:80 ./pkg/config/env.go:50 +#, c-format +msgid "read %s from %s" +msgstr "" + +#: ./cli/app/cmd.go:35 +msgid " # pass args/flags without \"--\"\n" + " abra app cmd 1312.net app my_cmd_arg foo --user bar\n" + "\n" + " # pass args/flags with \"--\"\n" + " abra app cmd 1312.net app my_cmd_args --user bar -- foo -vvv\n" + "\n" + " # drop the [service] arg if using \"--local/-l\"\n" + " abra app cmd 1312.net my_cmd --local" +msgstr "" + +#: ./cli/app/upgrade.go:152 +#, c-format +msgid "choosing %s as version to upgrade" +msgstr "" + +#: ./pkg/lint/recipe.go:83 +msgid "use a tag for all images" +msgstr "" + +#: ./pkg/config/abra.go:34 +#, c-format +msgid "error loading config file: %s" +msgstr "" + +#: ./pkg/recipe/compose.go:229 +#, c-format +msgid "coop-cloud.${STACK_NAME}.version=%s" +msgstr "" + +#: ./pkg/git/commit.go:44 +msgid "dry run: no changes commited" +msgstr "" + +#: ./pkg/git/clone.go:64 ./pkg/git/clone.go:102 +#, c-format +msgid "git clone %s: cancelled due to interrupt" +msgstr "" + +#: ./cli/app/secret.go:476 ./cli/app/secret.go:516 ./cli/app/secret.go:540 ./cli/app/secret.go:548 ./cli/app/restore.go:132 ./cli/app/ps.go:207 ./cli/app/cmd.go:273 ./cli/app/new.go:380 ./cli/app/check.go:88 ./cli/app/restart.go:155 ./cli/app/deploy.go:327 ./cli/app/cp.go:379 ./cli/app/backup.go:288 ./cli/app/backup.go:304 ./cli/app/labels.go:136 +msgid "C" +msgstr "" + +#: ./cli/app/cmd.go:264 +msgid "tty" +msgstr "" + +#: ./cli/app/deploy.go:316 +#, c-format +msgid "version: taking new recipe version: %s" +msgstr "" + +#: ./cli/app/remove.go:38 +msgid " abra app remove 1312.net" +msgstr "" + +#: ./cli/app/volume.go:76 +msgid "remove [volume] [flags]" +msgstr "" + +#: ./cli/run.go:126 +msgid "show debug messages" +msgstr "" + +#: ./cli/updater/updater.go:103 +msgid "missing arguments or --all/-a flag" +msgstr "" + +#: ./pkg/upstream/container/exec.go:108 +msgid "Error monitoring TTY size:" +msgstr "" + +#: ./cli/app/secret.go:137 +msgid "NOW" +msgstr "" + +#: ./cli/app/deploy.go:276 +#, c-format +msgid "secret not generated: %s" +msgstr "" + +#: ./cli/run.go:24 +msgid "abra [cmd] [args] [flags]" +msgstr "" + +#: ./pkg/upstream/commandconn/commandconn.go:255 +#, c-format +msgid "unimplemented call: SetDeadline(%v)" +msgstr "" + +#: ./pkg/upstream/convert/volume.go:110 +msgid "invalid tmpfs source, source must be empty" +msgstr "" + +#: ./pkg/git/push.go:31 +msgid "git changes pushed" +msgstr "" + +#: ./cli/app/restore.go:19 +msgid "Snapshots are restored while apps are deployed.\n" + "\n" + "Some restore scenarios may require service / app restarts." +msgstr "" + +#: ./cli/app/restore.go:57 +#, c-format +msgid "including TARGET=%s in backupbot exec invocation" +msgstr "" + +#: ./cli/app/services.go:67 +msgid "SERVICE (LONG)" +msgstr "" + +#: ./cli/app/restart.go:24 +msgid "This command restarts services within a deployed app.\n" + "\n" + "Run \"abra app ps \" to see a list of service names.\n" + "\n" + "Pass \"--all-services/-a\" to restart all services." +msgstr "" + +#: ./cli/app/env.go:18 +msgid " abra app env 1312.net" +msgstr "" + +#: ./cli/app/volume.go:150 +#, c-format +msgid "removing volume %s failed: %s" +msgstr "" + +#: ./pkg/upstream/commandconn/commandconn.go:259 +#, c-format +msgid "unimplemented call: SetReadDeadline(%v)" +msgstr "" + +#: ./pkg/recipe/recipe.go:659 +msgid "retrieving recipes" +msgstr "" + +#: ./cli/app/restore.go:115 ./cli/app/backup.go:279 +msgid "volumes" +msgstr "" + +#: ./cli/app/rollback.go:238 +#, c-format +msgid "please select a downgrade (version: %s):" +msgstr "" + +#: ./cli/app/backup.go:247 +msgid "timestamps" +msgstr "" + +#: ./pkg/lint/recipe.go:187 +#, c-format +msgid "linting for critical errors in %s configs" +msgstr "" + +#: ./pkg/upstream/container/tty.go:39 +#, c-format +msgid "error resize: %s" +msgstr "" + +#: ./pkg/recipe/recipe.go:74 +#, c-format +msgid "choosing %s as latest version of %s" +msgstr "" + +#: ./pkg/git/read.go:88 +#, c-format +msgid "no %s exists, not reading any global gitignore config" +msgstr "" + +#: ./pkg/git/init.go:24 +#, c-format +msgid "initialised new git repo in %s" +msgstr "" + +#: ./cli/app/backup.go:68 +msgid "Downloads a backup.tar.gz to the current working directory.\n" + "\n" + "\"--volumes/-v\" includes data contained in volumes alongide paths specified in\n" + "\"backupbot.backup.path\" labels." +msgstr "" + +#: ./cli/server/prune.go:101 +msgid "remove volumes" +msgstr "" + +#: ./cli/server/add.go:84 +msgid "local server successfully added" +msgstr "" + +#: ./pkg/ssh/ssh.go:16 +#, c-format +msgid "SSH host key verification failed for %s" +msgstr "" + +#: ./pkg/upstream/container/hijack.go:167 +#, c-format +msgid "error sendStdin: %s" +msgstr "" + +#: ./pkg/upstream/convert/service.go:815 +#, c-format +msgid "invalid credential spec: cannot specify both %s, and %s" +msgstr "" + diff --git a/pkg/i18n/locales/es/LC_MESSAGES/default.po b/pkg/i18n/locales/es/LC_MESSAGES/default.po new file mode 100644 index 00000000..6bb34bd3 --- /dev/null +++ b/pkg/i18n/locales/es/LC_MESSAGES/default.po @@ -0,0 +1,3727 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: EMAIL\n" +"POT-Creation-Date: 2025-08-23 14:02+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: pkg/dns/dns.go:52 +#, c-format +msgid "app domain %s (%s) does not appear to resolve to app server %s (%s)?" +msgstr "" + +#: cli/app/new.go:324 +msgid "no server provided" +msgstr "" + +#: cli/app/backup.go:49 +#, c-format +msgid "including SHOW_ALL=%v in backupbot exec invocation" +msgstr "" + +#: cli/upgrade.go:55 +msgid "install release candidate (may contain bugs)" +msgstr "" + +#: pkg/server/server.go:25 +#, c-format +msgid "successfully created %s" +msgstr "" + +#: cli/app/restore.go:118 +msgid "restore specific volumes" +msgstr "" + +#: cli/app/services.go:67 +msgid "SERVICE (SHORT)" +msgstr "" + +#: cli/app/restart.go:68 +msgid "cannot use [service] and --all-services/-a together" +msgstr "" + +#: cli/app/volume.go:190 +msgid "volume [cmd] [args] [flags]" +msgstr "" + +#: cli/app/secret.go:374 +msgid "List all secrets" +msgstr "" + +#: cli/app/new.go:266 +msgid "Specify app domain" +msgstr "" + +#: cli/app/check.go:17 +msgid "check [flags]" +msgstr "" + +#: cli/app/cp.go:85 +msgid "one of / arguments must take $SERVICE:$PATH form" +msgstr "" + +#: cli/upgrade.go:16 +msgid "upgrade [flags]" +msgstr "" + +#: pkg/recipe/git.go:262 +#, c-format +msgid "unable to fetch tags in %s: %s" +msgstr "" + +#: pkg/recipe/recipe.go:458 +#, c-format +msgid "recipe %s does not exist?" +msgstr "" + +#: cli/app/list.go:288 +msgid "status" +msgstr "" + +#: pkg/secret/secret.go:207 +#, c-format +msgid "skipping generation of %s (generate=false)" +msgstr "" + +#: pkg/recipe/recipe.go:207 +#, c-format +msgid "sample env: %s, " +msgstr "" + +#: cli/app/volume.go:78 +msgid "" +"Remove volumes associated with an app.\n" +"\n" +"The app in question must be undeployed before you try to remove volumes. " +"See\n" +"\"abra app undeploy \" for more.\n" +"\n" +"The command is interactive and will show a multiple select input which " +"allows\n" +"you to make a seclection. Use the \"?\" key to see more help on navigating " +"this\n" +"interface.\n" +"\n" +"Passing \"--force/-f\" will select all volumes for removal. Be careful." +msgstr "" + +#: pkg/recipe/git.go:187 +#, c-format +msgid "unable to check git clean status in %s: %s" +msgstr "" + +#: pkg/recipe/recipe.go:330 +#, c-format +msgid "%s: image meta is empty?" +msgstr "" + +#: cli/app/rollback.go:28 +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" +"versions are supported values for \"[version]\".\n" +"\n" +"It is possible to \"--force/-f\" an downgrade if you want to re-deploy a " +"specific\n" +"version.\n" +"\n" +"Only the deployed version is consulted when trying to determine what " +"downgrades\n" +"are available. The live deployment version is the \"source of truth\" in " +"this\n" +"case. The stored .env version is not consulted.\n" +"\n" +"A downgrade can be destructive, please ensure you have a copy of your app " +"data\n" +"beforehand. See \"abra app backup\" for more." +msgstr "" + +#: cli/app/secret.go:373 cli/app/cmd.go:197 cli/app/backup.go:16 +#: cli/app/volume.go:20 cli/app/list.go:44 +msgid "ls" +msgstr "" + +#: cli/app/secret.go:459 cli/app/secret.go:555 cli/app/ps.go:198 +#: cli/app/list.go:311 +msgid "machine" +msgstr "" + +#: cli/app/volume.go:21 +msgid "List volumes associated with an app" +msgstr "" + +#: cli/app/list.go:153 +#, c-format +msgid "unable to retrieve tags for %s: %s" +msgstr "" + +#: cli/app/list.go:177 +msgid "latest" +msgstr "" + +#: cli/app/list.go:296 cli/app/list.go:303 cli/run.go:32 +msgid "recipe" +msgstr "" + +#: cli/upgrade.go:18 +msgid "Upgrade abra" +msgstr "" + +#: cli/app/undeploy.go:155 +msgid "prune" +msgstr "" + +#: cli/app/deploy.go:28 +msgid "deploy [version] [flags]" +msgstr "" + +#: cli/app/cp.go:72 +#, c-format +msgid "retrieved %s as target container on %s" +msgstr "" + +#: cli/app/remove.go:73 cli/app/volume.go:120 +#, c-format +msgid "%s is still deployed. Run \"abra app undeploy %s\"" +msgstr "" + +#: cli/server/add.go:137 +#, c-format +msgid "serverAdd: cleanUp: unable to list files in %s: %s" +msgstr "" + +#: pkg/upstream/container/hijack.go:156 +msgid "[hijack] End of stdin" +msgstr "" + +#: pkg/upstream/convert/service.go:462 +#, c-format +msgid "undefined config %q" +msgstr "" + +#: pkg/recipe/git.go:52 +#, c-format +msgid "can not redeploy chaos version (%s) without --chaos" +msgstr "" + +#: cli/app/secret.go:260 +msgid "remove [[secret] | --all] [flags]" +msgstr "" + +#: cli/app/new.go:315 +msgid "Select app server:" +msgstr "" + +#: cli/app/cp.go:245 +#, c-format +msgid "copy: %s" +msgstr "" + +#: cli/app/logs.go:20 +msgid "Tail app logs" +msgstr "" + +#: cli/app/backup.go:263 +msgid "path" +msgstr "" + +#: cli/app/list.go:216 +msgid "DOMAIN" +msgstr "" + +#: pkg/client/context.go:66 +msgid "context 'default' cannot be removed" +msgstr "" + +#: pkg/dns/dns.go:18 +#, c-format +msgid "%s: no IPv4 available" +msgstr "" + +#: pkg/ssh/ssh.go:20 +#, c-format +msgid "connection timed out for %s" +msgstr "" + +#: pkg/recipe/git.go:225 pkg/recipe/git.go:406 pkg/git/branch.go:95 +#, c-format +msgid "failed to check out %s in %s" +msgstr "" + +#: pkg/recipe/recipe.go:199 +#, c-format +msgid "{name: %s, " +msgstr "" + +#: pkg/recipe/recipe.go:208 +#, c-format +msgid "abra.sh: %s}" +msgstr "" + +#: pkg/git/read.go:31 +#, c-format +msgid "unable to open worktree of %s: %s" +msgstr "" + +#: pkg/container/container.go:69 +msgid "failed to match chosen container" +msgstr "" + +#: cli/app/backup.go:242 +msgid "show all paths" +msgstr "" + +#: cli/catalogue/catalogue.go:191 +msgid "chore: publish new catalogue release changes" +msgstr "" + +#: cli/upgrade.go:37 pkg/secret/pass.go:23 pkg/secret/pass.go:45 +#, c-format +msgid "attempting to run %s" +msgstr "" + +#: pkg/upstream/convert/service.go:652 +#, c-format +msgid "unknown restart policy: %s" +msgstr "" + +#: cli/app/secret.go:468 cli/app/secret.go:492 cli/app/secret.go:532 +#: cli/app/ps.go:29 cli/app/undeploy.go:156 cli/app/new.go:364 +#: cli/app/backup.go:264 +msgid "p" +msgstr "" + +#: cli/app/cmd.go:67 +msgid "requires at least 3 arguments" +msgstr "" + +#: cli/app/upgrade.go:323 +#, c-format +msgid "parsing deployment version failed: %s" +msgstr "" + +#: cli/app/cp.go:164 +#, c-format +msgid "copy %s from local to %s on container" +msgstr "" + +#: cli/app/config.go:36 +#, c-format +msgid "cannot find app with name %s" +msgstr "" + +#: cli/run.go:134 +msgid "toggle non-interactive mode" +msgstr "" + +#: pkg/upstream/convert/service.go:813 +#, c-format +msgid "invalid credential spec: cannot specify both %s and %s" +msgstr "" + +#: cli/app/secret.go:478 cli/app/secret.go:518 cli/app/secret.go:542 +#: cli/app/secret.go:550 cli/app/restore.go:134 cli/app/ps.go:209 +#: cli/app/cmd.go:275 cli/app/new.go:382 cli/app/check.go:90 +#: cli/app/restart.go:157 cli/app/deploy.go:329 cli/app/cp.go:381 +#: cli/app/backup.go:290 cli/app/backup.go:306 cli/app/labels.go:138 +#: cli/catalogue/catalogue.go:274 +msgid "ignore uncommitted recipes changes" +msgstr "" + +#: cli/app/new.go:343 +msgid "specify server for new app" +msgstr "" + +#: cli/app/logs.go:96 +msgid "only tail stderr" +msgstr "" + +#: cli/app/logs.go:104 +msgid "tail logs since YYYY-MM-DDTHH:MM:SSZ" +msgstr "" + +#: pkg/lint/recipe.go:68 +msgid "compose config has expected version" +msgstr "" + +#: pkg/recipe/git.go:434 +#, c-format +msgid "%s service is missing image tag?" +msgstr "" + +#: pkg/recipe/recipe.go:462 +#, c-format +msgid "recipe metadata retrieved for %s" +msgstr "" + +#: cli/app/secret.go:145 +msgid "Insert secret" +msgstr "" + +#: cli/app/new.go:355 +msgid "domain" +msgstr "" + +#: cli/app/list.go:299 +msgid "show apps of a specific recipe" +msgstr "" + +#: cli/run.go:31 +msgid "man" +msgstr "" + +#: cli/server/prune.go:17 +msgid "Prune resources on a server" +msgstr "" + +#: cli/server/add.go:141 +#, c-format +msgid "serverAdd: cleanUp: %s is not empty, aborting cleanup" +msgstr "" + +#: pkg/upstream/convert/volume.go:90 +msgid "invalid bind source, source cannot be empty" +msgstr "" + +#: pkg/recipe/git.go:151 +#, c-format +msgid "read %s as tags for recipe %s" +msgstr "" + +#: cli/app/secret.go:144 +msgid "i" +msgstr "" + +#: cli/app/check.go:19 +msgid "Ensure an app is well configured" +msgstr "" + +#: cli/app/deploy.go:29 cli/app/backup.go:66 +msgid "d" +msgstr "" + +#: cli/app/deploy.go:101 +#, c-format +msgid "get deploy version: %s" +msgstr "" + +#: cli/app/remove.go:19 +msgid "remove [flags]" +msgstr "" + +#: cli/app/backup.go:17 +msgid "List the contents of a snapshot" +msgstr "" + +#: cli/complete.go:13 +msgid "" +"To load completions:\n" +"\n" +"Bash:\n" +" # Load autocompletion for the current Bash session\n" +" $ source <(abra autocomplete bash)\n" +"\n" +" # To load autocompletion for each session, execute once:\n" +" # Linux:\n" +" $ abra autocomplete bash | sudo tee /etc/bash_completion.d/abra\n" +" # macOS:\n" +" $ abra autocomplete bash | sudo tee $(brew --prefix)/etc/bash_completion.d/" +"abra\n" +"\n" +"Zsh:\n" +" # If shell autocompletion is not already enabled in your environment,\n" +" # you will need to enable it. You can execute the following once:\n" +"\n" +" $ echo \"autoload -U compinit; compinit\" >> ~/.zshrc\n" +"\n" +" # To load autocompletions for each session, execute once:\n" +" $ abra autocomplete zsh > \"${fpath[1]}/_abra\"\n" +"\n" +" # You will need to start a new shell for this setup to take effect.\n" +"\n" +"fish:\n" +" $ abra autocomplete fish | source\n" +"\n" +" # To load autocompletions for each session, execute once:\n" +" $ abra autocomplete fish > ~/.config/fish/completions/abra.fish\n" +"\n" +"PowerShell:\n" +" PS> abra autocomplete powershell | Out-String | Invoke-Expression\n" +"\n" +" # To load autocompletions for every new session, run:\n" +" PS> abra autocomplete powershell > abra.ps1\n" +" # and source this file from your PowerShell profile." +msgstr "" + +#: pkg/recipe/git.go:251 +#, c-format +msgid "unable to open git work tree in %s: %s" +msgstr "" + +#: cli/app/secret.go:102 +msgid "no secrets generated" +msgstr "" + +#: cli/app/upgrade.go:329 cli/app/upgrade.go:368 +#, c-format +msgid "parsing recipe version failed: %s" +msgstr "" + +#: cli/app/upgrade.go:443 cli/app/new.go:356 cli/app/rollback.go:332 +#: cli/app/deploy.go:343 +msgid "D" +msgstr "" + +#: pkg/lint/recipe.go:90 +msgid "tag all images with stable tags" +msgstr "" + +#: pkg/lint/recipe.go:154 +msgid "traefik routing enabled" +msgstr "" + +#: pkg/upstream/commandconn/connection.go:38 +msgid "ssh host connection is not valid" +msgstr "" + +#: pkg/git/init.go:73 +msgid "set 'main' as the default branch" +msgstr "" + +#: cli/app/secret.go:394 cli/app/ps.go:182 cli/app/list.go:221 +msgid "VERSION" +msgstr "" + +#: cli/app/secret.go:462 cli/app/secret.go:558 cli/app/ps.go:201 +#: cli/app/list.go:314 cli/server/list.go:102 +msgid "print machine-readable output" +msgstr "" + +#: cli/app/secret.go:475 cli/app/secret.go:515 cli/app/secret.go:539 +#: cli/app/secret.go:547 cli/app/restore.go:131 cli/app/ps.go:206 +#: cli/app/cmd.go:272 cli/app/new.go:379 cli/app/check.go:87 +#: cli/app/restart.go:154 cli/app/deploy.go:326 cli/app/cp.go:378 +#: cli/app/backup.go:287 cli/app/backup.go:303 cli/app/labels.go:135 +msgid "chaos" +msgstr "" + +#: cli/app/upgrade.go:445 cli/app/rollback.go:334 cli/app/deploy.go:345 +msgid "disable public DNS checks" +msgstr "" + +#: cli/run.go:78 +#, c-format +msgid "abra version: %s, commit: %s, lang: %s" +msgstr "" + +#: pkg/catalogue/catalogue.go:40 +#, c-format +msgid "" +"%s has locally unstaged changes? please commit/remove your changes before " +"proceeding" +msgstr "" + +#: pkg/upstream/commandconn/commandconn.go:141 +msgid "commandconn: failed to wait" +msgstr "" + +#: pkg/upstream/convert/service.go:780 +#, c-format +msgid "unknown mode: %s" +msgstr "" + +#: cli/app/upgrade.go:290 +#, c-format +msgid "please select an upgrade (version: %s, chaos: %s):" +msgstr "" + +#: pkg/service/service.go:41 +#, c-format +msgid "no services deployed matching label '%s'?" +msgstr "" + +#: pkg/lint/recipe.go:97 +msgid "use semver-like tags" +msgstr "" + +#: pkg/upstream/container/hijack.go:135 +#, c-format +msgid "error receiveStdout: %s" +msgstr "" + +#: pkg/ui/deploy.go:341 +#, c-format +msgid "%s: %s (retries: %v, healthcheck: %s)" +msgstr "" + +#: pkg/config/env.go:74 pkg/config/env.go:107 +#, c-format +msgid "broken symlink in your abra config folders: %s" +msgstr "" + +#: pkg/git/common.go:13 +#, c-format +msgid "no .git directory in %s?" +msgstr "" + +#: pkg/git/init.go:70 +#, c-format +msgid "repo set config: %s" +msgstr "" + +#: cli/app/cmd.go:22 +msgid "" +"command [service | --local] [[args] [flags] | [flags] -- " +"[args]]" +msgstr "" + +#: cli/app/run.go:22 cli/app/upgrade.go:459 cli/app/backup.go:296 +#: cli/app/list.go:297 +msgid "r" +msgstr "" + +#: cli/app/upgrade.go:442 cli/app/rollback.go:331 cli/app/deploy.go:342 +msgid "no-domain-checks" +msgstr "" + +#: cli/app/deploy.go:296 +#, c-format +msgid "version: taking version from cli arg: %s" +msgstr "" + +#: cli/catalogue/catalogue.go:258 +msgid "report changes that would be made" +msgstr "" + +#: cli/server/add.go:107 +#, c-format +msgid "ssh %s error: %s" +msgstr "" + +#: pkg/client/client.go:44 +#, c-format +msgid "unknown server, run \"abra server add %s\"?" +msgstr "" + +#: pkg/lint/recipe.go:52 +#, c-format +msgid "%s: skip condition: %s" +msgstr "" + +#: cli/app/new.go:358 +msgid "domain name for app" +msgstr "" + +#: cli/app/secret.go:366 +msgid "no secrets to remove?" +msgstr "" + +#: cli/app/secret.go:394 +msgid "CREATED ON SERVER" +msgstr "" + +#: pkg/client/client.go:88 +#, c-format +msgid "created client for %s" +msgstr "" + +#: pkg/lint/recipe.go:96 +msgid "tags use semver-like format" +msgstr "" + +#: cli/app/secret.go:134 +#, c-format +msgid "generated secrets %s shown again, please take note of them %s" +msgstr "" + +#: cli/app/cmd.go:108 +#, c-format +msgid "%s does not exist for %s?" +msgstr "" + +#: cli/app/env.go:15 +msgid "env [flags]" +msgstr "" + +#: cli/app/list.go:322 +msgid "show apps of a specific server" +msgstr "" + +#: cli/app/labels.go:53 +msgid "DEPLOYED LABELS" +msgstr "" + +#: cli/app/restore.go:18 +msgid "Restore a snapshot" +msgstr "" + +#: cli/app/restart.go:108 +#, c-format +msgid "attempting to scale %s to 0" +msgstr "" + +#: cli/app/remove.go:94 +msgid "no configs to remove" +msgstr "" + +#: pkg/ssh/ssh.go:22 +#, c-format +msgid "ssh auth: permission denied for %s" +msgstr "" + +#: pkg/secret/pass.go:51 +#, c-format +msgid "%s removed from pass store" +msgstr "" + +#: pkg/upstream/convert/volume.go:116 +msgid "volume options are incompatible with type tmpfs" +msgstr "" + +#: pkg/recipe/compose.go:58 +#, c-format +msgid "COMPOSE_FILE detected (%s), loading %s" +msgstr "" + +#: pkg/recipe/recipe.go:361 +#, c-format +msgid "%s: marker string %s not found" +msgstr "" + +#: cli/app/upgrade.go:458 +msgid "releasenotes" +msgstr "" + +#: cli/app/undeploy.go:128 cli/server/prune.go:45 +#, c-format +msgid "containers pruned: %d; space reclaimed: %s" +msgstr "" + +#: cli/app/cp.go:253 +#, c-format +msgid "untar: %s" +msgstr "" + +#: cli/app/labels.go:102 +msgid "LABELS OVERVIEW" +msgstr "" + +#: cli/server/list.go:20 +msgid "List managed servers" +msgstr "" + +#: pkg/upstream/commandconn/commandconn.go:162 +#, c-format +msgid "command %v did not exit after %v: stderr=%q" +msgstr "" + +#: pkg/recipe/compose.go:248 +msgid "no existing label found, automagic insertion not supported yet" +msgstr "" + +#: cli/app/new.go:309 +#, c-format +msgid "single server detected, choosing %s automatically" +msgstr "" + +#: cli/app/remove.go:141 +msgid "no volumes to remove" +msgstr "" + +#: cli/app/backup.go:234 cli/app/backup.go:258 +msgid "list specific snapshot" +msgstr "" + +#: cli/app/volume.go:145 +#, c-format +msgid "unable to remove volume: no volume with name '%s'?" +msgstr "" + +#: pkg/recipe/compose.go:159 +#, c-format +msgid "parsed %s from %s" +msgstr "" + +#: cli/app/secret.go:261 cli/app/remove.go:20 cli/app/volume.go:93 +msgid "rm" +msgstr "" + +#: cli/app/cmd.go:251 +msgid "run command locally" +msgstr "" + +#: cli/app/new.go:135 +#, c-format +msgid "%s sanitised as %s for new app" +msgstr "" + +#: cli/app/volume.go:184 +msgid "no volumes removed" +msgstr "" + +#: pkg/upstream/convert/service.go:414 +#, c-format +msgid "undefined secret %q" +msgstr "" + +#: cli/app/secret.go:267 +msgid " abra app secret rm 1312.net oauth_key" +msgstr "" + +#: cli/app/cp.go:145 cli/app/cp.go:184 +#, c-format +msgid "create remote directory: %s" +msgstr "" + +#: pkg/formatter/formatter.go:46 +msgid " ago" +msgstr "" + +#: cli/app/upgrade.go:30 +msgid "up" +msgstr "" + +#: pkg/lint/recipe.go:111 +msgid "fill out all the metadata" +msgstr "" + +#: pkg/git/init.go:21 +#, c-format +msgid "git branch rename: %s" +msgstr "" + +#: pkg/git/init.go:29 +#, c-format +msgid "git open: %s" +msgstr "" + +#: cli/app/secret.go:124 cli/app/secret.go:424 cli/server/list.go:82 +#, c-format +msgid "unable to render to JSON: %s" +msgstr "" + +#: cli/app/restore.go:74 +#, c-format +msgid "including CONTAINER=%s in backupbot exec invocation" +msgstr "" + +#: cli/app/run.go:105 +msgid "do not request a TTY" +msgstr "" + +#: cli/app/new.go:118 +#, c-format +msgid "failed to retrieve latest commit for %s: %s" +msgstr "" + +#: cli/app/remove.go:148 +#, c-format +msgid "file: %s removed" +msgstr "" + +#: cli/app/backup.go:250 +msgid "include timestamps" +msgstr "" + +#: pkg/upstream/convert/volume.go:56 +#, c-format +msgid "undefined volume %q" +msgstr "" + +#: cli/app/restore.go:110 +msgid "restore specific services" +msgstr "" + +#: cli/app/restore.go:126 +msgid "enable pre/post-hook command execution" +msgstr "" + +#: cli/app/restart.go:22 +msgid "re" +msgstr "" + +#: cli/app/labels.go:74 +msgid "RECIPE LABELS" +msgstr "" + +#: pkg/upstream/container/exec.go:43 +msgid "exec ID empty" +msgstr "" + +#: pkg/recipe/git.go:178 +#, c-format +msgid "successfully checked %s out to %s in %s" +msgstr "" + +#: pkg/git/init.go:38 +#, c-format +msgid "git add: %s" +msgstr "" + +#: cli/app/new.go:340 cli/app/new.go:347 cli/app/list.go:319 +#: cli/app/list.go:326 cli/run.go:33 +msgid "server" +msgstr "" + +#: cli/app/app.go:11 +msgid "Manage apps" +msgstr "" + +#: pkg/secret/secret.go:119 +msgid "not generating app secrets, none enabled in recipe config" +msgstr "" + +#: pkg/upstream/convert/service.go:834 +#, c-format +msgid "" +"invalid credential spec: spec specifies config %v, but no such config can be " +"found" +msgstr "" + +#: cli/run.go:29 +msgid "autocomplete" +msgstr "" + +#: cli/app/run.go:113 +msgid "run command as user" +msgstr "" + +#: cli/app/volume.go:161 +msgid "which volumes do you want to remove?" +msgstr "" + +#: cli/updater/updater.go:231 +#, c-format +msgid "%s (%s) can be upgraded from version %s to %s" +msgstr "" + +#: cli/app/upgrade.go:208 cli/app/deploy.go:166 +#, c-format +msgid "%s missing from %s.env" +msgstr "" + +#: cli/app/list.go:222 +msgid "UPGRADE" +msgstr "" + +#: cli/app/list.go:223 +msgid "AUTOUPDATE" +msgstr "" + +#: cli/app/labels.go:25 +msgid "Show deployment labels" +msgstr "" + +#: cli/updater/updater.go:76 +msgid "Upgrade apps" +msgstr "" + +#: pkg/recipe/compose.go:249 +#, c-format +msgid "add '- \"%s\"' manually to the 'app' service in %s" +msgstr "" + +#: cli/app/secret.go:483 cli/app/secret.go:523 cli/app/backup.go:239 +msgid "all" +msgstr "" + +#: cli/app/backup.go:117 +#, c-format +msgid "including VOLUMES=%v in backupbot exec invocation" +msgstr "" + +#: cli/server/remove.go:17 +msgid "remove [flags]" +msgstr "" + +#: pkg/client/registry.go:20 +#, c-format +msgid "failed to parse image %s, saw: %s" +msgstr "" + +#: pkg/secret/pass.go:15 pkg/secret/pass.go:37 +msgid "pass command not found on $PATH, is it installed?" +msgstr "" + +#: pkg/git/read.go:45 +#, c-format +msgid "unable to query status of %s: %s" +msgstr "" + +#: cli/app/upgrade.go:269 cli/app/deploy.go:231 +#, c-format +msgid "attempting to run post deploy commands, saw: %s" +msgstr "" + +#: cli/app/rollback.go:26 +msgid "rl" +msgstr "" + +#: cli/app/cp.go:32 +msgid "" +" # copy myfile.txt to the root of the app service\n" +" abra app cp 1312.net myfile.txt app:/\n" +"\n" +" # copy that file back to your current working directory locally\n" +" abra app cp 1312.net app:/myfile.txt ./" +msgstr "" + +#: cli/app/config.go:19 +msgid " abra config 1312.net" +msgstr "" + +#: cli/run.go:93 +msgid "" +" # generate the man pages into /usr/local/share/man/man1\n" +" abra_path=$(which abra) # pass abra absolute path to sudo below\n" +" sudo $abra_path man\n" +" sudo mandb\n" +"\n" +" # read the man pages\n" +" man abra\n" +" man abra-app-deploy" +msgstr "" + +#: pkg/ssh/ssh.go:18 +#, c-format +msgid "could not resolve hostname for %s" +msgstr "" + +#: pkg/ui/deploy.go:333 +msgid "rolled back" +msgstr "" + +#: pkg/recipe/git.go:458 +#, c-format +msgid "collected %s for %s" +msgstr "" + +#: cli/app/secret.go:57 +msgid "cannot use '[secret] [version]' and '--all' together" +msgstr "" + +#: cli/app/cmd.go:196 cli/app/backup.go:15 cli/app/volume.go:19 +msgid "list [flags]" +msgstr "" + +#: cli/app/rollback.go:145 +#, c-format +msgid "choosing %s as version to rollback" +msgstr "" + +#: cli/server/add.go:23 +msgid "Add a new server" +msgstr "" + +#: cli/app/secret.go:106 cli/app/new.go:187 +msgid "VALUE" +msgstr "" + +#: cli/app/secret.go:500 cli/app/upgrade.go:435 cli/app/rollback.go:324 +#: cli/app/deploy.go:335 cli/app/remove.go:156 cli/app/volume.go:199 +msgid "f" +msgstr "" + +#: cli/app/cmd.go:259 +msgid "request remote user" +msgstr "" + +#: cli/app/upgrade.go:285 +#, c-format +msgid "please select an upgrade (version: %s):" +msgstr "" + +#: cli/app/new.go:70 cli/app/deploy.go:262 +msgid "cannot use [version] and --chaos together" +msgstr "" + +#: cli/app/remove.go:116 +#, c-format +msgid "secret: %s removed" +msgstr "" + +#: cli/complete.go:12 +msgid "Generate autocompletion script" +msgstr "" + +#: pkg/recipe/recipe.go:368 +#, c-format +msgid "%s: end marker %s not found" +msgstr "" + +#: pkg/recipe/recipe.go:555 +#, c-format +msgid "fetching repo metadata from %s" +msgstr "" + +#: cli/app/secret.go:216 +#, c-format +msgid "reading secret from file: %s" +msgstr "" + +#: cli/app/secret.go:246 +#, c-format +msgid "deleted %s successfully from server" +msgstr "" + +#: cli/app/new.go:290 +msgid "Generate app secrets?" +msgstr "" + +#: pkg/upstream/convert/service.go:604 +msgid "test and disable can't be set at the same time" +msgstr "" + +#: pkg/recipe/recipe.go:201 +#, c-format +msgid "dirty: %v, " +msgstr "" + +#: cli/app/services.go:21 +msgid "services [flags]" +msgstr "" + +#: pkg/lint/recipe.go:148 +msgid "include \"deploy: labels: ...\" stanza" +msgstr "" + +#: pkg/lint/recipe.go:177 +msgid "replace lightweight tag with annotated tag" +msgstr "" + +#: pkg/upstream/container/hijack.go:172 +#, c-format +msgid "couldn't send EOF: %s" +msgstr "" + +#: pkg/git/clone.go:89 +#, c-format +msgid "git clone: %s already exists" +msgstr "" + +#: cli/app/restore.go:102 +msgid "target path" +msgstr "" + +#: cli/app/new.go:47 +msgid "new [recipe] [version] [flags]" +msgstr "" + +#: cli/app/new.go:49 +msgid "Create a new app" +msgstr "" + +#: cli/app/remove.go:59 +msgid "aborting as requested" +msgstr "" + +#: cli/app/volume.go:71 +#, c-format +msgid "no volumes created for %s" +msgstr "" + +#: cli/catalogue/catalogue.go:250 +msgid "publish changes to git.coopcloud.tech" +msgstr "" + +#: cli/run.go:92 +msgid "Generate manpage" +msgstr "" + +#: cli/server/prune.go:56 +msgid "removing all images, not only dangling ones" +msgstr "" + +#: cli/app/secret.go:143 +msgid "insert [flags]" +msgstr "" + +#: cli/app/undeploy.go:158 +msgid "prune unused containers, networks, and dangling images" +msgstr "" + +#: pkg/upstream/commandconn/commandconn.go:49 +#, c-format +msgid "commandconn: starting %s with %v" +msgstr "" + +#: cli/app/secret.go:263 +msgid "" +"This command removes a secret from an app environment.\n" +"\n" +"Arbitrary secret removal is not supported. Secrets that are removed must\n" +"match those configured in the recipe beforehand." +msgstr "" + +#: cli/app/cmd.go:265 +msgid "T" +msgstr "" + +#: cli/app/check.go:20 +msgid "" +"Compare env vars in both the app \".env\" and recipe \".env.sample\" file.\n" +"\n" +"The goal is to ensure that recipe \".env.sample\" env vars are defined in " +"your\n" +"app \".env\" file. Only env var definitions in the \".env.sample\" which " +"are\n" +"uncommented, e.g. \"FOO=bar\" are checked. If an app \".env\" file does not " +"include\n" +"these env vars, then \"check\" will complain.\n" +"\n" +"Recipe maintainers may or may not provide defaults for env vars within " +"their\n" +"recipes regardless of commenting or not (e.g. through the use of\n" +"${FOO:} syntax). \"check\" does not confirm or deny this for you." +msgstr "" + +#: cli/server/add.go:128 +#, c-format +msgid "serverAdd: cleanUp: cleaning up context for %s" +msgstr "" + +#: cli/app/undeploy.go:104 +msgid "undeploy succeeded 🟢" +msgstr "" + +#: cli/app/deploy.go:290 +#, c-format +msgid "version: taking chaos version: %s" +msgstr "" + +#: cli/app/deploy.go:311 +#, c-format +msgid "version: taking deployed version: %s" +msgstr "" + +#: cli/app/labels.go:23 +msgid "labels [flags]" +msgstr "" + +#: cli/updater/updater.go:35 +msgid "notify [flags]" +msgstr "" + +#: pkg/upstream/container/exec.go:113 +#, c-format +msgid "Error hijack: %s" +msgstr "" + +#: pkg/recipe/git.go:274 +#, c-format +msgid "unable to git pull in %s: %s" +msgstr "" + +#: pkg/git/diff.go:30 +msgid "unable to locate git command, cannot output diff" +msgstr "" + +#: cli/catalogue/catalogue.go:227 +msgid "dry run: no changes published" +msgstr "" + +#: cli/updater/updater.go:155 +#, c-format +msgid "no %s label found for %s" +msgstr "" + +#: pkg/lint/recipe.go:504 +msgid "invalid lightweight tag detected" +msgstr "" + +#: cli/app/secret.go:510 +msgid "trim input" +msgstr "" + +#: cli/app/restore.go:68 +#, c-format +msgid "including VOLUMES=%s in backupbot exec invocation" +msgstr "" + +#: cli/app/upgrade.go:362 +#, c-format +msgid "parsing deployed version failed: %s" +msgstr "" + +#: cli/app/cp.go:272 +msgid "can't copy dir to file" +msgstr "" + +#: pkg/upstream/convert/volume.go:113 +msgid "bind options are incompatible with type tmpfs" +msgstr "" + +#: pkg/recipe/compose.go:233 +#, c-format +msgid "%s is already set, nothing to do?" +msgstr "" + +#: cli/app/restart.go:132 +#, c-format +msgid "%s has been scaled to 0" +msgstr "" + +#: cli/app/remove.go:21 +msgid "Remove all app data, locally and remotely" +msgstr "" + +#: pkg/lint/recipe.go:203 +#, c-format +msgid "" +"\n" +"lint %s: %s" +msgstr "" + +#: pkg/git/clone.go:100 +#, c-format +msgid "unable to clean up git clone of %s: %s" +msgstr "" + +#: cli/app/restore.go:52 cli/app/backup.go:44 cli/app/backup.go:102 +#, c-format +msgid "including SNAPSHOT=%s in backupbot exec invocation" +msgstr "" + +#: cli/app/new.go:211 +#, c-format +msgid "secrets are %s shown again, please save them %s" +msgstr "" + +#: pkg/dns/dns.go:38 pkg/dns/dns.go:47 +#, c-format +msgid "cannot resolve ipv4 for %s?" +msgstr "" + +#: pkg/recipe/git.go:156 +#, c-format +msgid "attempting to checkout '%s' as chaos commit" +msgstr "" + +#: pkg/recipe/recipe.go:147 +#, c-format +msgid "invalid recipe: %s" +msgstr "" + +#: cli/app/ps.go:30 +msgid "Check app deployment status" +msgstr "" + +#: cli/app/new.go:372 cli/app/logs.go:102 cli/app/backup.go:272 +#: cli/app/list.go:289 +msgid "S" +msgstr "" + +#: cli/app/backup.go:180 +msgid "List all snapshots" +msgstr "" + +#: cli/server/add.go:163 +#, c-format +msgid "context for %s already exists" +msgstr "" + +#: cli/server/add.go:184 +#, c-format +msgid "server dir for %s already created" +msgstr "" + +#: pkg/lint/recipe.go:124 +msgid "long secret names" +msgstr "" + +#: pkg/catalogue/catalogue.go:59 pkg/recipe/git.go:245 +#, c-format +msgid "cannot ensure %s is up-to-date, no git remotes configured" +msgstr "" + +#: pkg/secret/secret.go:212 +#, c-format +msgid "attempting to generate and store %s on %s" +msgstr "" + +#: cli/app/deploy.go:96 +#, c-format +msgid "%s is already deployed" +msgstr "" + +#: cli/catalogue/catalogue.go:24 +msgid "generate [recipe] [flags]" +msgstr "" + +#: cli/server/add.go:114 +#, c-format +msgid "unable to resolve IPv4 for %s" +msgstr "" + +#: pkg/upstream/container/hijack.go:132 +msgid "[hijack] end of stdout" +msgstr "" + +#: pkg/ui/deploy.go:88 +#, c-format +msgid "status: %s, " +msgstr "" + +#: pkg/recipe/recipe.go:206 +#, c-format +msgid "readme: %s, " +msgstr "" + +#: pkg/git/read.go:52 +#, c-format +msgid "git status: %s: clean" +msgstr "" + +#: cli/app/labels.go:24 +msgid "lb" +msgstr "" + +#: cli/app/upgrade.go:240 cli/app/rollback.go:202 cli/app/deploy.go:203 +#, c-format +msgid "set waiting timeout to %d second(s)" +msgstr "" + +#: cli/app/cmd.go:46 +msgid "requires at least 2 arguments with --local/-l" +msgstr "" + +#: cli/app/secret.go:25 +msgid "g" +msgstr "" + +#: cli/app/secret.go:154 +msgid "" +" # insert regular secret\n" +" abra app secret insert 1312.net my_secret v1 mySuperSecret\n" +"\n" +" # insert secret as file\n" +" abra app secret insert 1312.net my_secret v1 secret.txt -f" +msgstr "" + +#: cli/app/secret.go:443 cli/app/restore.go:108 cli/app/new.go:341 +#: cli/app/logs.go:94 cli/app/backup.go:179 cli/app/backup.go:232 +#: cli/app/backup.go:256 cli/app/list.go:320 +msgid "s" +msgstr "" + +#: cli/app/new.go:199 +#, c-format +msgid "%s created (version: %s)" +msgstr "" + +#: cli/server/add.go:146 +#, c-format +msgid "serverAdd: cleanUp: failed to remove %s: %s" +msgstr "" + +#: cli/server/server.go:10 +msgid "server [cmd] [args] [flags]" +msgstr "" + +#: pkg/upstream/convert/volume.go:93 +msgid "volume options are incompatible with type bind" +msgstr "" + +#: cli/catalogue/catalogue.go:235 +msgid "Manage the recipe catalogue" +msgstr "" + +#: cli/run.go:142 +msgid "prefer offline & filesystem access" +msgstr "" + +#: cli/server/server.go:12 +msgid "Manage servers" +msgstr "" + +#: pkg/service/service.go:61 pkg/service/service.go:115 +msgid "which service are you looking for?" +msgstr "" + +#: pkg/upstream/commandconn/commandconn.go:239 +#, c-format +msgid "commandConn.Close: CloseRead: %v" +msgstr "" + +#: pkg/upstream/convert/service.go:72 +#, c-format +msgid "secret not found: %s" +msgstr "" + +#: pkg/git/read.go:50 +#, c-format +msgid "git status: %s: %s" +msgstr "" + +#: pkg/git/push.go:40 +msgid "git tags pushed" +msgstr "" + +#: cli/app/undeploy.go:22 +msgid "undeploy [flags]" +msgstr "" + +#: cli/app/new.go:371 cli/app/backup.go:271 +msgid "secrets" +msgstr "" + +#: cli/app/backup.go:67 +msgid "Download a snapshot" +msgstr "" + +#: cli/run.go:30 +msgid "catalogue" +msgstr "" + +#: cli/app/secret.go:362 +#, c-format +msgid "%s doesn't exist on server?" +msgstr "" + +#: cli/app/cmd.go:23 +msgid "cmd" +msgstr "" + +#: cli/app/rollback.go:142 +msgid "unknown deployed version, unable to downgrade" +msgstr "" + +#: cli/app/config.go:42 +msgid "which editor do you wish to use?" +msgstr "" + +#: cli/updater/updater.go:74 +msgid "upgrade [[stack] [recipe] | --all] [flags]" +msgstr "" + +#: pkg/service/service.go:57 pkg/service/service.go:111 +msgid "ambiguous service list received, prompting for input" +msgstr "" + +#: pkg/upstream/convert/volume.go:133 +msgid "volume options are incompatible with type npipe" +msgstr "" + +#: cli/app/secret.go:502 +msgid "treat input as a file" +msgstr "" + +#: cli/app/restart.go:133 +#, c-format +msgid "attempting to scale %s to 1" +msgstr "" + +#: cli/app/cp.go:29 +msgid "cp [flags]" +msgstr "" + +#: pkg/git/init.go:34 +#, c-format +msgid "git worktree: %s" +msgstr "" + +#: pkg/container/container.go:31 +#, c-format +msgid "no containers matching the %v filter found?" +msgstr "" + +#: cli/app/restore.go:116 cli/app/backup.go:280 +msgid "v" +msgstr "" + +#: cli/app/new.go:284 +#, c-format +msgid "%s has no secrets to generate, skipping..." +msgstr "" + +#: pkg/lint/recipe.go:481 +#, c-format +msgid "secret %s is longer than 12 characters" +msgstr "" + +#: pkg/upstream/commandconn/commandconn.go:263 +#, c-format +msgid "unimplemented call: SetWriteDeadline(%v)" +msgstr "" + +#: pkg/upstream/convert/volume.go:130 +msgid "invalid npipe source, source cannot be empty" +msgstr "" + +#: pkg/git/init.go:17 +#, c-format +msgid "git init: %s" +msgstr "" + +#: cli/app/rollback.go:27 +msgid "Roll an app back to a previous version" +msgstr "" + +#: cli/app/check.go:18 +msgid "chk" +msgstr "" + +#: cli/app/cp.go:108 +#, c-format +msgid "local %s " +msgstr "" + +#: pkg/upstream/container/tty.go:66 +msgid "failed to resize tty, using default size" +msgstr "" + +#: pkg/ui/deploy.go:83 +#, c-format +msgid "err: %v, " +msgstr "" + +#: pkg/recipe/compose.go:153 +#, c-format +msgid "unable to parse %s, skipping" +msgstr "" + +#: cli/app/secret.go:394 +msgid "GENERATED NAME" +msgstr "" + +#: cli/app/upgrade.go:461 +msgid "only show release notes" +msgstr "" + +#: cli/app/rollback.go:25 +msgid "rollback [version] [flags]" +msgstr "" + +#: cli/app/deploy.go:30 +msgid "Deploy an app" +msgstr "" + +#: cli/updater/updater.go:299 +#, c-format +msgid "available updates for %s: %s" +msgstr "" + +#: pkg/lint/recipe.go:155 +msgid "include \"traefik.enable=true\" deploy label" +msgstr "" + +#: pkg/lint/recipe.go:261 pkg/recipe/files.go:17 +#, c-format +msgid "unable to discover .env.sample for %s" +msgstr "" + +#: pkg/ui/deploy.go:121 +#, c-format +msgid "^%s" +msgstr "" + +#: cli/app/secret.go:146 +msgid "" +"This command inserts a secret into an app environment.\n" +"\n" +"Arbitrary secret insertion is not supported. Secrets that are inserted must\n" +"match those configured in the recipe beforehand.\n" +"\n" +"This can be useful when you want to manually generate secrets for an app\n" +"environment. Typically, you can let Abra generate them for you on app " +"creation\n" +"(see \"abra app new --secrets/-S\" for more)." +msgstr "" + +#: cli/app/cmd.go:249 cli/app/logs.go:19 +msgid "l" +msgstr "" + +#: cli/app/restart.go:143 +#, c-format +msgid "%s has been scaled to 1" +msgstr "" + +#: cli/updater/updater.go:273 +#, fuzzy, c-format +msgid "no published releases for %s in the recipe catalogue?" +msgstr "TRANSLATE THIS FUCKING SHIT ALREADY" + +#: pkg/upstream/container/hijack.go:82 +#, c-format +msgid "unable to set IO streams as raw terminal: %s" +msgstr "" + +#: pkg/recipe/git.go:378 +#, c-format +msgid "git: opening repository in %s" +msgstr "" + +#: pkg/recipe/compose.go:171 pkg/recipe/compose.go:237 +#, c-format +msgid "updating %s to %s in %s" +msgstr "" + +#: pkg/formatter/formatter.go:80 +msgid "detected ABRA_CI=1" +msgstr "" + +#: cli/app/remove.go:136 cli/app/volume.go:179 +#, c-format +msgid "removing volumes failed: %s" +msgstr "" + +#: cli/app/logs.go:101 +msgid "since" +msgstr "" + +#: cli/app/backup.go:215 +msgid "Manage app backups" +msgstr "" + +#: cli/server/prune.go:18 +msgid "" +"Prunes unused containers, networks, and dangling images.\n" +"\n" +"Use \"--volumes/-v\" to remove volumes that are not associated with a " +"deployed\n" +"app. This can result in unwanted data loss if not used carefully." +msgstr "" + +#: pkg/upstream/container/hijack.go:100 +#, c-format +msgid "invalid detach escape keys, using default: %s" +msgstr "" + +#: pkg/recipe/git.go:50 +#, c-format +msgid "ensuring env version %s" +msgstr "" + +#: cli/app/run.go:110 cli/app/cmd.go:256 +msgid "user" +msgstr "" + +#: cli/app/config.go:18 +msgid "Edit app config" +msgstr "" + +#: cli/app/volume.go:77 +msgid "Remove volume(s) associated with an app" +msgstr "" + +#: cli/recipe/lint.go:15 +msgid "Lint a recipe" +msgstr "" + +#: cli/app/ps.go:180 cli/app/list.go:219 +msgid "STATUS" +msgstr "" + +#: cli/app/upgrade.go:392 cli/app/rollback.go:275 +#, c-format +msgid "'%s' is not a known version for %s" +msgstr "" + +#: cli/app/backup.go:298 +msgid "number of retry attempts" +msgstr "" + +#: cli/app/volume.go:47 +msgid "ON SERVER" +msgstr "" + +#: cli/app/secret.go:24 +msgid "generate [[secret] [version] | --all] [flags]" +msgstr "" + +#: cli/upgrade.go:19 +msgid "" +"Upgrade abra in-place with the latest stable or release candidate.\n" +"\n" +"By default, the latest stable release is downloaded.\n" +"\n" +"Use \"--rc/-r\" to install the latest release candidate. Please bear in mind " +"that\n" +"it may contain absolutely catastrophic deal-breaker bugs. Thank you very " +"much\n" +"for the testing efforts 💗" +msgstr "" + +#: cli/server/add.go:57 +msgid "missing argument or --local/-l flag" +msgstr "" + +#: cli/app/secret.go:484 cli/app/secret.go:524 cli/app/restart.go:162 +#: cli/app/app.go:10 cli/app/backup.go:240 +msgid "a" +msgstr "" + +#: cli/app/upgrade.go:32 +msgid "" +"Upgrade an app.\n" +"\n" +"Unlike \"abra app deploy\", chaos operations are not supported here. Only " +"recipe\n" +"versions are supported values for \"[version]\".\n" +"\n" +"It is possible to \"--force/-f\" an upgrade if you want to re-deploy a " +"specific\n" +"version.\n" +"\n" +"Only the deployed version is consulted when trying to determine what " +"upgrades\n" +"are available. The live deployment version is the \"source of truth\" in " +"this\n" +"case. The stored .env version is not consulted.\n" +"\n" +"An upgrade can be destructive, please ensure you have a copy of your app " +"data\n" +"beforehand. See \"abra app backup\" for more." +msgstr "" + +#: cli/app/upgrade.go:453 cli/app/rollback.go:342 cli/app/deploy.go:353 +msgid "disable converge logic checks" +msgstr "" + +#: cli/app/cp.go:197 +#, c-format +msgid "remote: %s does not exist" +msgstr "" + +#: cli/server/add.go:53 +msgid "cannot use [server] and --local together" +msgstr "" + +#: pkg/upstream/convert/volume.go:136 +msgid "tmpfs options are incompatible with type npipe" +msgstr "" + +#: pkg/ui/deploy.go:82 +#, c-format +msgid "{decoder: %v, " +msgstr "" + +#: pkg/dns/dns.go:14 +#, c-format +msgid "%s: unable to resolve IPv4 address: %s" +msgstr "" + +#: cli/app/ps.go:181 +msgid "IMAGE" +msgstr "" + +#: cli/app/run.go:24 +msgid "" +" # run with args/flags\n" +" abra app run 1312.net app -- ls -lha\n" +"\n" +" # run without args/flags\n" +" abra app run 1312.net app bash --user nobody\n" +"\n" +" # run with both kinds of args/flags \n" +" abra app run 1312.net app --user nobody -- ls -lha" +msgstr "" + +#: cli/app/remove.go:50 +#, c-format +msgid "ALERTA ALERTA: deleting %s data and config (local/remote)" +msgstr "" + +#: pkg/service/service.go:95 +#, c-format +msgid "no services matching the %v filter found?" +msgstr "" + +#: pkg/ui/deploy.go:86 +#, c-format +msgid "reader: %v, " +msgstr "" + +#: cli/app/secret.go:507 +msgid "trim" +msgstr "" + +#: cli/app/deploy.go:31 +msgid "" +"Deploy an app.\n" +"\n" +"This command supports chaos operations. Use \"--chaos/-C\" to deploy your " +"recipe\n" +"checkout as-is. Recipe commit hashes are also supported as values for\n" +"\"[version]\". Please note, \"upgrade\"/\"rollback\" do not support chaos " +"operations." +msgstr "" + +#: cli/app/deploy.go:107 +#, c-format +msgid "ensure recipe: %s" +msgstr "" + +#: cli/server/prune.go:93 +msgid "remove all unused images" +msgstr "" + +#: pkg/lint/recipe.go:76 +msgid "wire up healthchecks" +msgstr "" + +#: pkg/ui/deploy.go:84 +#, c-format +msgid "id: %s, " +msgstr "" + +#: cli/server/add.go:100 +#, c-format +msgid "unable to create local context: %s" +msgstr "" + +#: pkg/lint/recipe.go:82 +msgid "all images use a tag" +msgstr "" + +#: cli/app/secret.go:230 +#, c-format +msgid "%s successfully stored on server" +msgstr "" + +#: cli/app/secret.go:253 +#, c-format +msgid "deleted %s successfully from local pass store" +msgstr "" + +#: cli/app/list.go:216 +msgid "RECIPE" +msgstr "" + +#: cli/server/add.go:168 +#, c-format +msgid "creating context with domain %s" +msgstr "" + +#: pkg/recipe/git.go:160 +#, c-format +msgid "unable to resolve '%s': %s" +msgstr "" + +#: pkg/recipe/recipe.go:205 +#, c-format +msgid "compose: %s, " +msgstr "" + +#: cli/app/cmd.go:137 +#, c-format +msgid "%s does not exist locally, use /bin/sh as fallback" +msgstr "" + +#: cli/app/env.go:41 +msgid "ENV OVERVIEW" +msgstr "" + +#: cli/upgrade.go:26 +msgid " abra upgrade --rc" +msgstr "" + +#: pkg/lint/recipe.go:496 +#, c-format +msgid "unable to list local tags for %s" +msgstr "" + +#: pkg/recipe/git.go:410 +#, c-format +msgid "git checkout: %s in %s" +msgstr "" + +#: cli/app/cmd.go:131 cli/app/cmd.go:176 +msgid "did not detect any command arguments" +msgstr "" + +#: cli/app/rollback.go:120 +msgid "no available downgrades" +msgstr "" + +#: cli/app/restart.go:164 +msgid "restart all services" +msgstr "" + +#: cli/app/remove.go:139 +#, c-format +msgid "%d volume(s) removed successfully" +msgstr "" + +#: cli/app/backup.go:266 +msgid "volumes path" +msgstr "" + +#: cli/server/add.go:40 +msgid " abra server add 1312.net" +msgstr "" + +#: pkg/lint/recipe.go:110 +msgid "README.md metadata filled in" +msgstr "" + +#: pkg/git/clone.go:59 pkg/git/clone.go:78 pkg/git/clone.go:87 +#, c-format +msgid "git clone: %s cloned successfully" +msgstr "" + +#: cli/app/secret.go:106 cli/app/secret.go:394 cli/app/new.go:187 +#: cli/app/volume.go:47 +msgid "NAME" +msgstr "" + +#: cli/app/secret.go:210 +#, c-format +msgid "no secret %s available for recipe %s?" +msgstr "" + +#: cli/app/cmd.go:101 +msgid "cannot use --local & --user together" +msgstr "" + +#: cli/app/cmd.go:119 +#, c-format +msgid "--local detected, running %s on local work station" +msgstr "" + +#: cli/app/upgrade.go:318 +#, c-format +msgid "parsing chosen upgrade version failed: %s" +msgstr "" + +#: cli/app/restart.go:161 +msgid "all-services" +msgstr "" + +#: cli/run.go:90 +msgid "man [flags]" +msgstr "" + +#: pkg/lint/recipe.go:162 +msgid "all services have images" +msgstr "" + +#: cli/catalogue/catalogue.go:266 +msgid "skip updating recipe repositories" +msgstr "" + +#: cli/run.go:49 +#, c-format +msgid "unable to create %s: %s" +msgstr "" + +#: pkg/recipe/compose.go:123 +#, c-format +msgid "considering %s config(s) for tag update" +msgstr "" + +#: pkg/recipe/recipe.go:203 +#, c-format +msgid "git url: %s, " +msgstr "" + +#: pkg/formatter/formatter.go:134 +msgid "CreateOverview: only accepts rows of len == 2" +msgstr "" + +#: cli/app/labels.go:27 +msgid " abra app labels 1312.net" +msgstr "" + +#: pkg/lint/recipe.go:118 +msgid "upload your recipe to git.coopcloud.tech/coop-cloud/..." +msgstr "" + +#: pkg/secret/secret.go:130 +#, c-format +msgid "%s not enabled in recipe config, skipping" +msgstr "" + +#: cli/app/run.go:21 +msgid "run [[args] [flags] | [flags] -- [args]]" +msgstr "" + +#: cli/app/cmd.go:168 +#, c-format +msgid "no service %s for %s?" +msgstr "" + +#: cli/app/upgrade.go:266 cli/app/deploy.go:229 +#, c-format +msgid "run the following post-deploy commands: %s" +msgstr "" + +#: cli/app/new.go:374 +msgid "automatically generate secrets" +msgstr "" + +#: pkg/upstream/commandconn/commandconn.go:65 +#, c-format +msgid "commandconn (%s):" +msgstr "" + +#: cli/app/secret.go:499 +msgid "file" +msgstr "" + +#: cli/app/undeploy.go:88 +msgid "initialising undeploy" +msgstr "" + +#: pkg/lint/recipe.go:132 pkg/lint/recipe.go:139 pkg/lint/recipe.go:146 +#: pkg/lint/recipe.go:153 pkg/lint/recipe.go:161 pkg/lint/recipe.go:168 +#: pkg/lint/recipe.go:175 +msgid "error" +msgstr "" + +#: pkg/recipe/recipe.go:435 +#, c-format +msgid "detected versions %s for %s" +msgstr "" + +#: cli/app/upgrade.go:434 cli/app/rollback.go:323 cli/app/deploy.go:334 +#: cli/app/remove.go:155 cli/app/volume.go:198 +msgid "force" +msgstr "" + +#: cli/app/cp.go:273 +msgid "destination directory does not exist" +msgstr "" + +#: cli/app/backup.go:136 +msgid "Create a new snapshot" +msgstr "" + +#: cli/server/add.go:111 +#, c-format +msgid "%s successfully added" +msgstr "" + +#: pkg/lint/recipe.go:75 +msgid "healthcheck enabled for all services" +msgstr "" + +#: pkg/config/env.go:98 +#, c-format +msgid "directory is empty: %s" +msgstr "" + +#: pkg/config/abra.go:88 +msgid "using default abra dir" +msgstr "" + +#: pkg/recipe/files.go:36 +#, c-format +msgid "%s release notes:" +msgstr "" + +#: cli/app/new.go:24 +msgid "" +"Creates a new app from a default recipe.\n" +"\n" +"This new app configuration is stored in your $ABRA_DIR directory under the\n" +"appropriate server.\n" +"\n" +"This command does not deploy your app for you. You will need to run \"abra " +"app\n" +"deploy \" to do so.\n" +"\n" +"You can see what recipes are available (i.e. values for the [recipe] " +"argument)\n" +"by running \"abra recipe ls\".\n" +"\n" +"Recipe commit hashes are supported values for \"[version]\".\n" +"\n" +"Passing the \"--secrets/-S\" flag will automatically generate secrets for " +"your\n" +"app and store them encrypted at rest on the chosen target server. These\n" +"generated secrets are only visible at generation time, so please take care " +"to\n" +"store them somewhere safe.\n" +"\n" +"You can use the \"--pass/-P\" to store these generated passwords locally in " +"a\n" +"pass store (see passwordstore.org for more). The pass command must be " +"available\n" +"on your $PATH." +msgstr "" + +#: cli/catalogue/catalogue.go:187 +#, c-format +msgid "no changes discovered in %s, nothing to publish?" +msgstr "" + +#: cli/server/add.go:202 +msgid "use local server" +msgstr "" + +#: pkg/recipe/git.go:398 +#, c-format +msgid "processing %s for %s" +msgstr "" + +#: pkg/recipe/recipe.go:202 +#, c-format +msgid "dir: %s, " +msgstr "" + +#: pkg/git/init.go:65 +#, c-format +msgid "repo config: %s" +msgstr "" + +#: pkg/git/push.go:13 +#, c-format +msgid "dry run: no git changes pushed in %s" +msgstr "" + +#: pkg/formatter/formatter.go:238 +#, c-format +msgid "stripped %s to %s for parsing" +msgstr "" + +#: cli/app/restart.go:29 +msgid "" +" # restart a single app service\n" +" abra app restart 1312.net app\n" +"\n" +" # restart all app services\n" +" abra app restart 1312.net -a" +msgstr "" + +#: cli/app/deploy.go:36 +msgid "" +" # standard deployment\n" +" abra app deploy 1312.net\n" +"\n" +" # chaos deployment\n" +" abra app deploy 1312.net --chaos\n" +" \n" +" # deploy specific version\n" +" abra app deploy 1312.net 2.0.0+1.2.3\n" +"\n" +" # deploy a specific git hash\n" +" abra app deploy 1312.net 886db76d" +msgstr "" + +#: cli/app/list.go:46 +msgid "" +"Generate a report of all managed apps.\n" +"\n" +"Use \"--status/-S\" flag to query all servers for the live deployment status." +msgstr "" + +#: cli/app/list.go:148 +#, c-format +msgid "unable to clone %s: %s" +msgstr "" + +#: cli/catalogue/catalogue.go:234 +msgid "catalogue [cmd] [args] [flags]" +msgstr "" + +#: pkg/client/context.go:26 +#, c-format +msgid "created the %s context" +msgstr "" + +#: pkg/secret/pass.go:29 +#, c-format +msgid "%s inserted into pass store" +msgstr "" + +#: pkg/config/abra.go:26 +#, c-format +msgid "error reading config file: %s" +msgstr "" + +#: cli/app/upgrade.go:149 +msgid "unknown deployed version, unable to upgrade" +msgstr "" + +#: cli/app/backup.go:107 +#, c-format +msgid "including INCLUDE_PATH=%s in backupbot exec invocation" +msgstr "" + +#: cli/app/secret.go:526 +msgid "remove all secrets" +msgstr "" + +#: cli/catalogue/catalogue.go:175 +#, c-format +msgid "generated recipe catalogue: %s" +msgstr "" + +#: pkg/context/context.go:34 +msgid "context lacks Docker endpoint" +msgstr "" + +#: pkg/lint/recipe.go:163 +msgid "ensure \"image: ...\" set on all services" +msgstr "" + +#: pkg/recipe/compose.go:38 +#, c-format +msgid "COMPOSE_FILE detected, loading %s" +msgstr "" + +#: pkg/recipe/recipe.go:406 +#, c-format +msgid "read recipe catalogue from file system cache in %s" +msgstr "" + +#: cli/app/new.go:275 +msgid "no domain provided" +msgstr "" + +#: cli/app/secret.go:442 +msgid "secret [cmd] [args] [flags]" +msgstr "" + +#: cli/updater/updater.go:197 +#, c-format +msgid "can't separate key from value: %s (this variable is probably unset)" +msgstr "" + +#: pkg/lint/recipe.go:55 +#, c-format +msgid "skipping %s based on skip condition" +msgstr "" + +#: pkg/recipe/compose.go:59 +#, c-format +msgid "retrieved %s configs for %s" +msgstr "" + +#: pkg/git/commit.go:14 +msgid "no commit message specified?" +msgstr "" + +#: cli/app/cp.go:117 cli/app/cp.go:199 cli/app/cp.go:210 +#, c-format +msgid "remote path: %s" +msgstr "" + +#: pkg/lint/recipe.go:89 +msgid "no unstable tags" +msgstr "" + +#: pkg/lint/recipe.go:133 +msgid ".env.sample provided" +msgstr "" + +#: pkg/catalogue/catalogue.go:21 +msgid "catalogue is missing, retrieving now" +msgstr "" + +#: pkg/secret/secret.go:139 +#, c-format +msgid "secret %s is > %d chars when combined with %s" +msgstr "" + +#: pkg/recipe/recipe.go:175 +#, c-format +msgid "failed to check git status of %s: %s" +msgstr "" + +#: pkg/git/init.go:47 +#, c-format +msgid "git commit: %s" +msgstr "" + +#: cli/run.go:74 +#, c-format +msgid "unsupported --lang: %s (want: es)" +msgstr "" + +#: pkg/git/init.go:60 +#, c-format +msgid "set reference: %s" +msgstr "" + +#: cli/app/ps.go:56 cli/app/upgrade.go:423 cli/app/undeploy.go:59 +#: cli/app/services.go:49 cli/app/restart.go:93 cli/app/logs.go:58 +#: cli/updater/updater.go:247 +#, c-format +msgid "%s is not deployed?" +msgstr "" + +#: cli/app/volume.go:153 +#, c-format +msgid "volume %s removed successfully" +msgstr "" + +#: pkg/lint/recipe.go:212 +#, c-format +msgid "" +"recipe '%s' failed lint checks:\n" +"%s" +msgstr "" + +#: pkg/recipe/compose.go:29 +#, c-format +msgid "no COMPOSE_FILE detected, loading default: %s" +msgstr "" + +#: pkg/container/container.go:48 +msgid "ambiguous container list received, prompting for input" +msgstr "" + +#: cli/app/upgrade.go:274 cli/app/undeploy.go:107 cli/app/new.go:224 +#: cli/app/rollback.go:227 cli/app/deploy.go:236 +#, c-format +msgid "writing recipe version failed: %s" +msgstr "" + +#: cli/app/rollback.go:270 +#, c-format +msgid "current deployment '%s' is not a known version for %s" +msgstr "" + +#: pkg/service/service.go:103 pkg/container/container.go:40 +#, c-format +msgid "%s (created %v)" +msgstr "" + +#: cli/app/cmd.go:24 +msgid "Run app commands" +msgstr "" + +#: cli/app/cmd.go:171 +#, c-format +msgid "running command %s within the context of %s_%s" +msgstr "" + +#: cli/app/volume.go:192 +msgid "Manage app volumes" +msgstr "" + +#: cli/app/list.go:45 +msgid "List all managed apps" +msgstr "" + +#: cli/updater/updater.go:224 +#, c-format +msgid "no available upgrades for %s" +msgstr "" + +#: pkg/git/init.go:50 +#, c-format +msgid "init committed all files for new git repo in %s" +msgstr "" + +#: cli/app/new.go:366 +msgid "store secrets in a local pass store" +msgstr "" + +#: cli/app/rollback.go:280 cli/app/rollback.go:284 +#, c-format +msgid "%s is not a downgrade for %s?" +msgstr "" + +#: cli/server/remove.go:20 +msgid "" +"Remove a managed server.\n" +"\n" +"Abra will remove the internal bookkeeping ($ABRA_DIR/servers/...) and\n" +"underlying client connection context. This server will then be lost in " +"time,\n" +"like tears in rain." +msgstr "" + +#: pkg/recipe/git.go:241 +#, c-format +msgid "unable to read remotes in %s: %s" +msgstr "" + +#: pkg/recipe/recipe.go:549 +msgid "collecting recipe listing" +msgstr "" + +#: cli/app/backup.go:274 +msgid "include secrets" +msgstr "" + +#: cli/run.go:34 +msgid "upgrade" +msgstr "" + +#: cli/updater/updater.go:37 +msgid "Check for available upgrades" +msgstr "" + +#: cli/app/secret.go:467 cli/app/secret.go:491 cli/app/secret.go:531 +#: cli/app/new.go:363 +msgid "pass" +msgstr "" + +#: cli/app/rollback.go:42 +msgid "" +" # standard rollback\n" +" abra app rollback 1312.net\n" +"\n" +" # rollback to specific version\n" +" abra app rollback 1312.net 2.0.0+1.2.3" +msgstr "" + +#: cli/app/remove.go:53 +msgid "are you sure?" +msgstr "" + +#: cli/app/backup.go:134 +msgid "create [flags]" +msgstr "" + +#: pkg/upstream/convert/service.go:375 +#, c-format +msgid "undefined network %q" +msgstr "" + +#: pkg/git/add.go:22 +#, c-format +msgid "dry run: adding %s" +msgstr "" + +#: cli/run.go:159 +msgid "force select language (supported: XXX)" +msgstr "" + +#: cli/updater/updater.go:77 +msgid "" +"Upgrade an app by specifying stack name and recipe. \n" +"\n" +"Use \"--all\" to upgrade every deployed app.\n" +"\n" +"For each app with auto updates enabled, the deployed version is compared " +"with\n" +"the current recipe catalogue version. If a new patch/minor version is\n" +"available, the app is upgraded.\n" +"\n" +"To include major versions use the \"--major/-m\" flag. You probably don't " +"want\n" +"that as it will break things. Only apps that are not deployed with \"--" +"chaos/-C\"\n" +"are upgraded, to update chaos deployments use the \"--chaos/-C\" flag. Use " +"it\n" +"with care." +msgstr "" + +#: pkg/upstream/convert/service.go:43 +#, c-format +msgid "duplicate secret target for %s not allowed" +msgstr "" + +#: pkg/git/clone.go:68 +msgid "git clone: main branch failed, attempting master branch" +msgstr "" + +#: cli/app/upgrade.go:29 +msgid "upgrade [version] [flags]" +msgstr "" + +#: cli/app/remove.go:89 +#, c-format +msgid "removing configs failed: %s" +msgstr "" + +#: cli/run.go:150 +msgid "ignore .env version checkout" +msgstr "" + +#: pkg/git/clone.go:49 +#, c-format +msgid "git clone: %s" +msgstr "" + +#: cli/server/remove.go:19 +msgid "Remove a managed server" +msgstr "" + +#: pkg/upstream/container/hijack.go:43 +#, c-format +msgid "unable to setup input stream: %s" +msgstr "" + +#: pkg/recipe/compose.go:191 +#, c-format +msgid "considering %s config(s) for label update" +msgstr "" + +#: pkg/container/container.go:52 +msgid "which container are you looking for?" +msgstr "" + +#: cli/app/secret.go:460 cli/app/secret.go:556 cli/app/ps.go:199 +#: cli/app/list.go:312 +msgid "m" +msgstr "" + +#: cli/app/run.go:23 +msgid "Run a command inside a service container" +msgstr "" + +#: cli/app/run.go:102 +msgid "no-tty" +msgstr "" + +#: cli/app/remove.go:119 +msgid "no secrets to remove" +msgstr "" + +#: cli/server/add.go:86 +msgid "local server already exists" +msgstr "" + +#: pkg/lint/recipe.go:134 +msgid "create an example .env.sample" +msgstr "" + +#: cli/app/secret.go:444 +msgid "Manage app secrets" +msgstr "" + +#: cli/app/services.go:22 +msgid "sr" +msgstr "" + +#: cli/app/backup.go:178 +msgid "snapshots [flags]" +msgstr "" + +#: cli/server/add.go:76 cli/server/add.go:103 +#, c-format +msgid "attempting to create client for %s" +msgstr "" + +#: pkg/client/configs.go:35 +#, c-format +msgid "conf %s: %s" +msgstr "" + +#: pkg/recipe/recipe.go:130 +#, c-format +msgid "version seems invalid: %s" +msgstr "" + +#: pkg/web/web.go:45 +#, c-format +msgid "bad status: %s" +msgstr "" + +#: cli/run.go:109 +#, c-format +msgid "unable to proceed, %s does not exist?" +msgstr "" + +#: cli/app/restore.go:99 +msgid "target" +msgstr "" + +#: cli/app/remove.go:92 +#, c-format +msgid "%d config(s) removed successfully" +msgstr "" + +#: cli/server/remove.go:43 +#, c-format +msgid "%s is now lost in time, like tears in rain" +msgstr "" + +#: cli/recipe/lint.go:14 +msgid "lint [flags]" +msgstr "" + +#: pkg/recipe/compose.go:243 +#, c-format +msgid "synced label %s to service %s" +msgstr "" + +#: cli/app/cmd.go:51 +msgid "accepts at most 2 args with --local/-l" +msgstr "" + +#: cli/app/cmd.go:198 +msgid "List all available commands" +msgstr "" + +#: cli/catalogue/catalogue.go:223 +#, c-format +msgid "new changes published: %s" +msgstr "" + +#: cli/updater/updater.go:251 +#, c-format +msgid "failed to determine deployed version of %s" +msgstr "" + +#: pkg/client/volumes.go:63 +#, c-format +msgid "%d retries failed" +msgstr "" + +#: pkg/lint/recipe.go:140 +msgid "one service named 'app'" +msgstr "" + +#: pkg/envfile/envfile.go:82 +#, c-format +msgid "read 0 env var exports from %s" +msgstr "" + +#: pkg/config/abra.go:77 +msgid "read abra dir from $ABRA_DIR" +msgstr "" + +#: cli/app/secret.go:38 cli/app/secret.go:170 cli/app/secret.go:280 +#: cli/app/upgrade.go:58 cli/app/rollback.go:58 cli/app/deploy.go:59 +#: cli/app/logs.go:32 pkg/autocomplete/autocomplete.go:17 +#: pkg/autocomplete/autocomplete.go:32 pkg/autocomplete/autocomplete.go:43 +#: pkg/autocomplete/autocomplete.go:59 pkg/autocomplete/autocomplete.go:77 +#: pkg/autocomplete/autocomplete.go:93 pkg/autocomplete/autocomplete.go:99 +#: pkg/autocomplete/autocomplete.go:114 +#, c-format +msgid "autocomplete failed: %s" +msgstr "" + +#: cli/app/secret.go:136 +msgid "NOT" +msgstr "" + +#: cli/app/secret.go:437 +#, c-format +msgid "no secrets stored for %s" +msgstr "" + +#: cli/app/cmd.go:267 +msgid "disable remote TTY" +msgstr "" + +#: cli/app/new.go:207 +msgid "SECRETS OVERVIEW" +msgstr "" + +#: cli/app/logs.go:93 +msgid "stderr" +msgstr "" + +#: cli/server/add.go:21 +msgid "add [[server] | --local] [flags]" +msgstr "" + +#: pkg/lint/recipe.go:117 +msgid "git.coopcloud.tech repo exists" +msgstr "" + +#: cli/app/volume.go:191 +msgid "vl" +msgstr "" + +#: pkg/client/volumes.go:59 +#, c-format +msgid "%s: waiting %d seconds before next retry" +msgstr "" + +#: pkg/service/service.go:30 +msgid "no services deployed?" +msgstr "" + +#: pkg/lint/recipe.go:125 +msgid "reduce length of secret names to 12 chars" +msgstr "" + +#: pkg/lint/recipe.go:215 +#, c-format +msgid "linting successful, %s is well configured" +msgstr "" + +#: pkg/upstream/convert/service.go:122 +#, c-format +msgid "duplicate config target for %s not allowed" +msgstr "" + +#: pkg/upstream/convert/volume.go:44 +msgid "tmpfs options are incompatible with type volume" +msgstr "" + +#: pkg/config/env.go:37 +#, c-format +msgid "retrieved %v servers: %s" +msgstr "" + +#: cli/app/restart.go:23 +msgid "Restart an app" +msgstr "" + +#: cli/app/restart.go:64 +msgid "missing [service]" +msgstr "" + +#: cli/app/secret.go:75 +#, c-format +msgid "%s doesn't exist in the env config?" +msgstr "" + +#: cli/app/upgrade.go:31 +msgid "Upgrade an app" +msgstr "" + +#: cli/app/undeploy.go:135 cli/server/prune.go:52 +#, c-format +msgid "networks pruned: %d" +msgstr "" + +#: cli/updater/updater.go:239 +#, c-format +msgid "retrieve deployed version whether %s is already deployed" +msgstr "" + +#: pkg/recipe/git.go:191 +#, c-format +msgid "%s (%s) has locally unstaged changes?" +msgstr "" + +#: pkg/recipe/recipe.go:138 +#, c-format +msgid "removed dirty suffix from .env version: %s -> %s" +msgstr "" + +#: cli/app/ps.go:165 +#, c-format +msgid "unable to convert to JSON: %s" +msgstr "" + +#: cli/app/upgrade.go:437 cli/app/rollback.go:326 cli/app/deploy.go:337 +#: cli/app/remove.go:158 cli/app/volume.go:201 +msgid "perform action without further prompt" +msgstr "" + +#: cli/app/upgrade.go:451 cli/app/rollback.go:340 cli/app/deploy.go:351 +#: cli/app/cp.go:30 cli/app/backup.go:135 +msgid "c" +msgstr "" + +#: cli/app/restart.go:21 +msgid "restart [[service] | --all-services] [flags]" +msgstr "" + +#: pkg/lint/recipe.go:21 pkg/lint/recipe.go:67 pkg/lint/recipe.go:74 +#: pkg/lint/recipe.go:81 pkg/lint/recipe.go:88 pkg/lint/recipe.go:95 +#: pkg/lint/recipe.go:102 pkg/lint/recipe.go:109 pkg/lint/recipe.go:116 +#: pkg/lint/recipe.go:123 +msgid "warn" +msgstr "" + +#: pkg/config/abra.go:20 +msgid "no config file found" +msgstr "" + +#: pkg/git/branch.go:99 +#, c-format +msgid "successfully checked out %v in %s" +msgstr "" + +#: cli/app/upgrade.go:415 cli/app/undeploy.go:51 cli/app/deploy.go:88 +#, c-format +msgid "checking whether %s is already deployed" +msgstr "" + +#: cli/app/restart.go:144 +#, c-format +msgid "%s service successfully restarted" +msgstr "" + +#: cli/app/config.go:16 +msgid "config [flags]" +msgstr "" + +#: cli/app/backup.go:54 +#, c-format +msgid "including TIMESTAMPS=%v in backupbot exec invocation" +msgstr "" + +#: pkg/lint/recipe.go:170 +msgid "vendor config versions in an abra.sh" +msgstr "" + +#: pkg/upstream/convert/service.go:153 pkg/upstream/convert/service.go:168 +#, c-format +msgid "config not found: %s" +msgstr "" + +#: pkg/ui/deploy.go:85 +#, c-format +msgid "name: %s, " +msgstr "" + +#: pkg/recipe/recipe.go:325 +#, c-format +msgid "%s: image meta has incorrect format: %s" +msgstr "" + +#: cli/app/secret.go:470 cli/app/secret.go:494 +msgid "store generated secrets in a local pass store" +msgstr "" + +#: cli/app/secret.go:534 +msgid "remove generated secrets from a local pass store" +msgstr "" + +#: cli/app/backup.go:231 cli/app/backup.go:255 +msgid "snapshot" +msgstr "" + +#: cli/updater/updater.go:176 +#, c-format +msgid "boolean label %s could not be found for %s, set default to false." +msgstr "" + +#: pkg/catalogue/catalogue.go:84 pkg/recipe/git.go:278 +#, c-format +msgid "fetched latest git changes for %s" +msgstr "" + +#: pkg/upstream/convert/volume.go:162 +msgid "volume type must be volume, bind, tmpfs or npipe" +msgstr "" + +#: pkg/recipe/compose.go:47 +#, c-format +msgid "COMPOSE_FILE (=\"%s\") parsing failed?" +msgstr "" + +#: pkg/git/branch.go:68 +#, c-format +msgid "failed to select default branch in %s" +msgstr "" + +#: cli/app/ps.go:183 cli/app/list.go:220 +msgid "CHAOS" +msgstr "" + +#: cli/app/new.go:48 +msgid "n" +msgstr "" + +#: cli/app/backup.go:282 +msgid "include volumes" +msgstr "" + +#: cli/app/list.go:49 +msgid "" +" # list apps of all servers without live status\n" +" abra app ls\n" +"\n" +" # list apps of a specific server with live status\n" +" abra app ls -s 1312.net -S\n" +"\n" +" # list apps of all servers which match a specific recipe\n" +" abra app ls -r gitea" +msgstr "" + +#: cli/complete.go:11 +msgid "autocomplete [bash|zsh|fish|powershell]" +msgstr "" + +#: pkg/client/client.go:100 +msgid "swarm mode not enabled on local server?" +msgstr "" + +#: pkg/logs/logs.go:86 +#, c-format +msgid "tailLogs: unable to copy buffer: %s" +msgstr "" + +#: pkg/config/abra.go:37 +#, c-format +msgid "config file loaded from: %s" +msgstr "" + +#: cli/app/secret.go:307 +msgid "cannot use [secret] and --all/-a together" +msgstr "" + +#: cli/app/secret.go:508 cli/app/restore.go:100 cli/app/run.go:103 +#: cli/app/backup.go:248 +msgid "t" +msgstr "" + +#: cli/app/backup.go:112 +#, c-format +msgid "including SECRETS=%v in backupbot exec invocation" +msgstr "" + +#: cli/updater/updater.go:38 +msgid "" +"Notify on new versions for deployed apps.\n" +"\n" +"If a new patch/minor version is available, a notification is printed.\n" +"\n" +"Use \"--major/-m\" to include new major versions." +msgstr "" + +#: pkg/upstream/convert/volume.go:96 +msgid "tmpfs options are incompatible with type bind" +msgstr "" + +#: pkg/git/commit.go:42 +msgid "git changes commited" +msgstr "" + +#: cli/app/run.go:111 cli/app/cmd.go:257 +msgid "u" +msgstr "" + +#: cli/app/undeploy.go:24 +msgid "Undeploy an app" +msgstr "" + +#: cli/app/list.go:216 +msgid "SERVER" +msgstr "" + +#: pkg/client/client.go:97 +#, c-format +msgid "swarm mode not enabled on %s?" +msgstr "" + +#: cli/app/secret.go:486 +msgid "generate all secrets" +msgstr "" + +#: cli/app/deploy.go:180 +msgid "skipping domain checks" +msgstr "" + +#: cli/app/config.go:17 +msgid "cfg" +msgstr "" + +#: cli/server/prune.go:15 +msgid "prune [flags]" +msgstr "" + +#: pkg/recipe/compose.go:107 +#, c-format +msgid "%s has no version label? try running \"abra recipe sync %s\" first?" +msgstr "" + +#: cli/app/cmd.go:128 cli/app/cmd.go:174 +#, c-format +msgid "parsed following command arguments: %s" +msgstr "" + +#: cli/app/upgrade.go:450 cli/app/rollback.go:339 cli/app/deploy.go:350 +msgid "no-converge-checks" +msgstr "" + +#: pkg/lint/recipe.go:169 +msgid "config version are vendored" +msgstr "" + +#: pkg/ui/deploy.go:330 +msgid "succeeded" +msgstr "" + +#: pkg/git/read.go:149 +#, c-format +msgid "read global ignore paths: %s" +msgstr "" + +#: cli/app/secret.go:372 +msgid "list " +msgstr "" + +#: cli/app/undeploy.go:25 +msgid "" +"This does not destroy any application data.\n" +"\n" +"However, you should remain vigilant, as your swarm installation will " +"consider\n" +"any previously attached volumes as eligible for pruning once undeployed.\n" +"\n" +"Passing \"--prune/-p\" does not remove those volumes." +msgstr "" + +#: cli/app/new.go:236 +#, c-format +msgid "trimming %s to %s to avoid runtime limits" +msgstr "" + +#: cli/app/env.go:16 +msgid "e" +msgstr "" + +#: cli/app/backup.go:213 +msgid "backup [cmd] [args] [flags]" +msgstr "" + +#: pkg/secret/secret.go:62 pkg/secret/secret.go:80 +#, c-format +msgid "generated %s" +msgstr "" + +#: pkg/upstream/commandconn/commandconn.go:172 +#, c-format +msgid "" +"command %v has exited with %v, please make sure the URL is valid, and Docker " +"18.09 or later is installed on the remote host: stderr=%s" +msgstr "" + +#: pkg/git/read.go:130 +#, c-format +msgid "no %s exists, skipping reading gitignore paths" +msgstr "" + +#: cli/app/secret.go:26 +msgid "Generate secrets" +msgstr "" + +#: cli/app/restore.go:17 +msgid "rs" +msgstr "" + +#: cli/run.go:117 +msgid "don't forget to run 'sudo mandb'" +msgstr "" + +#: pkg/service/service.go:77 pkg/service/service.go:131 +msgid "failed to match chosen service" +msgstr "" + +#: pkg/recipe/recipe.go:237 +#, c-format +msgid "%s: attempt recipe metadata parse" +msgstr "" + +#: cli/app/restore.go:124 +msgid "H" +msgstr "" + +#: cli/app/cmd.go:25 +msgid "" +"Run an app specific command.\n" +"\n" +"These commands are bash functions, defined in the abra.sh of the recipe " +"itself.\n" +"They can be run within the context of a service (e.g. app) or locally on " +"your\n" +"work station by passing \"--local/-l\".\n" +"\n" +"N.B. If using the \"--\" style to pass arguments, flags (e.g. \"--local/-" +"l\") must\n" +"be passed *before* the \"--\". It is possible to pass arguments without the " +"\"--\"\n" +"as long as no dashes are present (i.e. \"foo\" works without \"--\", \"-" +"foo\"\n" +"does not)." +msgstr "" + +#: cli/app/upgrade.go:402 cli/app/upgrade.go:406 +#, c-format +msgid "%s is not an upgrade for %s?" +msgstr "" + +#: cli/app/env.go:17 +msgid "Show app .env values" +msgstr "" + +#: cli/app/remove.go:22 +msgid "" +"Remove everything related to an app which is already undeployed.\n" +"\n" +"By default, it will prompt for confirmation before proceeding. All secrets,\n" +"volumes and the local app env file will be deleted.\n" +"\n" +"Only run this command when you are sure you want to completely remove the " +"app\n" +"and all associated app data. This is a destructive action, Be Careful!\n" +"\n" +"If you would like to delete specific volumes or secrets, please use removal\n" +"sub-commands under \"app volume\" and \"app secret\" instead.\n" +"\n" +"Please note, if you delete the local app env file without removing volumes " +"and\n" +"secrets first, Abra will *not* be able to help you remove them afterwards.\n" +"\n" +"To delete everything without prompt, use the \"--force/-f\" or the \"--no-" +"input/n\"\n" +"flag." +msgstr "" + +#: cli/updater/updater.go:202 +#, c-format +msgid "for %s read env %s with value: %s from docker service" +msgstr "" + +#: pkg/lint/recipe.go:491 pkg/recipe/git.go:236 pkg/git/read.go:26 +#, c-format +msgid "unable to open %s: %s" +msgstr "" + +#: pkg/git/remote.go:15 +#, c-format +msgid "dry run: remote %s (%s) not created" +msgstr "" + +#: cli/app/ps.go:119 cli/app/ps.go:120 cli/app/ps.go:121 cli/app/ps.go:122 +#: cli/app/ps.go:123 cli/app/list.go:111 cli/app/list.go:112 +#: cli/app/list.go:113 cli/app/list.go:114 cli/app/list.go:115 +#: cli/app/list.go:175 cli/app/labels.go:71 +msgid "unknown" +msgstr "" + +#: cli/app/services.go:23 +msgid "Display all services of an app" +msgstr "" + +#: cli/app/cp.go:31 +msgid "Copy files to/from a deployed app service" +msgstr "" + +#: pkg/recipe/compose.go:72 +#, c-format +msgid "%s is missing a compose.yml or compose.*.yml file?" +msgstr "" + +#: cli/server/add.go:120 pkg/secret/secret.go:223 pkg/secret/secret.go:243 +#: pkg/server/server.go:21 +#, c-format +msgid "%s already exists" +msgstr "" + +#: cli/app/restore.go:62 +#, c-format +msgid "including NONINTERACTIVE=%v in backupbot exec invocation" +msgstr "" + +#: cli/app/restore.go:107 +msgid "services" +msgstr "" + +#: cli/app/restore.go:16 +msgid "restore [flags]" +msgstr "" + +#: cli/app/backup.go:214 +msgid "b" +msgstr "" + +#: pkg/service/service.go:53 pkg/service/service.go:107 +#, c-format +msgid "expected 1 service but found %v: %s" +msgstr "" + +#: pkg/lint/recipe.go:69 +msgid "ensure 'version: \"3.8\"' in compose configs" +msgstr "" + +#: pkg/ssh/ssh.go:24 +#, c-format +msgid "unable to connect to %s, please check your SSH config" +msgstr "" + +#: cli/app/restore.go:79 +#, c-format +msgid "including NO_COMMANDS=%v in backupbot exec invocation" +msgstr "" + +#: cli/app/undeploy.go:23 +msgid "un" +msgstr "" + +#: cli/app/rollback.go:243 +#, c-format +msgid "please select a downgrade (version: %s, chaos: %s):" +msgstr "" + +#: cli/app/deploy.go:303 +#, c-format +msgid "version: can not redeploy chaos version %s" +msgstr "" + +#: cli/app/deploy.go:305 +#, c-format +msgid "version: taking version from .env file: %s" +msgstr "" + +#: cli/app/logs.go:18 +msgid "logs [service] [flags]" +msgstr "" + +#: pkg/lint/recipe.go:103 +msgid "has published catalogue version" +msgstr "" + +#: pkg/ui/deploy.go:87 +#, c-format +msgid "writer: %v, " +msgstr "" + +#: cli/app/secret.go:262 +msgid "Remove a secret" +msgstr "" + +#: cli/app/app.go:9 +msgid "app [cmd] [args] [flags]" +msgstr "" + +#: cli/run.go:25 +msgid "The Co-op Cloud command-line utility belt 🎩🐇" +msgstr "" + +#: pkg/ssh/ssh.go:26 +msgid "docker: is the daemon running / your user has docker permissions?" +msgstr "" + +#: pkg/envfile/envfile.go:73 +#, c-format +msgid "couldn't parse %s" +msgstr "" + +#: pkg/config/abra.go:81 +msgid "read abra dir from config file" +msgstr "" + +#: pkg/recipe/git.go:256 +#, c-format +msgid "unable to check out default branch in %s: %s" +msgstr "" + +#: pkg/recipe/recipe.go:204 +#, c-format +msgid "ssh url: %s, " +msgstr "" + +#: cli/app/restore.go:123 +msgid "hooks" +msgstr "" + +#: cli/app/cmd.go:248 +msgid "local" +msgstr "" + +#: cli/catalogue/catalogue.go:26 +msgid "Generate the recipe catalogue" +msgstr "TRANSLATE THIS FUCKING SHIT ALREADY" + +#: pkg/lint/recipe.go:22 +msgid "critical" +msgstr "" + +#: pkg/upstream/convert/service.go:774 +msgid "replicas can only be used with replicated mode" +msgstr "" + +#: pkg/container/container.go:44 +#, c-format +msgid "expected 1 container but found %v: %s" +msgstr "" + +#: cli/app/secret.go:53 +msgid "missing arguments [secret]/[version] or '--all'" +msgstr "" + +#: cli/app/secret.go:311 +msgid "no secret(s) specified?" +msgstr "" + +#: cli/app/ps.go:28 +msgid "ps [flags]" +msgstr "" + +#: cli/app/deploy.go:177 +msgid "skipping domain checks, no DOMAIN=... configured" +msgstr "" + +#: cli/app/backup.go:65 +msgid "download [flags]" +msgstr "" + +#: cli/app/backup.go:295 +msgid "retries" +msgstr "" + +#: cli/app/volume.go:88 +msgid "" +" # delete volumes interactively\n" +" abra app volume rm 1312.net\n" +"\n" +" # delete specific volume\n" +" abra app volume rm 1312.net my_volume" +msgstr "" + +#: cli/app/volume.go:162 +msgid "" +"'x' indicates selected, enter / return to confirm, ctrl-c to exit, vim mode " +"is enabled" +msgstr "" + +#: cli/app/undeploy.go:143 cli/server/prune.go:66 +#, c-format +msgid "images pruned: %d; space reclaimed: %s" +msgstr "" + +#: cli/catalogue/catalogue.go:27 +msgid "" +"Generate a new copy of the recipe catalogue.\n" +"\n" +"N.B. this command **will** wipe local unstaged changes from your local " +"recipes\n" +"if present. \"--chaos/-C\" on this command refers to the catalogue " +"repository\n" +"(\"$ABRA_DIR/catalogue\") and not the recipes. Please take care not to lose " +"your\n" +"changes.\n" +"\n" +"It is possible to generate new metadata for a single recipe by passing\n" +"[recipe]. The existing local catalogue will be updated, not overwritten.\n" +"\n" +"It is quite easy to get rate limited by Docker Hub when running this " +"command.\n" +"If you have a Hub account you can \"docker login\" and Abra will " +"automatically\n" +"use those details.\n" +"\n" +"Push your new release to git.coopcloud.tech with \"--publish/-p\". This " +"requires\n" +"that you have permission to git push to these repositories and have your " +"SSH\n" +"keys configured on your account." +msgstr "" + +#: cli/app/labels.go:26 +msgid "Both local recipe and live deployment labels are shown." +msgstr "" + +#: cli/catalogue/catalogue.go:89 +msgid "collecting catalogue metadata" +msgstr "" + +#: pkg/secret/secret.go:126 +#, c-format +msgid "missing version for secret? (%s)" +msgstr "" + +#: pkg/secret/secret.go:268 +#, c-format +msgid "generated and stored %v on %s" +msgstr "" + +#: pkg/recipe/git.go:367 +#, c-format +msgid "detected %s as tags for recipe %s" +msgstr "" + +#: pkg/recipe/recipe.go:200 +#, c-format +msgid "version : %s, " +msgstr "" + +#: cli/app/ps.go:179 +msgid "SERVICE" +msgstr "" + +#: cli/app/upgrade.go:127 +msgid "no available upgrades" +msgstr "" + +#: cli/app/upgrade.go:397 +#, c-format +msgid "'%s' is not a known version" +msgstr "" + +#: cli/app/volume.go:182 +#, c-format +msgid "%d volumes removed successfully" +msgstr "" + +#: cli/app/list.go:291 +msgid "show app deployment status" +msgstr "" + +#: cli/run.go:28 +msgid "app" +msgstr "" + +#: pkg/lint/recipe.go:141 +msgid "name a servce 'app'" +msgstr "" + +#: pkg/lint/recipe.go:176 +msgid "only annotated tags used for recipe version" +msgstr "" + +#: cli/app/backup.go:167 +#, c-format +msgid "including RETRIES=%s in backupbot exec invocation" +msgstr "" + +#: cli/app/list.go:43 cli/server/list.go:18 +msgid "list [flags]" +msgstr "" + +#: cli/server/prune.go:75 +#, c-format +msgid "volumes pruned: %d; space reclaimed: %s" +msgstr "" + +#: cli/server/add.go:24 +msgid "" +"Add a new server to your configuration so that it can be managed by Abra.\n" +"\n" +"Abra relies on the standard SSH command-line and ~/.ssh/config for client\n" +"connection details. You must configure an entry per-host in your ~/.ssh/" +"config\n" +"for each server:\n" +"\n" +" Host 1312.net 1312\n" +" Hostname 1312.net\n" +" User antifa\n" +" Port 12345\n" +" IdentityFile ~/.ssh/antifa@somewhere\n" +"\n" +"If \"--local\" is passed, then Abra assumes that the current local server " +"is\n" +"intended as the target server. This is useful when you want to have your " +"entire\n" +"Co-op Cloud config located on the server itself, and not on your local\n" +"developer machine. The domain is then set to \"default\"." +msgstr "" + +#: pkg/lint/recipe.go:104 +msgid "publish a recipe version to the catalogue" +msgstr "" + +#: pkg/lint/recipe.go:147 +msgid "deploy labels stanza present" +msgstr "" + +#: pkg/upstream/convert/volume.go:47 +msgid "bind options are incompatible with type volume" +msgstr "" + +#: pkg/envfile/envfile.go:42 pkg/envfile/envfile.go:80 pkg/config/env.go:50 +#, c-format +msgid "read %s from %s" +msgstr "" + +#: cli/app/cmd.go:35 +msgid "" +" # pass args/flags without \"--\"\n" +" abra app cmd 1312.net app my_cmd_arg foo --user bar\n" +"\n" +" # pass args/flags with \"--\"\n" +" abra app cmd 1312.net app my_cmd_args --user bar -- foo -vvv\n" +"\n" +" # drop the [service] arg if using \"--local/-l\"\n" +" abra app cmd 1312.net my_cmd --local" +msgstr "" + +#: cli/app/upgrade.go:152 +#, c-format +msgid "choosing %s as version to upgrade" +msgstr "" + +#: pkg/lint/recipe.go:83 +msgid "use a tag for all images" +msgstr "" + +#: pkg/config/abra.go:34 +#, c-format +msgid "error loading config file: %s" +msgstr "" + +#: pkg/recipe/compose.go:229 +#, c-format +msgid "coop-cloud.${STACK_NAME}.version=%s" +msgstr "" + +#: pkg/git/commit.go:44 +msgid "dry run: no changes commited" +msgstr "" + +#: pkg/git/clone.go:64 pkg/git/clone.go:102 +#, c-format +msgid "git clone %s: cancelled due to interrupt" +msgstr "" + +#: cli/app/secret.go:476 cli/app/secret.go:516 cli/app/secret.go:540 +#: cli/app/secret.go:548 cli/app/restore.go:132 cli/app/ps.go:207 +#: cli/app/cmd.go:273 cli/app/new.go:380 cli/app/check.go:88 +#: cli/app/restart.go:155 cli/app/deploy.go:327 cli/app/cp.go:379 +#: cli/app/backup.go:288 cli/app/backup.go:304 cli/app/labels.go:136 +msgid "C" +msgstr "" + +#: cli/app/cmd.go:264 +msgid "tty" +msgstr "" + +#: cli/app/deploy.go:316 +#, c-format +msgid "version: taking new recipe version: %s" +msgstr "" + +#: cli/app/remove.go:38 +msgid " abra app remove 1312.net" +msgstr "" + +#: cli/app/volume.go:76 +msgid "remove [volume] [flags]" +msgstr "" + +#: cli/run.go:126 +msgid "show debug messages" +msgstr "" + +#: cli/updater/updater.go:103 +msgid "missing arguments or --all/-a flag" +msgstr "" + +#: pkg/upstream/container/exec.go:108 +msgid "Error monitoring TTY size:" +msgstr "" + +#: cli/app/secret.go:137 +msgid "NOW" +msgstr "" + +#: cli/app/deploy.go:276 +#, c-format +msgid "secret not generated: %s" +msgstr "" + +#: cli/run.go:24 +msgid "abra [cmd] [args] [flags]" +msgstr "" + +#: pkg/upstream/commandconn/commandconn.go:255 +#, c-format +msgid "unimplemented call: SetDeadline(%v)" +msgstr "" + +#: pkg/upstream/convert/volume.go:110 +msgid "invalid tmpfs source, source must be empty" +msgstr "" + +#: pkg/git/push.go:31 +msgid "git changes pushed" +msgstr "" + +#: cli/app/restore.go:19 +msgid "" +"Snapshots are restored while apps are deployed.\n" +"\n" +"Some restore scenarios may require service / app restarts." +msgstr "" + +#: cli/app/restore.go:57 +#, c-format +msgid "including TARGET=%s in backupbot exec invocation" +msgstr "" + +#: cli/app/services.go:67 +msgid "SERVICE (LONG)" +msgstr "" + +#: cli/app/restart.go:24 +msgid "" +"This command restarts services within a deployed app.\n" +"\n" +"Run \"abra app ps \" to see a list of service names.\n" +"\n" +"Pass \"--all-services/-a\" to restart all services." +msgstr "" + +#: cli/app/env.go:18 +msgid " abra app env 1312.net" +msgstr "" + +#: cli/app/volume.go:150 +#, c-format +msgid "removing volume %s failed: %s" +msgstr "" + +#: pkg/upstream/commandconn/commandconn.go:259 +#, c-format +msgid "unimplemented call: SetReadDeadline(%v)" +msgstr "" + +#: pkg/recipe/recipe.go:659 +msgid "retrieving recipes" +msgstr "" + +#: cli/app/restore.go:115 cli/app/backup.go:279 +msgid "volumes" +msgstr "" + +#: cli/app/rollback.go:238 +#, c-format +msgid "please select a downgrade (version: %s):" +msgstr "" + +#: cli/app/backup.go:247 +msgid "timestamps" +msgstr "" + +#: pkg/lint/recipe.go:187 +#, c-format +msgid "linting for critical errors in %s configs" +msgstr "" + +#: pkg/upstream/container/tty.go:39 +#, c-format +msgid "error resize: %s" +msgstr "" + +#: pkg/recipe/recipe.go:74 +#, c-format +msgid "choosing %s as latest version of %s" +msgstr "" + +#: pkg/git/read.go:88 +#, c-format +msgid "no %s exists, not reading any global gitignore config" +msgstr "" + +#: pkg/git/init.go:24 +#, c-format +msgid "initialised new git repo in %s" +msgstr "" + +#: cli/app/backup.go:68 +msgid "" +"Downloads a backup.tar.gz to the current working directory.\n" +"\n" +"\"--volumes/-v\" includes data contained in volumes alongide paths specified " +"in\n" +"\"backupbot.backup.path\" labels." +msgstr "" + +#: cli/server/prune.go:101 +msgid "remove volumes" +msgstr "" + +#: cli/server/add.go:84 +msgid "local server successfully added" +msgstr "" + +#: pkg/ssh/ssh.go:16 +#, c-format +msgid "SSH host key verification failed for %s" +msgstr "" + +#: pkg/upstream/container/hijack.go:167 +#, c-format +msgid "error sendStdin: %s" +msgstr "" + +#: pkg/upstream/convert/service.go:815 +#, c-format +msgid "invalid credential spec: cannot specify both %s, and %s" +msgstr "" diff --git a/pkg/i18n/locales/es/LC_MESSAGES/default.po~ b/pkg/i18n/locales/es/LC_MESSAGES/default.po~ new file mode 100644 index 00000000..e344f6e2 --- /dev/null +++ b/pkg/i18n/locales/es/LC_MESSAGES/default.po~ @@ -0,0 +1,3726 @@ +msgid "" +msgstr "Project-Id-Version: \n" + "Report-Msgid-Bugs-To: EMAIL\n" + "POT-Creation-Date: 2025-08-23 14:02+0200\n" + "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" + "Last-Translator: FULL NAME \n" + "Language-Team: LANGUAGE \n" + "Language: \n" + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" + +#: pkg/dns/dns.go:52 +#, c-format +msgid "app domain %s (%s) does not appear to resolve to app server %s (%s)?" +msgstr "" + +#: cli/app/new.go:324 +msgid "no server provided" +msgstr "" + +#: cli/app/backup.go:49 +#, c-format +msgid "including SHOW_ALL=%v in backupbot exec invocation" +msgstr "" + +#: cli/upgrade.go:55 +msgid "install release candidate (may contain bugs)" +msgstr "" + +#: pkg/server/server.go:25 +#, c-format +msgid "successfully created %s" +msgstr "" + +#: cli/app/restore.go:118 +msgid "restore specific volumes" +msgstr "" + +#: cli/app/services.go:67 +msgid "SERVICE (SHORT)" +msgstr "" + +#: cli/app/restart.go:68 +msgid "cannot use [service] and --all-services/-a together" +msgstr "" + +#: cli/app/volume.go:190 +msgid "volume [cmd] [args] [flags]" +msgstr "" + +#: cli/app/secret.go:374 +msgid "List all secrets" +msgstr "" + +#: cli/app/new.go:266 +msgid "Specify app domain" +msgstr "" + +#: cli/app/check.go:17 +msgid "check [flags]" +msgstr "" + +#: cli/app/cp.go:85 +msgid "one of / arguments must take $SERVICE:$PATH form" +msgstr "" + +#: cli/upgrade.go:16 +msgid "upgrade [flags]" +msgstr "" + +#: pkg/recipe/git.go:262 +#, c-format +msgid "unable to fetch tags in %s: %s" +msgstr "" + +#: pkg/recipe/recipe.go:458 +#, c-format +msgid "recipe %s does not exist?" +msgstr "" + +#: cli/app/list.go:288 +msgid "status" +msgstr "" + +#: pkg/secret/secret.go:207 +#, c-format +msgid "skipping generation of %s (generate=false)" +msgstr "" + +#: pkg/recipe/recipe.go:207 +#, c-format +msgid "sample env: %s, " +msgstr "" + +#: cli/app/volume.go:78 +msgid "" +"Remove volumes associated with an app.\n" +"\n" +"The app in question must be undeployed before you try to remove volumes. " +"See\n" +"\"abra app undeploy \" for more.\n" +"\n" +"The command is interactive and will show a multiple select input which " +"allows\n" +"you to make a seclection. Use the \"?\" key to see more help on navigating " +"this\n" +"interface.\n" +"\n" +"Passing \"--force/-f\" will select all volumes for removal. Be careful." +msgstr "" + +#: pkg/recipe/git.go:187 +#, c-format +msgid "unable to check git clean status in %s: %s" +msgstr "" + +#: pkg/recipe/recipe.go:330 +#, c-format +msgid "%s: image meta is empty?" +msgstr "" + +#: cli/app/rollback.go:28 +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" +"versions are supported values for \"[version]\".\n" +"\n" +"It is possible to \"--force/-f\" an downgrade if you want to re-deploy a " +"specific\n" +"version.\n" +"\n" +"Only the deployed version is consulted when trying to determine what " +"downgrades\n" +"are available. The live deployment version is the \"source of truth\" in " +"this\n" +"case. The stored .env version is not consulted.\n" +"\n" +"A downgrade can be destructive, please ensure you have a copy of your app " +"data\n" +"beforehand. See \"abra app backup\" for more." +msgstr "" + +#: cli/app/secret.go:373 cli/app/cmd.go:197 cli/app/backup.go:16 +#: cli/app/volume.go:20 cli/app/list.go:44 +msgid "ls" +msgstr "" + +#: cli/app/secret.go:459 cli/app/secret.go:555 cli/app/ps.go:198 +#: cli/app/list.go:311 +msgid "machine" +msgstr "" + +#: cli/app/volume.go:21 +msgid "List volumes associated with an app" +msgstr "" + +#: cli/app/list.go:153 +#, c-format +msgid "unable to retrieve tags for %s: %s" +msgstr "" + +#: cli/app/list.go:177 +msgid "latest" +msgstr "" + +#: cli/app/list.go:296 cli/app/list.go:303 cli/run.go:32 +msgid "recipe" +msgstr "" + +#: cli/upgrade.go:18 +msgid "Upgrade abra" +msgstr "" + +#: cli/app/undeploy.go:155 +msgid "prune" +msgstr "" + +#: cli/app/deploy.go:28 +msgid "deploy [version] [flags]" +msgstr "" + +#: cli/app/cp.go:72 +#, c-format +msgid "retrieved %s as target container on %s" +msgstr "" + +#: cli/app/remove.go:73 cli/app/volume.go:120 +#, c-format +msgid "%s is still deployed. Run \"abra app undeploy %s\"" +msgstr "" + +#: cli/server/add.go:137 +#, c-format +msgid "serverAdd: cleanUp: unable to list files in %s: %s" +msgstr "" + +#: pkg/upstream/container/hijack.go:156 +msgid "[hijack] End of stdin" +msgstr "" + +#: pkg/upstream/convert/service.go:462 +#, c-format +msgid "undefined config %q" +msgstr "" + +#: pkg/recipe/git.go:52 +#, c-format +msgid "can not redeploy chaos version (%s) without --chaos" +msgstr "" + +#: cli/app/secret.go:260 +msgid "remove [[secret] | --all] [flags]" +msgstr "" + +#: cli/app/new.go:315 +msgid "Select app server:" +msgstr "" + +#: cli/app/cp.go:245 +#, c-format +msgid "copy: %s" +msgstr "" + +#: cli/app/logs.go:20 +msgid "Tail app logs" +msgstr "" + +#: cli/app/backup.go:263 +msgid "path" +msgstr "" + +#: cli/app/list.go:216 +msgid "DOMAIN" +msgstr "" + +#: pkg/client/context.go:66 +msgid "context 'default' cannot be removed" +msgstr "" + +#: pkg/dns/dns.go:18 +#, c-format +msgid "%s: no IPv4 available" +msgstr "" + +#: pkg/ssh/ssh.go:20 +#, c-format +msgid "connection timed out for %s" +msgstr "" + +#: pkg/recipe/git.go:225 pkg/recipe/git.go:406 pkg/git/branch.go:95 +#, c-format +msgid "failed to check out %s in %s" +msgstr "" + +#: pkg/recipe/recipe.go:199 +#, c-format +msgid "{name: %s, " +msgstr "" + +#: pkg/recipe/recipe.go:208 +#, c-format +msgid "abra.sh: %s}" +msgstr "" + +#: pkg/git/read.go:31 +#, c-format +msgid "unable to open worktree of %s: %s" +msgstr "" + +#: pkg/container/container.go:69 +msgid "failed to match chosen container" +msgstr "" + +#: cli/app/backup.go:242 +msgid "show all paths" +msgstr "" + +#: cli/catalogue/catalogue.go:191 +msgid "chore: publish new catalogue release changes" +msgstr "" + +#: cli/upgrade.go:37 pkg/secret/pass.go:23 pkg/secret/pass.go:45 +#, c-format +msgid "attempting to run %s" +msgstr "" + +#: pkg/upstream/convert/service.go:652 +#, c-format +msgid "unknown restart policy: %s" +msgstr "" + +#: cli/app/secret.go:468 cli/app/secret.go:492 cli/app/secret.go:532 +#: cli/app/ps.go:29 cli/app/undeploy.go:156 cli/app/new.go:364 +#: cli/app/backup.go:264 +msgid "p" +msgstr "" + +#: cli/app/cmd.go:67 +msgid "requires at least 3 arguments" +msgstr "" + +#: cli/app/upgrade.go:323 +#, c-format +msgid "parsing deployment version failed: %s" +msgstr "" + +#: cli/app/cp.go:164 +#, c-format +msgid "copy %s from local to %s on container" +msgstr "" + +#: cli/app/config.go:36 +#, c-format +msgid "cannot find app with name %s" +msgstr "" + +#: cli/run.go:134 +msgid "toggle non-interactive mode" +msgstr "" + +#: pkg/upstream/convert/service.go:813 +#, c-format +msgid "invalid credential spec: cannot specify both %s and %s" +msgstr "" + +#: cli/app/secret.go:478 cli/app/secret.go:518 cli/app/secret.go:542 +#: cli/app/secret.go:550 cli/app/restore.go:134 cli/app/ps.go:209 +#: cli/app/cmd.go:275 cli/app/new.go:382 cli/app/check.go:90 +#: cli/app/restart.go:157 cli/app/deploy.go:329 cli/app/cp.go:381 +#: cli/app/backup.go:290 cli/app/backup.go:306 cli/app/labels.go:138 +#: cli/catalogue/catalogue.go:274 +msgid "ignore uncommitted recipes changes" +msgstr "" + +#: cli/app/new.go:343 +msgid "specify server for new app" +msgstr "" + +#: cli/app/logs.go:96 +msgid "only tail stderr" +msgstr "" + +#: cli/app/logs.go:104 +msgid "tail logs since YYYY-MM-DDTHH:MM:SSZ" +msgstr "" + +#: pkg/lint/recipe.go:68 +msgid "compose config has expected version" +msgstr "" + +#: pkg/recipe/git.go:434 +#, c-format +msgid "%s service is missing image tag?" +msgstr "" + +#: pkg/recipe/recipe.go:462 +#, c-format +msgid "recipe metadata retrieved for %s" +msgstr "" + +#: cli/app/secret.go:145 +msgid "Insert secret" +msgstr "" + +#: cli/app/new.go:355 +msgid "domain" +msgstr "" + +#: cli/app/list.go:299 +msgid "show apps of a specific recipe" +msgstr "" + +#: cli/run.go:31 +msgid "man" +msgstr "" + +#: cli/server/prune.go:17 +msgid "Prune resources on a server" +msgstr "" + +#: cli/server/add.go:141 +#, c-format +msgid "serverAdd: cleanUp: %s is not empty, aborting cleanup" +msgstr "" + +#: pkg/upstream/convert/volume.go:90 +msgid "invalid bind source, source cannot be empty" +msgstr "" + +#: pkg/recipe/git.go:151 +#, c-format +msgid "read %s as tags for recipe %s" +msgstr "" + +#: cli/app/secret.go:144 +msgid "i" +msgstr "" + +#: cli/app/check.go:19 +msgid "Ensure an app is well configured" +msgstr "" + +#: cli/app/deploy.go:29 cli/app/backup.go:66 +msgid "d" +msgstr "" + +#: cli/app/deploy.go:101 +#, c-format +msgid "get deploy version: %s" +msgstr "" + +#: cli/app/remove.go:19 +msgid "remove [flags]" +msgstr "" + +#: cli/app/backup.go:17 +msgid "List the contents of a snapshot" +msgstr "" + +#: cli/complete.go:13 +msgid "" +"To load completions:\n" +"\n" +"Bash:\n" +" # Load autocompletion for the current Bash session\n" +" $ source <(abra autocomplete bash)\n" +"\n" +" # To load autocompletion for each session, execute once:\n" +" # Linux:\n" +" $ abra autocomplete bash | sudo tee /etc/bash_completion.d/abra\n" +" # macOS:\n" +" $ abra autocomplete bash | sudo tee $(brew --prefix)/etc/bash_completion.d/" +"abra\n" +"\n" +"Zsh:\n" +" # If shell autocompletion is not already enabled in your environment,\n" +" # you will need to enable it. You can execute the following once:\n" +"\n" +" $ echo \"autoload -U compinit; compinit\" >> ~/.zshrc\n" +"\n" +" # To load autocompletions for each session, execute once:\n" +" $ abra autocomplete zsh > \"${fpath[1]}/_abra\"\n" +"\n" +" # You will need to start a new shell for this setup to take effect.\n" +"\n" +"fish:\n" +" $ abra autocomplete fish | source\n" +"\n" +" # To load autocompletions for each session, execute once:\n" +" $ abra autocomplete fish > ~/.config/fish/completions/abra.fish\n" +"\n" +"PowerShell:\n" +" PS> abra autocomplete powershell | Out-String | Invoke-Expression\n" +"\n" +" # To load autocompletions for every new session, run:\n" +" PS> abra autocomplete powershell > abra.ps1\n" +" # and source this file from your PowerShell profile." +msgstr "" + +#: pkg/recipe/git.go:251 +#, c-format +msgid "unable to open git work tree in %s: %s" +msgstr "" + +#: cli/app/secret.go:102 +msgid "no secrets generated" +msgstr "" + +#: cli/app/upgrade.go:329 cli/app/upgrade.go:368 +#, c-format +msgid "parsing recipe version failed: %s" +msgstr "" + +#: cli/app/upgrade.go:443 cli/app/new.go:356 cli/app/rollback.go:332 +#: cli/app/deploy.go:343 +msgid "D" +msgstr "" + +#: pkg/lint/recipe.go:90 +msgid "tag all images with stable tags" +msgstr "" + +#: pkg/lint/recipe.go:154 +msgid "traefik routing enabled" +msgstr "" + +#: pkg/upstream/commandconn/connection.go:38 +msgid "ssh host connection is not valid" +msgstr "" + +#: pkg/git/init.go:73 +msgid "set 'main' as the default branch" +msgstr "" + +#: cli/app/secret.go:394 cli/app/ps.go:182 cli/app/list.go:221 +msgid "VERSION" +msgstr "" + +#: cli/app/secret.go:462 cli/app/secret.go:558 cli/app/ps.go:201 +#: cli/app/list.go:314 cli/server/list.go:102 +msgid "print machine-readable output" +msgstr "" + +#: cli/app/secret.go:475 cli/app/secret.go:515 cli/app/secret.go:539 +#: cli/app/secret.go:547 cli/app/restore.go:131 cli/app/ps.go:206 +#: cli/app/cmd.go:272 cli/app/new.go:379 cli/app/check.go:87 +#: cli/app/restart.go:154 cli/app/deploy.go:326 cli/app/cp.go:378 +#: cli/app/backup.go:287 cli/app/backup.go:303 cli/app/labels.go:135 +msgid "chaos" +msgstr "" + +#: cli/app/upgrade.go:445 cli/app/rollback.go:334 cli/app/deploy.go:345 +msgid "disable public DNS checks" +msgstr "" + +#: cli/run.go:78 +#, c-format +msgid "abra version: %s, commit: %s, lang: %s" +msgstr "" + +#: pkg/catalogue/catalogue.go:40 +#, c-format +msgid "" +"%s has locally unstaged changes? please commit/remove your changes before " +"proceeding" +msgstr "" + +#: pkg/upstream/commandconn/commandconn.go:141 +msgid "commandconn: failed to wait" +msgstr "" + +#: pkg/upstream/convert/service.go:780 +#, c-format +msgid "unknown mode: %s" +msgstr "" + +#: cli/app/upgrade.go:290 +#, c-format +msgid "please select an upgrade (version: %s, chaos: %s):" +msgstr "" + +#: pkg/service/service.go:41 +#, c-format +msgid "no services deployed matching label '%s'?" +msgstr "" + +#: pkg/lint/recipe.go:97 +msgid "use semver-like tags" +msgstr "" + +#: pkg/upstream/container/hijack.go:135 +#, c-format +msgid "error receiveStdout: %s" +msgstr "" + +#: pkg/ui/deploy.go:341 +#, c-format +msgid "%s: %s (retries: %v, healthcheck: %s)" +msgstr "" + +#: pkg/config/env.go:74 pkg/config/env.go:107 +#, c-format +msgid "broken symlink in your abra config folders: %s" +msgstr "" + +#: pkg/git/common.go:13 +#, c-format +msgid "no .git directory in %s?" +msgstr "" + +#: pkg/git/init.go:70 +#, c-format +msgid "repo set config: %s" +msgstr "" + +#: cli/app/cmd.go:22 +msgid "" +"command [service | --local] [[args] [flags] | [flags] -- " +"[args]]" +msgstr "" + +#: cli/app/run.go:22 cli/app/upgrade.go:459 cli/app/backup.go:296 +#: cli/app/list.go:297 +msgid "r" +msgstr "" + +#: cli/app/upgrade.go:442 cli/app/rollback.go:331 cli/app/deploy.go:342 +msgid "no-domain-checks" +msgstr "" + +#: cli/app/deploy.go:296 +#, c-format +msgid "version: taking version from cli arg: %s" +msgstr "" + +#: cli/catalogue/catalogue.go:258 +msgid "report changes that would be made" +msgstr "" + +#: cli/server/add.go:107 +#, c-format +msgid "ssh %s error: %s" +msgstr "" + +#: pkg/client/client.go:44 +#, c-format +msgid "unknown server, run \"abra server add %s\"?" +msgstr "" + +#: pkg/lint/recipe.go:52 +#, c-format +msgid "%s: skip condition: %s" +msgstr "" + +#: cli/app/new.go:358 +msgid "domain name for app" +msgstr "" + +#: cli/app/secret.go:366 +msgid "no secrets to remove?" +msgstr "" + +#: cli/app/secret.go:394 +msgid "CREATED ON SERVER" +msgstr "" + +#: pkg/client/client.go:88 +#, c-format +msgid "created client for %s" +msgstr "" + +#: pkg/lint/recipe.go:96 +msgid "tags use semver-like format" +msgstr "" + +#: cli/app/secret.go:134 +#, c-format +msgid "generated secrets %s shown again, please take note of them %s" +msgstr "" + +#: cli/app/cmd.go:108 +#, c-format +msgid "%s does not exist for %s?" +msgstr "" + +#: cli/app/env.go:15 +msgid "env [flags]" +msgstr "" + +#: cli/app/list.go:322 +msgid "show apps of a specific server" +msgstr "" + +#: cli/app/labels.go:53 +msgid "DEPLOYED LABELS" +msgstr "" + +#: cli/app/restore.go:18 +msgid "Restore a snapshot" +msgstr "" + +#: cli/app/restart.go:108 +#, c-format +msgid "attempting to scale %s to 0" +msgstr "" + +#: cli/app/remove.go:94 +msgid "no configs to remove" +msgstr "" + +#: pkg/ssh/ssh.go:22 +#, c-format +msgid "ssh auth: permission denied for %s" +msgstr "" + +#: pkg/secret/pass.go:51 +#, c-format +msgid "%s removed from pass store" +msgstr "" + +#: pkg/upstream/convert/volume.go:116 +msgid "volume options are incompatible with type tmpfs" +msgstr "" + +#: pkg/recipe/compose.go:58 +#, c-format +msgid "COMPOSE_FILE detected (%s), loading %s" +msgstr "" + +#: pkg/recipe/recipe.go:361 +#, c-format +msgid "%s: marker string %s not found" +msgstr "" + +#: cli/app/upgrade.go:458 +msgid "releasenotes" +msgstr "" + +#: cli/app/undeploy.go:128 cli/server/prune.go:45 +#, c-format +msgid "containers pruned: %d; space reclaimed: %s" +msgstr "" + +#: cli/app/cp.go:253 +#, c-format +msgid "untar: %s" +msgstr "" + +#: cli/app/labels.go:102 +msgid "LABELS OVERVIEW" +msgstr "" + +#: cli/server/list.go:20 +msgid "List managed servers" +msgstr "" + +#: pkg/upstream/commandconn/commandconn.go:162 +#, c-format +msgid "command %v did not exit after %v: stderr=%q" +msgstr "" + +#: pkg/recipe/compose.go:248 +msgid "no existing label found, automagic insertion not supported yet" +msgstr "" + +#: cli/app/new.go:309 +#, c-format +msgid "single server detected, choosing %s automatically" +msgstr "" + +#: cli/app/remove.go:141 +msgid "no volumes to remove" +msgstr "" + +#: cli/app/backup.go:234 cli/app/backup.go:258 +msgid "list specific snapshot" +msgstr "" + +#: cli/app/volume.go:145 +#, c-format +msgid "unable to remove volume: no volume with name '%s'?" +msgstr "" + +#: pkg/recipe/compose.go:159 +#, c-format +msgid "parsed %s from %s" +msgstr "" + +#: cli/app/secret.go:261 cli/app/remove.go:20 cli/app/volume.go:93 +msgid "rm" +msgstr "" + +#: cli/app/cmd.go:251 +msgid "run command locally" +msgstr "" + +#: cli/app/new.go:135 +#, c-format +msgid "%s sanitised as %s for new app" +msgstr "" + +#: cli/app/volume.go:184 +msgid "no volumes removed" +msgstr "" + +#: pkg/upstream/convert/service.go:414 +#, c-format +msgid "undefined secret %q" +msgstr "" + +#: cli/app/secret.go:267 +msgid " abra app secret rm 1312.net oauth_key" +msgstr "" + +#: cli/app/cp.go:145 cli/app/cp.go:184 +#, c-format +msgid "create remote directory: %s" +msgstr "" + +#: pkg/formatter/formatter.go:46 +msgid " ago" +msgstr "" + +#: cli/app/upgrade.go:30 +msgid "up" +msgstr "" + +#: pkg/lint/recipe.go:111 +msgid "fill out all the metadata" +msgstr "" + +#: pkg/git/init.go:21 +#, c-format +msgid "git branch rename: %s" +msgstr "" + +#: pkg/git/init.go:29 +#, c-format +msgid "git open: %s" +msgstr "" + +#: cli/app/secret.go:124 cli/app/secret.go:424 cli/server/list.go:82 +#, c-format +msgid "unable to render to JSON: %s" +msgstr "" + +#: cli/app/restore.go:74 +#, c-format +msgid "including CONTAINER=%s in backupbot exec invocation" +msgstr "" + +#: cli/app/run.go:105 +msgid "do not request a TTY" +msgstr "" + +#: cli/app/new.go:118 +#, c-format +msgid "failed to retrieve latest commit for %s: %s" +msgstr "" + +#: cli/app/remove.go:148 +#, c-format +msgid "file: %s removed" +msgstr "" + +#: cli/app/backup.go:250 +msgid "include timestamps" +msgstr "" + +#: pkg/upstream/convert/volume.go:56 +#, c-format +msgid "undefined volume %q" +msgstr "" + +#: cli/app/restore.go:110 +msgid "restore specific services" +msgstr "" + +#: cli/app/restore.go:126 +msgid "enable pre/post-hook command execution" +msgstr "" + +#: cli/app/restart.go:22 +msgid "re" +msgstr "" + +#: cli/app/labels.go:74 +msgid "RECIPE LABELS" +msgstr "" + +#: pkg/upstream/container/exec.go:43 +msgid "exec ID empty" +msgstr "" + +#: pkg/recipe/git.go:178 +#, c-format +msgid "successfully checked %s out to %s in %s" +msgstr "" + +#: pkg/git/init.go:38 +#, c-format +msgid "git add: %s" +msgstr "" + +#: cli/app/new.go:340 cli/app/new.go:347 cli/app/list.go:319 +#: cli/app/list.go:326 cli/run.go:33 +msgid "server" +msgstr "" + +#: cli/app/app.go:11 +msgid "Manage apps" +msgstr "" + +#: pkg/secret/secret.go:119 +msgid "not generating app secrets, none enabled in recipe config" +msgstr "" + +#: pkg/upstream/convert/service.go:834 +#, c-format +msgid "" +"invalid credential spec: spec specifies config %v, but no such config can be " +"found" +msgstr "" + +#: cli/run.go:29 +msgid "autocomplete" +msgstr "" + +#: cli/app/run.go:113 +msgid "run command as user" +msgstr "" + +#: cli/app/volume.go:161 +msgid "which volumes do you want to remove?" +msgstr "" + +#: cli/updater/updater.go:231 +#, c-format +msgid "%s (%s) can be upgraded from version %s to %s" +msgstr "" + +#: cli/app/upgrade.go:208 cli/app/deploy.go:166 +#, c-format +msgid "%s missing from %s.env" +msgstr "" + +#: cli/app/list.go:222 +msgid "UPGRADE" +msgstr "" + +#: cli/app/list.go:223 +msgid "AUTOUPDATE" +msgstr "" + +#: cli/app/labels.go:25 +msgid "Show deployment labels" +msgstr "" + +#: cli/updater/updater.go:76 +msgid "Upgrade apps" +msgstr "" + +#: pkg/recipe/compose.go:249 +#, c-format +msgid "add '- \"%s\"' manually to the 'app' service in %s" +msgstr "" + +#: cli/app/secret.go:483 cli/app/secret.go:523 cli/app/backup.go:239 +msgid "all" +msgstr "" + +#: cli/app/backup.go:117 +#, c-format +msgid "including VOLUMES=%v in backupbot exec invocation" +msgstr "" + +#: cli/server/remove.go:17 +msgid "remove [flags]" +msgstr "" + +#: pkg/client/registry.go:20 +#, c-format +msgid "failed to parse image %s, saw: %s" +msgstr "" + +#: pkg/secret/pass.go:15 pkg/secret/pass.go:37 +msgid "pass command not found on $PATH, is it installed?" +msgstr "" + +#: pkg/git/read.go:45 +#, c-format +msgid "unable to query status of %s: %s" +msgstr "" + +#: cli/app/upgrade.go:269 cli/app/deploy.go:231 +#, c-format +msgid "attempting to run post deploy commands, saw: %s" +msgstr "" + +#: cli/app/rollback.go:26 +msgid "rl" +msgstr "" + +#: cli/app/cp.go:32 +msgid "" +" # copy myfile.txt to the root of the app service\n" +" abra app cp 1312.net myfile.txt app:/\n" +"\n" +" # copy that file back to your current working directory locally\n" +" abra app cp 1312.net app:/myfile.txt ./" +msgstr "" + +#: cli/app/config.go:19 +msgid " abra config 1312.net" +msgstr "" + +#: cli/run.go:93 +msgid "" +" # generate the man pages into /usr/local/share/man/man1\n" +" abra_path=$(which abra) # pass abra absolute path to sudo below\n" +" sudo $abra_path man\n" +" sudo mandb\n" +"\n" +" # read the man pages\n" +" man abra\n" +" man abra-app-deploy" +msgstr "" + +#: pkg/ssh/ssh.go:18 +#, c-format +msgid "could not resolve hostname for %s" +msgstr "" + +#: pkg/ui/deploy.go:333 +msgid "rolled back" +msgstr "" + +#: pkg/recipe/git.go:458 +#, c-format +msgid "collected %s for %s" +msgstr "" + +#: cli/app/secret.go:57 +msgid "cannot use '[secret] [version]' and '--all' together" +msgstr "" + +#: cli/app/cmd.go:196 cli/app/backup.go:15 cli/app/volume.go:19 +msgid "list [flags]" +msgstr "" + +#: cli/app/rollback.go:145 +#, c-format +msgid "choosing %s as version to rollback" +msgstr "" + +#: cli/server/add.go:23 +msgid "Add a new server" +msgstr "" + +#: cli/app/secret.go:106 cli/app/new.go:187 +msgid "VALUE" +msgstr "" + +#: cli/app/secret.go:500 cli/app/upgrade.go:435 cli/app/rollback.go:324 +#: cli/app/deploy.go:335 cli/app/remove.go:156 cli/app/volume.go:199 +msgid "f" +msgstr "" + +#: cli/app/cmd.go:259 +msgid "request remote user" +msgstr "" + +#: cli/app/upgrade.go:285 +#, c-format +msgid "please select an upgrade (version: %s):" +msgstr "" + +#: cli/app/new.go:70 cli/app/deploy.go:262 +msgid "cannot use [version] and --chaos together" +msgstr "" + +#: cli/app/remove.go:116 +#, c-format +msgid "secret: %s removed" +msgstr "" + +#: cli/complete.go:12 +msgid "Generate autocompletion script" +msgstr "" + +#: pkg/recipe/recipe.go:368 +#, c-format +msgid "%s: end marker %s not found" +msgstr "" + +#: pkg/recipe/recipe.go:555 +#, c-format +msgid "fetching repo metadata from %s" +msgstr "" + +#: cli/app/secret.go:216 +#, c-format +msgid "reading secret from file: %s" +msgstr "" + +#: cli/app/secret.go:246 +#, c-format +msgid "deleted %s successfully from server" +msgstr "" + +#: cli/app/new.go:290 +msgid "Generate app secrets?" +msgstr "" + +#: pkg/upstream/convert/service.go:604 +msgid "test and disable can't be set at the same time" +msgstr "" + +#: pkg/recipe/recipe.go:201 +#, c-format +msgid "dirty: %v, " +msgstr "" + +#: cli/app/services.go:21 +msgid "services [flags]" +msgstr "" + +#: pkg/lint/recipe.go:148 +msgid "include \"deploy: labels: ...\" stanza" +msgstr "" + +#: pkg/lint/recipe.go:177 +msgid "replace lightweight tag with annotated tag" +msgstr "" + +#: pkg/upstream/container/hijack.go:172 +#, c-format +msgid "couldn't send EOF: %s" +msgstr "" + +#: pkg/git/clone.go:89 +#, c-format +msgid "git clone: %s already exists" +msgstr "" + +#: cli/app/restore.go:102 +msgid "target path" +msgstr "" + +#: cli/app/new.go:47 +msgid "new [recipe] [version] [flags]" +msgstr "" + +#: cli/app/new.go:49 +msgid "Create a new app" +msgstr "" + +#: cli/app/remove.go:59 +msgid "aborting as requested" +msgstr "" + +#: cli/app/volume.go:71 +#, c-format +msgid "no volumes created for %s" +msgstr "" + +#: cli/catalogue/catalogue.go:250 +msgid "publish changes to git.coopcloud.tech" +msgstr "" + +#: cli/run.go:92 +msgid "Generate manpage" +msgstr "" + +#: cli/server/prune.go:56 +msgid "removing all images, not only dangling ones" +msgstr "" + +#: cli/app/secret.go:143 +msgid "insert [flags]" +msgstr "" + +#: cli/app/undeploy.go:158 +msgid "prune unused containers, networks, and dangling images" +msgstr "" + +#: pkg/upstream/commandconn/commandconn.go:49 +#, c-format +msgid "commandconn: starting %s with %v" +msgstr "" + +#: cli/app/secret.go:263 +msgid "" +"This command removes a secret from an app environment.\n" +"\n" +"Arbitrary secret removal is not supported. Secrets that are removed must\n" +"match those configured in the recipe beforehand." +msgstr "" + +#: cli/app/cmd.go:265 +msgid "T" +msgstr "" + +#: cli/app/check.go:20 +msgid "" +"Compare env vars in both the app \".env\" and recipe \".env.sample\" file.\n" +"\n" +"The goal is to ensure that recipe \".env.sample\" env vars are defined in " +"your\n" +"app \".env\" file. Only env var definitions in the \".env.sample\" which " +"are\n" +"uncommented, e.g. \"FOO=bar\" are checked. If an app \".env\" file does not " +"include\n" +"these env vars, then \"check\" will complain.\n" +"\n" +"Recipe maintainers may or may not provide defaults for env vars within " +"their\n" +"recipes regardless of commenting or not (e.g. through the use of\n" +"${FOO:} syntax). \"check\" does not confirm or deny this for you." +msgstr "" + +#: cli/server/add.go:128 +#, c-format +msgid "serverAdd: cleanUp: cleaning up context for %s" +msgstr "" + +#: cli/app/undeploy.go:104 +msgid "undeploy succeeded " +msgstr "" + +#: cli/app/deploy.go:290 +#, c-format +msgid "version: taking chaos version: %s" +msgstr "" + +#: cli/app/deploy.go:311 +#, c-format +msgid "version: taking deployed version: %s" +msgstr "" + +#: cli/app/labels.go:23 +msgid "labels [flags]" +msgstr "" + +#: cli/updater/updater.go:35 +msgid "notify [flags]" +msgstr "" + +#: pkg/upstream/container/exec.go:113 +#, c-format +msgid "Error hijack: %s" +msgstr "" + +#: pkg/recipe/git.go:274 +#, c-format +msgid "unable to git pull in %s: %s" +msgstr "" + +#: pkg/git/diff.go:30 +msgid "unable to locate git command, cannot output diff" +msgstr "" + +#: cli/catalogue/catalogue.go:227 +msgid "dry run: no changes published" +msgstr "" + +#: cli/updater/updater.go:155 +#, c-format +msgid "no %s label found for %s" +msgstr "" + +#: pkg/lint/recipe.go:504 +msgid "invalid lightweight tag detected" +msgstr "" + +#: cli/app/secret.go:510 +msgid "trim input" +msgstr "" + +#: cli/app/restore.go:68 +#, c-format +msgid "including VOLUMES=%s in backupbot exec invocation" +msgstr "" + +#: cli/app/upgrade.go:362 +#, c-format +msgid "parsing deployed version failed: %s" +msgstr "" + +#: cli/app/cp.go:272 +msgid "can't copy dir to file" +msgstr "" + +#: pkg/upstream/convert/volume.go:113 +msgid "bind options are incompatible with type tmpfs" +msgstr "" + +#: pkg/recipe/compose.go:233 +#, c-format +msgid "%s is already set, nothing to do?" +msgstr "" + +#: cli/app/restart.go:132 +#, c-format +msgid "%s has been scaled to 0" +msgstr "" + +#: cli/app/remove.go:21 +msgid "Remove all app data, locally and remotely" +msgstr "" + +#: pkg/lint/recipe.go:203 +#, c-format +msgid "" +"\n" +"lint %s: %s" +msgstr "" + +#: pkg/git/clone.go:100 +#, c-format +msgid "unable to clean up git clone of %s: %s" +msgstr "" + +#: cli/app/restore.go:52 cli/app/backup.go:44 cli/app/backup.go:102 +#, c-format +msgid "including SNAPSHOT=%s in backupbot exec invocation" +msgstr "" + +#: cli/app/new.go:211 +#, c-format +msgid "secrets are %s shown again, please save them %s" +msgstr "" + +#: pkg/dns/dns.go:38 pkg/dns/dns.go:47 +#, c-format +msgid "cannot resolve ipv4 for %s?" +msgstr "" + +#: pkg/recipe/git.go:156 +#, c-format +msgid "attempting to checkout '%s' as chaos commit" +msgstr "" + +#: pkg/recipe/recipe.go:147 +#, c-format +msgid "invalid recipe: %s" +msgstr "" + +#: cli/app/ps.go:30 +msgid "Check app deployment status" +msgstr "" + +#: cli/app/new.go:372 cli/app/logs.go:102 cli/app/backup.go:272 +#: cli/app/list.go:289 +msgid "S" +msgstr "" + +#: cli/app/backup.go:180 +msgid "List all snapshots" +msgstr "" + +#: cli/server/add.go:163 +#, c-format +msgid "context for %s already exists" +msgstr "" + +#: cli/server/add.go:184 +#, c-format +msgid "server dir for %s already created" +msgstr "" + +#: pkg/lint/recipe.go:124 +msgid "long secret names" +msgstr "" + +#: pkg/catalogue/catalogue.go:59 pkg/recipe/git.go:245 +#, c-format +msgid "cannot ensure %s is up-to-date, no git remotes configured" +msgstr "" + +#: pkg/secret/secret.go:212 +#, c-format +msgid "attempting to generate and store %s on %s" +msgstr "" + +#: cli/app/deploy.go:96 +#, c-format +msgid "%s is already deployed" +msgstr "" + +#: cli/catalogue/catalogue.go:24 +msgid "generate [recipe] [flags]" +msgstr "" + +#: cli/server/add.go:114 +#, c-format +msgid "unable to resolve IPv4 for %s" +msgstr "" + +#: pkg/upstream/container/hijack.go:132 +msgid "[hijack] end of stdout" +msgstr "" + +#: pkg/ui/deploy.go:88 +#, c-format +msgid "status: %s, " +msgstr "" + +#: pkg/recipe/recipe.go:206 +#, c-format +msgid "readme: %s, " +msgstr "" + +#: pkg/git/read.go:52 +#, c-format +msgid "git status: %s: clean" +msgstr "" + +#: cli/app/labels.go:24 +msgid "lb" +msgstr "" + +#: cli/app/upgrade.go:240 cli/app/rollback.go:202 cli/app/deploy.go:203 +#, c-format +msgid "set waiting timeout to %d second(s)" +msgstr "" + +#: cli/app/cmd.go:46 +msgid "requires at least 2 arguments with --local/-l" +msgstr "" + +#: cli/app/secret.go:25 +msgid "g" +msgstr "" + +#: cli/app/secret.go:154 +msgid "" +" # insert regular secret\n" +" abra app secret insert 1312.net my_secret v1 mySuperSecret\n" +"\n" +" # insert secret as file\n" +" abra app secret insert 1312.net my_secret v1 secret.txt -f" +msgstr "" + +#: cli/app/secret.go:443 cli/app/restore.go:108 cli/app/new.go:341 +#: cli/app/logs.go:94 cli/app/backup.go:179 cli/app/backup.go:232 +#: cli/app/backup.go:256 cli/app/list.go:320 +msgid "s" +msgstr "" + +#: cli/app/new.go:199 +#, c-format +msgid "%s created (version: %s)" +msgstr "" + +#: cli/server/add.go:146 +#, c-format +msgid "serverAdd: cleanUp: failed to remove %s: %s" +msgstr "" + +#: cli/server/server.go:10 +msgid "server [cmd] [args] [flags]" +msgstr "" + +#: pkg/upstream/convert/volume.go:93 +msgid "volume options are incompatible with type bind" +msgstr "" + +#: cli/catalogue/catalogue.go:235 +msgid "Manage the recipe catalogue" +msgstr "" + +#: cli/run.go:142 +msgid "prefer offline & filesystem access" +msgstr "" + +#: cli/server/server.go:12 +msgid "Manage servers" +msgstr "" + +#: pkg/service/service.go:61 pkg/service/service.go:115 +msgid "which service are you looking for?" +msgstr "" + +#: pkg/upstream/commandconn/commandconn.go:239 +#, c-format +msgid "commandConn.Close: CloseRead: %v" +msgstr "" + +#: pkg/upstream/convert/service.go:72 +#, c-format +msgid "secret not found: %s" +msgstr "" + +#: pkg/git/read.go:50 +#, c-format +msgid "git status: %s: %s" +msgstr "" + +#: pkg/git/push.go:40 +msgid "git tags pushed" +msgstr "" + +#: cli/app/undeploy.go:22 +msgid "undeploy [flags]" +msgstr "" + +#: cli/app/new.go:371 cli/app/backup.go:271 +msgid "secrets" +msgstr "" + +#: cli/app/backup.go:67 +msgid "Download a snapshot" +msgstr "" + +#: cli/run.go:30 +msgid "catalogue" +msgstr "" + +#: cli/app/secret.go:362 +#, c-format +msgid "%s doesn't exist on server?" +msgstr "" + +#: cli/app/cmd.go:23 +msgid "cmd" +msgstr "" + +#: cli/app/rollback.go:142 +msgid "unknown deployed version, unable to downgrade" +msgstr "" + +#: cli/app/config.go:42 +msgid "which editor do you wish to use?" +msgstr "" + +#: cli/updater/updater.go:74 +msgid "upgrade [[stack] [recipe] | --all] [flags]" +msgstr "" + +#: pkg/service/service.go:57 pkg/service/service.go:111 +msgid "ambiguous service list received, prompting for input" +msgstr "" + +#: pkg/upstream/convert/volume.go:133 +msgid "volume options are incompatible with type npipe" +msgstr "" + +#: cli/app/secret.go:502 +msgid "treat input as a file" +msgstr "" + +#: cli/app/restart.go:133 +#, c-format +msgid "attempting to scale %s to 1" +msgstr "" + +#: cli/app/cp.go:29 +msgid "cp [flags]" +msgstr "" + +#: pkg/git/init.go:34 +#, c-format +msgid "git worktree: %s" +msgstr "" + +#: pkg/container/container.go:31 +#, c-format +msgid "no containers matching the %v filter found?" +msgstr "" + +#: cli/app/restore.go:116 cli/app/backup.go:280 +msgid "v" +msgstr "" + +#: cli/app/new.go:284 +#, c-format +msgid "%s has no secrets to generate, skipping..." +msgstr "" + +#: pkg/lint/recipe.go:481 +#, c-format +msgid "secret %s is longer than 12 characters" +msgstr "" + +#: pkg/upstream/commandconn/commandconn.go:263 +#, c-format +msgid "unimplemented call: SetWriteDeadline(%v)" +msgstr "" + +#: pkg/upstream/convert/volume.go:130 +msgid "invalid npipe source, source cannot be empty" +msgstr "" + +#: pkg/git/init.go:17 +#, c-format +msgid "git init: %s" +msgstr "" + +#: cli/app/rollback.go:27 +msgid "Roll an app back to a previous version" +msgstr "" + +#: cli/app/check.go:18 +msgid "chk" +msgstr "" + +#: cli/app/cp.go:108 +#, c-format +msgid "local %s " +msgstr "" + +#: pkg/upstream/container/tty.go:66 +msgid "failed to resize tty, using default size" +msgstr "" + +#: pkg/ui/deploy.go:83 +#, c-format +msgid "err: %v, " +msgstr "" + +#: pkg/recipe/compose.go:153 +#, c-format +msgid "unable to parse %s, skipping" +msgstr "" + +#: cli/app/secret.go:394 +msgid "GENERATED NAME" +msgstr "" + +#: cli/app/upgrade.go:461 +msgid "only show release notes" +msgstr "" + +#: cli/app/rollback.go:25 +msgid "rollback [version] [flags]" +msgstr "" + +#: cli/app/deploy.go:30 +msgid "Deploy an app" +msgstr "" + +#: cli/updater/updater.go:299 +#, c-format +msgid "available updates for %s: %s" +msgstr "" + +#: pkg/lint/recipe.go:155 +msgid "include \"traefik.enable=true\" deploy label" +msgstr "" + +#: pkg/lint/recipe.go:261 pkg/recipe/files.go:17 +#, c-format +msgid "unable to discover .env.sample for %s" +msgstr "" + +#: pkg/ui/deploy.go:121 +#, c-format +msgid "^%s" +msgstr "" + +#: cli/app/secret.go:146 +msgid "" +"This command inserts a secret into an app environment.\n" +"\n" +"Arbitrary secret insertion is not supported. Secrets that are inserted must\n" +"match those configured in the recipe beforehand.\n" +"\n" +"This can be useful when you want to manually generate secrets for an app\n" +"environment. Typically, you can let Abra generate them for you on app " +"creation\n" +"(see \"abra app new --secrets/-S\" for more)." +msgstr "" + +#: cli/app/cmd.go:249 cli/app/logs.go:19 +msgid "l" +msgstr "" + +#: cli/app/restart.go:143 +#, c-format +msgid "%s has been scaled to 1" +msgstr "" + +#: cli/updater/updater.go:273 +#, fuzzy, c-format +msgid "no published releases for %s in the recipe catalogue?" +msgstr "TRANSLATE THIS FUCKING SHIT ALREADY" + +#: pkg/upstream/container/hijack.go:82 +#, c-format +msgid "unable to set IO streams as raw terminal: %s" +msgstr "" + +#: pkg/recipe/git.go:378 +#, c-format +msgid "git: opening repository in %s" +msgstr "" + +#: pkg/recipe/compose.go:171 pkg/recipe/compose.go:237 +#, c-format +msgid "updating %s to %s in %s" +msgstr "" + +#: pkg/formatter/formatter.go:80 +msgid "detected ABRA_CI=1" +msgstr "" + +#: cli/app/remove.go:136 cli/app/volume.go:179 +#, c-format +msgid "removing volumes failed: %s" +msgstr "" + +#: cli/app/logs.go:101 +msgid "since" +msgstr "" + +#: cli/app/backup.go:215 +msgid "Manage app backups" +msgstr "" + +#: cli/server/prune.go:18 +msgid "" +"Prunes unused containers, networks, and dangling images.\n" +"\n" +"Use \"--volumes/-v\" to remove volumes that are not associated with a " +"deployed\n" +"app. This can result in unwanted data loss if not used carefully." +msgstr "" + +#: pkg/upstream/container/hijack.go:100 +#, c-format +msgid "invalid detach escape keys, using default: %s" +msgstr "" + +#: pkg/recipe/git.go:50 +#, c-format +msgid "ensuring env version %s" +msgstr "" + +#: cli/app/run.go:110 cli/app/cmd.go:256 +msgid "user" +msgstr "" + +#: cli/app/config.go:18 +msgid "Edit app config" +msgstr "" + +#: cli/app/volume.go:77 +msgid "Remove volume(s) associated with an app" +msgstr "" + +#: cli/recipe/lint.go:15 +msgid "Lint a recipe" +msgstr "" + +#: cli/app/ps.go:180 cli/app/list.go:219 +msgid "STATUS" +msgstr "" + +#: cli/app/upgrade.go:392 cli/app/rollback.go:275 +#, c-format +msgid "'%s' is not a known version for %s" +msgstr "" + +#: cli/app/backup.go:298 +msgid "number of retry attempts" +msgstr "" + +#: cli/app/volume.go:47 +msgid "ON SERVER" +msgstr "" + +#: cli/app/secret.go:24 +msgid "generate [[secret] [version] | --all] [flags]" +msgstr "" + +#: cli/upgrade.go:19 +msgid "" +"Upgrade abra in-place with the latest stable or release candidate.\n" +"\n" +"By default, the latest stable release is downloaded.\n" +"\n" +"Use \"--rc/-r\" to install the latest release candidate. Please bear in mind " +"that\n" +"it may contain absolutely catastrophic deal-breaker bugs. Thank you very " +"much\n" +"for the testing efforts " +msgstr "" + +#: cli/server/add.go:57 +msgid "missing argument or --local/-l flag" +msgstr "" + +#: cli/app/secret.go:484 cli/app/secret.go:524 cli/app/restart.go:162 +#: cli/app/app.go:10 cli/app/backup.go:240 +msgid "a" +msgstr "" + +#: cli/app/upgrade.go:32 +msgid "" +"Upgrade an app.\n" +"\n" +"Unlike \"abra app deploy\", chaos operations are not supported here. Only " +"recipe\n" +"versions are supported values for \"[version]\".\n" +"\n" +"It is possible to \"--force/-f\" an upgrade if you want to re-deploy a " +"specific\n" +"version.\n" +"\n" +"Only the deployed version is consulted when trying to determine what " +"upgrades\n" +"are available. The live deployment version is the \"source of truth\" in " +"this\n" +"case. The stored .env version is not consulted.\n" +"\n" +"An upgrade can be destructive, please ensure you have a copy of your app " +"data\n" +"beforehand. See \"abra app backup\" for more." +msgstr "" + +#: cli/app/upgrade.go:453 cli/app/rollback.go:342 cli/app/deploy.go:353 +msgid "disable converge logic checks" +msgstr "" + +#: cli/app/cp.go:197 +#, c-format +msgid "remote: %s does not exist" +msgstr "" + +#: cli/server/add.go:53 +msgid "cannot use [server] and --local together" +msgstr "" + +#: pkg/upstream/convert/volume.go:136 +msgid "tmpfs options are incompatible with type npipe" +msgstr "" + +#: pkg/ui/deploy.go:82 +#, c-format +msgid "{decoder: %v, " +msgstr "" + +#: pkg/dns/dns.go:14 +#, c-format +msgid "%s: unable to resolve IPv4 address: %s" +msgstr "" + +#: cli/app/ps.go:181 +msgid "IMAGE" +msgstr "" + +#: cli/app/run.go:24 +msgid "" +" # run with args/flags\n" +" abra app run 1312.net app -- ls -lha\n" +"\n" +" # run without args/flags\n" +" abra app run 1312.net app bash --user nobody\n" +"\n" +" # run with both kinds of args/flags \n" +" abra app run 1312.net app --user nobody -- ls -lha" +msgstr "" + +#: cli/app/remove.go:50 +#, c-format +msgid "ALERTA ALERTA: deleting %s data and config (local/remote)" +msgstr "" + +#: pkg/service/service.go:95 +#, c-format +msgid "no services matching the %v filter found?" +msgstr "" + +#: pkg/ui/deploy.go:86 +#, c-format +msgid "reader: %v, " +msgstr "" + +#: cli/app/secret.go:507 +msgid "trim" +msgstr "" + +#: cli/app/deploy.go:31 +msgid "" +"Deploy an app.\n" +"\n" +"This command supports chaos operations. Use \"--chaos/-C\" to deploy your " +"recipe\n" +"checkout as-is. Recipe commit hashes are also supported as values for\n" +"\"[version]\". Please note, \"upgrade\"/\"rollback\" do not support chaos " +"operations." +msgstr "" + +#: cli/app/deploy.go:107 +#, c-format +msgid "ensure recipe: %s" +msgstr "" + +#: cli/server/prune.go:93 +msgid "remove all unused images" +msgstr "" + +#: pkg/lint/recipe.go:76 +msgid "wire up healthchecks" +msgstr "" + +#: pkg/ui/deploy.go:84 +#, c-format +msgid "id: %s, " +msgstr "" + +#: cli/server/add.go:100 +#, c-format +msgid "unable to create local context: %s" +msgstr "" + +#: pkg/lint/recipe.go:82 +msgid "all images use a tag" +msgstr "" + +#: cli/app/secret.go:230 +#, c-format +msgid "%s successfully stored on server" +msgstr "" + +#: cli/app/secret.go:253 +#, c-format +msgid "deleted %s successfully from local pass store" +msgstr "" + +#: cli/app/list.go:216 +msgid "RECIPE" +msgstr "" + +#: cli/server/add.go:168 +#, c-format +msgid "creating context with domain %s" +msgstr "" + +#: pkg/recipe/git.go:160 +#, c-format +msgid "unable to resolve '%s': %s" +msgstr "" + +#: pkg/recipe/recipe.go:205 +#, c-format +msgid "compose: %s, " +msgstr "" + +#: cli/app/cmd.go:137 +#, c-format +msgid "%s does not exist locally, use /bin/sh as fallback" +msgstr "" + +#: cli/app/env.go:41 +msgid "ENV OVERVIEW" +msgstr "" + +#: cli/upgrade.go:26 +msgid " abra upgrade --rc" +msgstr "" + +#: pkg/lint/recipe.go:496 +#, c-format +msgid "unable to list local tags for %s" +msgstr "" + +#: pkg/recipe/git.go:410 +#, c-format +msgid "git checkout: %s in %s" +msgstr "" + +#: cli/app/cmd.go:131 cli/app/cmd.go:176 +msgid "did not detect any command arguments" +msgstr "" + +#: cli/app/rollback.go:120 +msgid "no available downgrades" +msgstr "" + +#: cli/app/restart.go:164 +msgid "restart all services" +msgstr "" + +#: cli/app/remove.go:139 +#, c-format +msgid "%d volume(s) removed successfully" +msgstr "" + +#: cli/app/backup.go:266 +msgid "volumes path" +msgstr "" + +#: cli/server/add.go:40 +msgid " abra server add 1312.net" +msgstr "" + +#: pkg/lint/recipe.go:110 +msgid "README.md metadata filled in" +msgstr "" + +#: pkg/git/clone.go:59 pkg/git/clone.go:78 pkg/git/clone.go:87 +#, c-format +msgid "git clone: %s cloned successfully" +msgstr "" + +#: cli/app/secret.go:106 cli/app/secret.go:394 cli/app/new.go:187 +#: cli/app/volume.go:47 +msgid "NAME" +msgstr "" + +#: cli/app/secret.go:210 +#, c-format +msgid "no secret %s available for recipe %s?" +msgstr "" + +#: cli/app/cmd.go:101 +msgid "cannot use --local & --user together" +msgstr "" + +#: cli/app/cmd.go:119 +#, c-format +msgid "--local detected, running %s on local work station" +msgstr "" + +#: cli/app/upgrade.go:318 +#, c-format +msgid "parsing chosen upgrade version failed: %s" +msgstr "" + +#: cli/app/restart.go:161 +msgid "all-services" +msgstr "" + +#: cli/run.go:90 +msgid "man [flags]" +msgstr "" + +#: pkg/lint/recipe.go:162 +msgid "all services have images" +msgstr "" + +#: cli/catalogue/catalogue.go:266 +msgid "skip updating recipe repositories" +msgstr "" + +#: cli/run.go:49 +#, c-format +msgid "unable to create %s: %s" +msgstr "" + +#: pkg/recipe/compose.go:123 +#, c-format +msgid "considering %s config(s) for tag update" +msgstr "" + +#: pkg/recipe/recipe.go:203 +#, c-format +msgid "git url: %s, " +msgstr "" + +#: pkg/formatter/formatter.go:134 +msgid "CreateOverview: only accepts rows of len == 2" +msgstr "" + +#: cli/app/labels.go:27 +msgid " abra app labels 1312.net" +msgstr "" + +#: pkg/lint/recipe.go:118 +msgid "upload your recipe to git.coopcloud.tech/coop-cloud/..." +msgstr "" + +#: pkg/secret/secret.go:130 +#, c-format +msgid "%s not enabled in recipe config, skipping" +msgstr "" + +#: cli/app/run.go:21 +msgid "run [[args] [flags] | [flags] -- [args]]" +msgstr "" + +#: cli/app/cmd.go:168 +#, c-format +msgid "no service %s for %s?" +msgstr "" + +#: cli/app/upgrade.go:266 cli/app/deploy.go:229 +#, c-format +msgid "run the following post-deploy commands: %s" +msgstr "" + +#: cli/app/new.go:374 +msgid "automatically generate secrets" +msgstr "" + +#: pkg/upstream/commandconn/commandconn.go:65 +#, c-format +msgid "commandconn (%s):" +msgstr "" + +#: cli/app/secret.go:499 +msgid "file" +msgstr "" + +#: cli/app/undeploy.go:88 +msgid "initialising undeploy" +msgstr "" + +#: pkg/lint/recipe.go:132 pkg/lint/recipe.go:139 pkg/lint/recipe.go:146 +#: pkg/lint/recipe.go:153 pkg/lint/recipe.go:161 pkg/lint/recipe.go:168 +#: pkg/lint/recipe.go:175 +msgid "error" +msgstr "" + +#: pkg/recipe/recipe.go:435 +#, c-format +msgid "detected versions %s for %s" +msgstr "" + +#: cli/app/upgrade.go:434 cli/app/rollback.go:323 cli/app/deploy.go:334 +#: cli/app/remove.go:155 cli/app/volume.go:198 +msgid "force" +msgstr "" + +#: cli/app/cp.go:273 +msgid "destination directory does not exist" +msgstr "" + +#: cli/app/backup.go:136 +msgid "Create a new snapshot" +msgstr "" + +#: cli/server/add.go:111 +#, c-format +msgid "%s successfully added" +msgstr "" + +#: pkg/lint/recipe.go:75 +msgid "healthcheck enabled for all services" +msgstr "" + +#: pkg/config/env.go:98 +#, c-format +msgid "directory is empty: %s" +msgstr "" + +#: pkg/config/abra.go:88 +msgid "using default abra dir" +msgstr "" + +#: pkg/recipe/files.go:36 +#, c-format +msgid "%s release notes:" +msgstr "" + +#: cli/app/new.go:24 +msgid "" +"Creates a new app from a default recipe.\n" +"\n" +"This new app configuration is stored in your $ABRA_DIR directory under the\n" +"appropriate server.\n" +"\n" +"This command does not deploy your app for you. You will need to run \"abra " +"app\n" +"deploy \" to do so.\n" +"\n" +"You can see what recipes are available (i.e. values for the [recipe] " +"argument)\n" +"by running \"abra recipe ls\".\n" +"\n" +"Recipe commit hashes are supported values for \"[version]\".\n" +"\n" +"Passing the \"--secrets/-S\" flag will automatically generate secrets for " +"your\n" +"app and store them encrypted at rest on the chosen target server. These\n" +"generated secrets are only visible at generation time, so please take care " +"to\n" +"store them somewhere safe.\n" +"\n" +"You can use the \"--pass/-P\" to store these generated passwords locally in " +"a\n" +"pass store (see passwordstore.org for more). The pass command must be " +"available\n" +"on your $PATH." +msgstr "" + +#: cli/catalogue/catalogue.go:187 +#, c-format +msgid "no changes discovered in %s, nothing to publish?" +msgstr "" + +#: cli/server/add.go:202 +msgid "use local server" +msgstr "" + +#: pkg/recipe/git.go:398 +#, c-format +msgid "processing %s for %s" +msgstr "" + +#: pkg/recipe/recipe.go:202 +#, c-format +msgid "dir: %s, " +msgstr "" + +#: pkg/git/init.go:65 +#, c-format +msgid "repo config: %s" +msgstr "" + +#: pkg/git/push.go:13 +#, c-format +msgid "dry run: no git changes pushed in %s" +msgstr "" + +#: pkg/formatter/formatter.go:238 +#, c-format +msgid "stripped %s to %s for parsing" +msgstr "" + +#: cli/app/restart.go:29 +msgid "" +" # restart a single app service\n" +" abra app restart 1312.net app\n" +"\n" +" # restart all app services\n" +" abra app restart 1312.net -a" +msgstr "" + +#: cli/app/deploy.go:36 +msgid "" +" # standard deployment\n" +" abra app deploy 1312.net\n" +"\n" +" # chaos deployment\n" +" abra app deploy 1312.net --chaos\n" +" \n" +" # deploy specific version\n" +" abra app deploy 1312.net 2.0.0+1.2.3\n" +"\n" +" # deploy a specific git hash\n" +" abra app deploy 1312.net 886db76d" +msgstr "" + +#: cli/app/list.go:46 +msgid "" +"Generate a report of all managed apps.\n" +"\n" +"Use \"--status/-S\" flag to query all servers for the live deployment status." +msgstr "" + +#: cli/app/list.go:148 +#, c-format +msgid "unable to clone %s: %s" +msgstr "" + +#: cli/catalogue/catalogue.go:234 +msgid "catalogue [cmd] [args] [flags]" +msgstr "" + +#: pkg/client/context.go:26 +#, c-format +msgid "created the %s context" +msgstr "" + +#: pkg/secret/pass.go:29 +#, c-format +msgid "%s inserted into pass store" +msgstr "" + +#: pkg/config/abra.go:26 +#, c-format +msgid "error reading config file: %s" +msgstr "" + +#: cli/app/upgrade.go:149 +msgid "unknown deployed version, unable to upgrade" +msgstr "" + +#: cli/app/backup.go:107 +#, c-format +msgid "including INCLUDE_PATH=%s in backupbot exec invocation" +msgstr "" + +#: cli/app/secret.go:526 +msgid "remove all secrets" +msgstr "" + +#: cli/catalogue/catalogue.go:175 +#, c-format +msgid "generated recipe catalogue: %s" +msgstr "" + +#: pkg/context/context.go:34 +msgid "context lacks Docker endpoint" +msgstr "" + +#: pkg/lint/recipe.go:163 +msgid "ensure \"image: ...\" set on all services" +msgstr "" + +#: pkg/recipe/compose.go:38 +#, c-format +msgid "COMPOSE_FILE detected, loading %s" +msgstr "" + +#: pkg/recipe/recipe.go:406 +#, c-format +msgid "read recipe catalogue from file system cache in %s" +msgstr "" + +#: cli/app/new.go:275 +msgid "no domain provided" +msgstr "" + +#: cli/app/secret.go:442 +msgid "secret [cmd] [args] [flags]" +msgstr "" + +#: cli/updater/updater.go:197 +#, c-format +msgid "can't separate key from value: %s (this variable is probably unset)" +msgstr "" + +#: pkg/lint/recipe.go:55 +#, c-format +msgid "skipping %s based on skip condition" +msgstr "" + +#: pkg/recipe/compose.go:59 +#, c-format +msgid "retrieved %s configs for %s" +msgstr "" + +#: pkg/git/commit.go:14 +msgid "no commit message specified?" +msgstr "" + +#: cli/app/cp.go:117 cli/app/cp.go:199 cli/app/cp.go:210 +#, c-format +msgid "remote path: %s" +msgstr "" + +#: pkg/lint/recipe.go:89 +msgid "no unstable tags" +msgstr "" + +#: pkg/lint/recipe.go:133 +msgid ".env.sample provided" +msgstr "" + +#: pkg/catalogue/catalogue.go:21 +msgid "catalogue is missing, retrieving now" +msgstr "" + +#: pkg/secret/secret.go:139 +#, c-format +msgid "secret %s is > %d chars when combined with %s" +msgstr "" + +#: pkg/recipe/recipe.go:175 +#, c-format +msgid "failed to check git status of %s: %s" +msgstr "" + +#: pkg/git/init.go:47 +#, c-format +msgid "git commit: %s" +msgstr "" + +#: cli/run.go:74 +#, c-format +msgid "unsupported --lang: %s (want: es)" +msgstr "" + +#: pkg/git/init.go:60 +#, c-format +msgid "set reference: %s" +msgstr "" + +#: cli/app/ps.go:56 cli/app/upgrade.go:423 cli/app/undeploy.go:59 +#: cli/app/services.go:49 cli/app/restart.go:93 cli/app/logs.go:58 +#: cli/updater/updater.go:247 +#, c-format +msgid "%s is not deployed?" +msgstr "" + +#: cli/app/volume.go:153 +#, c-format +msgid "volume %s removed successfully" +msgstr "" + +#: pkg/lint/recipe.go:212 +#, c-format +msgid "" +"recipe '%s' failed lint checks:\n" +"%s" +msgstr "" + +#: pkg/recipe/compose.go:29 +#, c-format +msgid "no COMPOSE_FILE detected, loading default: %s" +msgstr "" + +#: pkg/container/container.go:48 +msgid "ambiguous container list received, prompting for input" +msgstr "" + +#: cli/app/upgrade.go:274 cli/app/undeploy.go:107 cli/app/new.go:224 +#: cli/app/rollback.go:227 cli/app/deploy.go:236 +#, c-format +msgid "writing recipe version failed: %s" +msgstr "" + +#: cli/app/rollback.go:270 +#, c-format +msgid "current deployment '%s' is not a known version for %s" +msgstr "" + +#: pkg/service/service.go:103 pkg/container/container.go:40 +#, c-format +msgid "%s (created %v)" +msgstr "" + +#: cli/app/cmd.go:24 +msgid "Run app commands" +msgstr "" + +#: cli/app/cmd.go:171 +#, c-format +msgid "running command %s within the context of %s_%s" +msgstr "" + +#: cli/app/volume.go:192 +msgid "Manage app volumes" +msgstr "" + +#: cli/app/list.go:45 +msgid "List all managed apps" +msgstr "" + +#: cli/updater/updater.go:224 +#, c-format +msgid "no available upgrades for %s" +msgstr "" + +#: pkg/git/init.go:50 +#, c-format +msgid "init committed all files for new git repo in %s" +msgstr "" + +#: cli/app/new.go:366 +msgid "store secrets in a local pass store" +msgstr "" + +#: cli/app/rollback.go:280 cli/app/rollback.go:284 +#, c-format +msgid "%s is not a downgrade for %s?" +msgstr "" + +#: cli/server/remove.go:20 +msgid "" +"Remove a managed server.\n" +"\n" +"Abra will remove the internal bookkeeping ($ABRA_DIR/servers/...) and\n" +"underlying client connection context. This server will then be lost in " +"time,\n" +"like tears in rain." +msgstr "" + +#: pkg/recipe/git.go:241 +#, c-format +msgid "unable to read remotes in %s: %s" +msgstr "" + +#: pkg/recipe/recipe.go:549 +msgid "collecting recipe listing" +msgstr "" + +#: cli/app/backup.go:274 +msgid "include secrets" +msgstr "" + +#: cli/run.go:34 +msgid "upgrade" +msgstr "" + +#: cli/updater/updater.go:37 +msgid "Check for available upgrades" +msgstr "" + +#: cli/app/secret.go:467 cli/app/secret.go:491 cli/app/secret.go:531 +#: cli/app/new.go:363 +msgid "pass" +msgstr "" + +#: cli/app/rollback.go:42 +msgid "" +" # standard rollback\n" +" abra app rollback 1312.net\n" +"\n" +" # rollback to specific version\n" +" abra app rollback 1312.net 2.0.0+1.2.3" +msgstr "" + +#: cli/app/remove.go:53 +msgid "are you sure?" +msgstr "" + +#: cli/app/backup.go:134 +msgid "create [flags]" +msgstr "" + +#: pkg/upstream/convert/service.go:375 +#, c-format +msgid "undefined network %q" +msgstr "" + +#: pkg/git/add.go:22 +#, c-format +msgid "dry run: adding %s" +msgstr "" + +#: cli/run.go:159 +msgid "force select language (supported: XXX)" +msgstr "" + +#: cli/updater/updater.go:77 +msgid "" +"Upgrade an app by specifying stack name and recipe. \n" +"\n" +"Use \"--all\" to upgrade every deployed app.\n" +"\n" +"For each app with auto updates enabled, the deployed version is compared " +"with\n" +"the current recipe catalogue version. If a new patch/minor version is\n" +"available, the app is upgraded.\n" +"\n" +"To include major versions use the \"--major/-m\" flag. You probably don't " +"want\n" +"that as it will break things. Only apps that are not deployed with \"--" +"chaos/-C\"\n" +"are upgraded, to update chaos deployments use the \"--chaos/-C\" flag. Use " +"it\n" +"with care." +msgstr "" + +#: pkg/upstream/convert/service.go:43 +#, c-format +msgid "duplicate secret target for %s not allowed" +msgstr "" + +#: pkg/git/clone.go:68 +msgid "git clone: main branch failed, attempting master branch" +msgstr "" + +#: cli/app/upgrade.go:29 +msgid "upgrade [version] [flags]" +msgstr "" + +#: cli/app/remove.go:89 +#, c-format +msgid "removing configs failed: %s" +msgstr "" + +#: cli/run.go:150 +msgid "ignore .env version checkout" +msgstr "" + +#: pkg/git/clone.go:49 +#, c-format +msgid "git clone: %s" +msgstr "" + +#: cli/server/remove.go:19 +msgid "Remove a managed server" +msgstr "" + +#: pkg/upstream/container/hijack.go:43 +#, c-format +msgid "unable to setup input stream: %s" +msgstr "" + +#: pkg/recipe/compose.go:191 +#, c-format +msgid "considering %s config(s) for label update" +msgstr "" + +#: pkg/container/container.go:52 +msgid "which container are you looking for?" +msgstr "" + +#: cli/app/secret.go:460 cli/app/secret.go:556 cli/app/ps.go:199 +#: cli/app/list.go:312 +msgid "m" +msgstr "" + +#: cli/app/run.go:23 +msgid "Run a command inside a service container" +msgstr "" + +#: cli/app/run.go:102 +msgid "no-tty" +msgstr "" + +#: cli/app/remove.go:119 +msgid "no secrets to remove" +msgstr "" + +#: cli/server/add.go:86 +msgid "local server already exists" +msgstr "" + +#: pkg/lint/recipe.go:134 +msgid "create an example .env.sample" +msgstr "" + +#: cli/app/secret.go:444 +msgid "Manage app secrets" +msgstr "" + +#: cli/app/services.go:22 +msgid "sr" +msgstr "" + +#: cli/app/backup.go:178 +msgid "snapshots [flags]" +msgstr "" + +#: cli/server/add.go:76 cli/server/add.go:103 +#, c-format +msgid "attempting to create client for %s" +msgstr "" + +#: pkg/client/configs.go:35 +#, c-format +msgid "conf %s: %s" +msgstr "" + +#: pkg/recipe/recipe.go:130 +#, c-format +msgid "version seems invalid: %s" +msgstr "" + +#: pkg/web/web.go:45 +#, c-format +msgid "bad status: %s" +msgstr "" + +#: cli/run.go:109 +#, c-format +msgid "unable to proceed, %s does not exist?" +msgstr "" + +#: cli/app/restore.go:99 +msgid "target" +msgstr "" + +#: cli/app/remove.go:92 +#, c-format +msgid "%d config(s) removed successfully" +msgstr "" + +#: cli/server/remove.go:43 +#, c-format +msgid "%s is now lost in time, like tears in rain" +msgstr "" + +#: cli/recipe/lint.go:14 +msgid "lint [flags]" +msgstr "" + +#: pkg/recipe/compose.go:243 +#, c-format +msgid "synced label %s to service %s" +msgstr "" + +#: cli/app/cmd.go:51 +msgid "accepts at most 2 args with --local/-l" +msgstr "" + +#: cli/app/cmd.go:198 +msgid "List all available commands" +msgstr "" + +#: cli/catalogue/catalogue.go:223 +#, c-format +msgid "new changes published: %s" +msgstr "" + +#: cli/updater/updater.go:251 +#, c-format +msgid "failed to determine deployed version of %s" +msgstr "" + +#: pkg/client/volumes.go:63 +#, c-format +msgid "%d retries failed" +msgstr "" + +#: pkg/lint/recipe.go:140 +msgid "one service named 'app'" +msgstr "" + +#: pkg/envfile/envfile.go:82 +#, c-format +msgid "read 0 env var exports from %s" +msgstr "" + +#: pkg/config/abra.go:77 +msgid "read abra dir from $ABRA_DIR" +msgstr "" + +#: cli/app/secret.go:38 cli/app/secret.go:170 cli/app/secret.go:280 +#: cli/app/upgrade.go:58 cli/app/rollback.go:58 cli/app/deploy.go:59 +#: cli/app/logs.go:32 pkg/autocomplete/autocomplete.go:17 +#: pkg/autocomplete/autocomplete.go:32 pkg/autocomplete/autocomplete.go:43 +#: pkg/autocomplete/autocomplete.go:59 pkg/autocomplete/autocomplete.go:77 +#: pkg/autocomplete/autocomplete.go:93 pkg/autocomplete/autocomplete.go:99 +#: pkg/autocomplete/autocomplete.go:114 +#, c-format +msgid "autocomplete failed: %s" +msgstr "" + +#: cli/app/secret.go:136 +msgid "NOT" +msgstr "" + +#: cli/app/secret.go:437 +#, c-format +msgid "no secrets stored for %s" +msgstr "" + +#: cli/app/cmd.go:267 +msgid "disable remote TTY" +msgstr "" + +#: cli/app/new.go:207 +msgid "SECRETS OVERVIEW" +msgstr "" + +#: cli/app/logs.go:93 +msgid "stderr" +msgstr "" + +#: cli/server/add.go:21 +msgid "add [[server] | --local] [flags]" +msgstr "" + +#: pkg/lint/recipe.go:117 +msgid "git.coopcloud.tech repo exists" +msgstr "" + +#: cli/app/volume.go:191 +msgid "vl" +msgstr "" + +#: pkg/client/volumes.go:59 +#, c-format +msgid "%s: waiting %d seconds before next retry" +msgstr "" + +#: pkg/service/service.go:30 +msgid "no services deployed?" +msgstr "" + +#: pkg/lint/recipe.go:125 +msgid "reduce length of secret names to 12 chars" +msgstr "" + +#: pkg/lint/recipe.go:215 +#, c-format +msgid "linting successful, %s is well configured" +msgstr "" + +#: pkg/upstream/convert/service.go:122 +#, c-format +msgid "duplicate config target for %s not allowed" +msgstr "" + +#: pkg/upstream/convert/volume.go:44 +msgid "tmpfs options are incompatible with type volume" +msgstr "" + +#: pkg/config/env.go:37 +#, c-format +msgid "retrieved %v servers: %s" +msgstr "" + +#: cli/app/restart.go:23 +msgid "Restart an app" +msgstr "" + +#: cli/app/restart.go:64 +msgid "missing [service]" +msgstr "" + +#: cli/app/secret.go:75 +#, c-format +msgid "%s doesn't exist in the env config?" +msgstr "" + +#: cli/app/upgrade.go:31 +msgid "Upgrade an app" +msgstr "" + +#: cli/app/undeploy.go:135 cli/server/prune.go:52 +#, c-format +msgid "networks pruned: %d" +msgstr "" + +#: cli/updater/updater.go:239 +#, c-format +msgid "retrieve deployed version whether %s is already deployed" +msgstr "" + +#: pkg/recipe/git.go:191 +#, c-format +msgid "%s (%s) has locally unstaged changes?" +msgstr "" + +#: pkg/recipe/recipe.go:138 +#, c-format +msgid "removed dirty suffix from .env version: %s -> %s" +msgstr "" + +#: cli/app/ps.go:165 +#, c-format +msgid "unable to convert to JSON: %s" +msgstr "" + +#: cli/app/upgrade.go:437 cli/app/rollback.go:326 cli/app/deploy.go:337 +#: cli/app/remove.go:158 cli/app/volume.go:201 +msgid "perform action without further prompt" +msgstr "" + +#: cli/app/upgrade.go:451 cli/app/rollback.go:340 cli/app/deploy.go:351 +#: cli/app/cp.go:30 cli/app/backup.go:135 +msgid "c" +msgstr "" + +#: cli/app/restart.go:21 +msgid "restart [[service] | --all-services] [flags]" +msgstr "" + +#: pkg/lint/recipe.go:21 pkg/lint/recipe.go:67 pkg/lint/recipe.go:74 +#: pkg/lint/recipe.go:81 pkg/lint/recipe.go:88 pkg/lint/recipe.go:95 +#: pkg/lint/recipe.go:102 pkg/lint/recipe.go:109 pkg/lint/recipe.go:116 +#: pkg/lint/recipe.go:123 +msgid "warn" +msgstr "" + +#: pkg/config/abra.go:20 +msgid "no config file found" +msgstr "" + +#: pkg/git/branch.go:99 +#, c-format +msgid "successfully checked out %v in %s" +msgstr "" + +#: cli/app/upgrade.go:415 cli/app/undeploy.go:51 cli/app/deploy.go:88 +#, c-format +msgid "checking whether %s is already deployed" +msgstr "" + +#: cli/app/restart.go:144 +#, c-format +msgid "%s service successfully restarted" +msgstr "" + +#: cli/app/config.go:16 +msgid "config [flags]" +msgstr "" + +#: cli/app/backup.go:54 +#, c-format +msgid "including TIMESTAMPS=%v in backupbot exec invocation" +msgstr "" + +#: pkg/lint/recipe.go:170 +msgid "vendor config versions in an abra.sh" +msgstr "" + +#: pkg/upstream/convert/service.go:153 pkg/upstream/convert/service.go:168 +#, c-format +msgid "config not found: %s" +msgstr "" + +#: pkg/ui/deploy.go:85 +#, c-format +msgid "name: %s, " +msgstr "" + +#: pkg/recipe/recipe.go:325 +#, c-format +msgid "%s: image meta has incorrect format: %s" +msgstr "" + +#: cli/app/secret.go:470 cli/app/secret.go:494 +msgid "store generated secrets in a local pass store" +msgstr "" + +#: cli/app/secret.go:534 +msgid "remove generated secrets from a local pass store" +msgstr "" + +#: cli/app/backup.go:231 cli/app/backup.go:255 +msgid "snapshot" +msgstr "" + +#: cli/updater/updater.go:176 +#, c-format +msgid "boolean label %s could not be found for %s, set default to false." +msgstr "" + +#: pkg/catalogue/catalogue.go:84 pkg/recipe/git.go:278 +#, c-format +msgid "fetched latest git changes for %s" +msgstr "" + +#: pkg/upstream/convert/volume.go:162 +msgid "volume type must be volume, bind, tmpfs or npipe" +msgstr "" + +#: pkg/recipe/compose.go:47 +#, c-format +msgid "COMPOSE_FILE (=\"%s\") parsing failed?" +msgstr "" + +#: pkg/git/branch.go:68 +#, c-format +msgid "failed to select default branch in %s" +msgstr "" + +#: cli/app/ps.go:183 cli/app/list.go:220 +msgid "CHAOS" +msgstr "" + +#: cli/app/new.go:48 +msgid "n" +msgstr "" + +#: cli/app/backup.go:282 +msgid "include volumes" +msgstr "" + +#: cli/app/list.go:49 +msgid "" +" # list apps of all servers without live status\n" +" abra app ls\n" +"\n" +" # list apps of a specific server with live status\n" +" abra app ls -s 1312.net -S\n" +"\n" +" # list apps of all servers which match a specific recipe\n" +" abra app ls -r gitea" +msgstr "" + +#: cli/complete.go:11 +msgid "autocomplete [bash|zsh|fish|powershell]" +msgstr "" + +#: pkg/client/client.go:100 +msgid "swarm mode not enabled on local server?" +msgstr "" + +#: pkg/logs/logs.go:86 +#, c-format +msgid "tailLogs: unable to copy buffer: %s" +msgstr "" + +#: pkg/config/abra.go:37 +#, c-format +msgid "config file loaded from: %s" +msgstr "" + +#: cli/app/secret.go:307 +msgid "cannot use [secret] and --all/-a together" +msgstr "" + +#: cli/app/secret.go:508 cli/app/restore.go:100 cli/app/run.go:103 +#: cli/app/backup.go:248 +msgid "t" +msgstr "" + +#: cli/app/backup.go:112 +#, c-format +msgid "including SECRETS=%v in backupbot exec invocation" +msgstr "" + +#: cli/updater/updater.go:38 +msgid "" +"Notify on new versions for deployed apps.\n" +"\n" +"If a new patch/minor version is available, a notification is printed.\n" +"\n" +"Use \"--major/-m\" to include new major versions." +msgstr "" + +#: pkg/upstream/convert/volume.go:96 +msgid "tmpfs options are incompatible with type bind" +msgstr "" + +#: pkg/git/commit.go:42 +msgid "git changes commited" +msgstr "" + +#: cli/app/run.go:111 cli/app/cmd.go:257 +msgid "u" +msgstr "" + +#: cli/app/undeploy.go:24 +msgid "Undeploy an app" +msgstr "" + +#: cli/app/list.go:216 +msgid "SERVER" +msgstr "" + +#: pkg/client/client.go:97 +#, c-format +msgid "swarm mode not enabled on %s?" +msgstr "" + +#: cli/app/secret.go:486 +msgid "generate all secrets" +msgstr "" + +#: cli/app/deploy.go:180 +msgid "skipping domain checks" +msgstr "" + +#: cli/app/config.go:17 +msgid "cfg" +msgstr "" + +#: cli/server/prune.go:15 +msgid "prune [flags]" +msgstr "" + +#: pkg/recipe/compose.go:107 +#, c-format +msgid "%s has no version label? try running \"abra recipe sync %s\" first?" +msgstr "" + +#: cli/app/cmd.go:128 cli/app/cmd.go:174 +#, c-format +msgid "parsed following command arguments: %s" +msgstr "" + +#: cli/app/upgrade.go:450 cli/app/rollback.go:339 cli/app/deploy.go:350 +msgid "no-converge-checks" +msgstr "" + +#: pkg/lint/recipe.go:169 +msgid "config version are vendored" +msgstr "" + +#: pkg/ui/deploy.go:330 +msgid "succeeded" +msgstr "" + +#: pkg/git/read.go:149 +#, c-format +msgid "read global ignore paths: %s" +msgstr "" + +#: cli/app/secret.go:372 +msgid "list " +msgstr "" + +#: cli/app/undeploy.go:25 +msgid "" +"This does not destroy any application data.\n" +"\n" +"However, you should remain vigilant, as your swarm installation will " +"consider\n" +"any previously attached volumes as eligible for pruning once undeployed.\n" +"\n" +"Passing \"--prune/-p\" does not remove those volumes." +msgstr "" + +#: cli/app/new.go:236 +#, c-format +msgid "trimming %s to %s to avoid runtime limits" +msgstr "" + +#: cli/app/env.go:16 +msgid "e" +msgstr "" + +#: cli/app/backup.go:213 +msgid "backup [cmd] [args] [flags]" +msgstr "" + +#: pkg/secret/secret.go:62 pkg/secret/secret.go:80 +#, c-format +msgid "generated %s" +msgstr "" + +#: pkg/upstream/commandconn/commandconn.go:172 +#, c-format +msgid "" +"command %v has exited with %v, please make sure the URL is valid, and Docker " +"18.09 or later is installed on the remote host: stderr=%s" +msgstr "" + +#: pkg/git/read.go:130 +#, c-format +msgid "no %s exists, skipping reading gitignore paths" +msgstr "" + +#: cli/app/secret.go:26 +msgid "Generate secrets" +msgstr "" + +#: cli/app/restore.go:17 +msgid "rs" +msgstr "" + +#: cli/run.go:117 +msgid "don't forget to run 'sudo mandb'" +msgstr "" + +#: pkg/service/service.go:77 pkg/service/service.go:131 +msgid "failed to match chosen service" +msgstr "" + +#: pkg/recipe/recipe.go:237 +#, c-format +msgid "%s: attempt recipe metadata parse" +msgstr "" + +#: cli/app/restore.go:124 +msgid "H" +msgstr "" + +#: cli/app/cmd.go:25 +msgid "" +"Run an app specific command.\n" +"\n" +"These commands are bash functions, defined in the abra.sh of the recipe " +"itself.\n" +"They can be run within the context of a service (e.g. app) or locally on " +"your\n" +"work station by passing \"--local/-l\".\n" +"\n" +"N.B. If using the \"--\" style to pass arguments, flags (e.g. \"--local/-" +"l\") must\n" +"be passed *before* the \"--\". It is possible to pass arguments without the " +"\"--\"\n" +"as long as no dashes are present (i.e. \"foo\" works without \"--\", \"-" +"foo\"\n" +"does not)." +msgstr "" + +#: cli/app/upgrade.go:402 cli/app/upgrade.go:406 +#, c-format +msgid "%s is not an upgrade for %s?" +msgstr "" + +#: cli/app/env.go:17 +msgid "Show app .env values" +msgstr "" + +#: cli/app/remove.go:22 +msgid "" +"Remove everything related to an app which is already undeployed.\n" +"\n" +"By default, it will prompt for confirmation before proceeding. All secrets,\n" +"volumes and the local app env file will be deleted.\n" +"\n" +"Only run this command when you are sure you want to completely remove the " +"app\n" +"and all associated app data. This is a destructive action, Be Careful!\n" +"\n" +"If you would like to delete specific volumes or secrets, please use removal\n" +"sub-commands under \"app volume\" and \"app secret\" instead.\n" +"\n" +"Please note, if you delete the local app env file without removing volumes " +"and\n" +"secrets first, Abra will *not* be able to help you remove them afterwards.\n" +"\n" +"To delete everything without prompt, use the \"--force/-f\" or the \"--no-" +"input/n\"\n" +"flag." +msgstr "" + +#: cli/updater/updater.go:202 +#, c-format +msgid "for %s read env %s with value: %s from docker service" +msgstr "" + +#: pkg/lint/recipe.go:491 pkg/recipe/git.go:236 pkg/git/read.go:26 +#, c-format +msgid "unable to open %s: %s" +msgstr "" + +#: pkg/git/remote.go:15 +#, c-format +msgid "dry run: remote %s (%s) not created" +msgstr "" + +#: cli/app/ps.go:119 cli/app/ps.go:120 cli/app/ps.go:121 cli/app/ps.go:122 +#: cli/app/ps.go:123 cli/app/list.go:111 cli/app/list.go:112 +#: cli/app/list.go:113 cli/app/list.go:114 cli/app/list.go:115 +#: cli/app/list.go:175 cli/app/labels.go:71 +msgid "unknown" +msgstr "" + +#: cli/app/services.go:23 +msgid "Display all services of an app" +msgstr "" + +#: cli/app/cp.go:31 +msgid "Copy files to/from a deployed app service" +msgstr "" + +#: pkg/recipe/compose.go:72 +#, c-format +msgid "%s is missing a compose.yml or compose.*.yml file?" +msgstr "" + +#: cli/server/add.go:120 pkg/secret/secret.go:223 pkg/secret/secret.go:243 +#: pkg/server/server.go:21 +#, c-format +msgid "%s already exists" +msgstr "" + +#: cli/app/restore.go:62 +#, c-format +msgid "including NONINTERACTIVE=%v in backupbot exec invocation" +msgstr "" + +#: cli/app/restore.go:107 +msgid "services" +msgstr "" + +#: cli/app/restore.go:16 +msgid "restore [flags]" +msgstr "" + +#: cli/app/backup.go:214 +msgid "b" +msgstr "" + +#: pkg/service/service.go:53 pkg/service/service.go:107 +#, c-format +msgid "expected 1 service but found %v: %s" +msgstr "" + +#: pkg/lint/recipe.go:69 +msgid "ensure 'version: \"3.8\"' in compose configs" +msgstr "" + +#: pkg/ssh/ssh.go:24 +#, c-format +msgid "unable to connect to %s, please check your SSH config" +msgstr "" + +#: cli/app/restore.go:79 +#, c-format +msgid "including NO_COMMANDS=%v in backupbot exec invocation" +msgstr "" + +#: cli/app/undeploy.go:23 +msgid "un" +msgstr "" + +#: cli/app/rollback.go:243 +#, c-format +msgid "please select a downgrade (version: %s, chaos: %s):" +msgstr "" + +#: cli/app/deploy.go:303 +#, c-format +msgid "version: can not redeploy chaos version %s" +msgstr "" + +#: cli/app/deploy.go:305 +#, c-format +msgid "version: taking version from .env file: %s" +msgstr "" + +#: cli/app/logs.go:18 +msgid "logs [service] [flags]" +msgstr "" + +#: pkg/lint/recipe.go:103 +msgid "has published catalogue version" +msgstr "" + +#: pkg/ui/deploy.go:87 +#, c-format +msgid "writer: %v, " +msgstr "" + +#: cli/app/secret.go:262 +msgid "Remove a secret" +msgstr "" + +#: cli/app/app.go:9 +msgid "app [cmd] [args] [flags]" +msgstr "" + +#: cli/run.go:25 +msgid "The Co-op Cloud command-line utility belt " +msgstr "" + +#: pkg/ssh/ssh.go:26 +msgid "docker: is the daemon running / your user has docker permissions?" +msgstr "" + +#: pkg/envfile/envfile.go:73 +#, c-format +msgid "couldn't parse %s" +msgstr "" + +#: pkg/config/abra.go:81 +msgid "read abra dir from config file" +msgstr "" + +#: pkg/recipe/git.go:256 +#, c-format +msgid "unable to check out default branch in %s: %s" +msgstr "" + +#: pkg/recipe/recipe.go:204 +#, c-format +msgid "ssh url: %s, " +msgstr "" + +#: cli/app/restore.go:123 +msgid "hooks" +msgstr "" + +#: cli/app/cmd.go:248 +msgid "local" +msgstr "" + +#: cli/catalogue/catalogue.go:26 +msgid "Generate the recipe catalogue" +msgstr "TRANSLATE THIS FUCKING SHIT ALREADY" + +#: pkg/lint/recipe.go:22 +msgid "critical" +msgstr "" + +#: pkg/upstream/convert/service.go:774 +msgid "replicas can only be used with replicated mode" +msgstr "" + +#: pkg/container/container.go:44 +#, c-format +msgid "expected 1 container but found %v: %s" +msgstr "" + +#: cli/app/secret.go:53 +msgid "missing arguments [secret]/[version] or '--all'" +msgstr "" + +#: cli/app/secret.go:311 +msgid "no secret(s) specified?" +msgstr "" + +#: cli/app/ps.go:28 +msgid "ps [flags]" +msgstr "" + +#: cli/app/deploy.go:177 +msgid "skipping domain checks, no DOMAIN=... configured" +msgstr "" + +#: cli/app/backup.go:65 +msgid "download [flags]" +msgstr "" + +#: cli/app/backup.go:295 +msgid "retries" +msgstr "" + +#: cli/app/volume.go:88 +msgid "" +" # delete volumes interactively\n" +" abra app volume rm 1312.net\n" +"\n" +" # delete specific volume\n" +" abra app volume rm 1312.net my_volume" +msgstr "" + +#: cli/app/volume.go:162 +msgid "" +"'x' indicates selected, enter / return to confirm, ctrl-c to exit, vim mode " +"is enabled" +msgstr "" + +#: cli/app/undeploy.go:143 cli/server/prune.go:66 +#, c-format +msgid "images pruned: %d; space reclaimed: %s" +msgstr "" + +#: cli/catalogue/catalogue.go:27 +msgid "" +"Generate a new copy of the recipe catalogue.\n" +"\n" +"N.B. this command **will** wipe local unstaged changes from your local " +"recipes\n" +"if present. \"--chaos/-C\" on this command refers to the catalogue " +"repository\n" +"(\"$ABRA_DIR/catalogue\") and not the recipes. Please take care not to lose " +"your\n" +"changes.\n" +"\n" +"It is possible to generate new metadata for a single recipe by passing\n" +"[recipe]. The existing local catalogue will be updated, not overwritten.\n" +"\n" +"It is quite easy to get rate limited by Docker Hub when running this " +"command.\n" +"If you have a Hub account you can \"docker login\" and Abra will " +"automatically\n" +"use those details.\n" +"\n" +"Push your new release to git.coopcloud.tech with \"--publish/-p\". This " +"requires\n" +"that you have permission to git push to these repositories and have your " +"SSH\n" +"keys configured on your account." +msgstr "" + +#: cli/app/labels.go:26 +msgid "Both local recipe and live deployment labels are shown." +msgstr "" + +#: cli/catalogue/catalogue.go:89 +msgid "collecting catalogue metadata" +msgstr "" + +#: pkg/secret/secret.go:126 +#, c-format +msgid "missing version for secret? (%s)" +msgstr "" + +#: pkg/secret/secret.go:268 +#, c-format +msgid "generated and stored %v on %s" +msgstr "" + +#: pkg/recipe/git.go:367 +#, c-format +msgid "detected %s as tags for recipe %s" +msgstr "" + +#: pkg/recipe/recipe.go:200 +#, c-format +msgid "version : %s, " +msgstr "" + +#: cli/app/ps.go:179 +msgid "SERVICE" +msgstr "" + +#: cli/app/upgrade.go:127 +msgid "no available upgrades" +msgstr "" + +#: cli/app/upgrade.go:397 +#, c-format +msgid "'%s' is not a known version" +msgstr "" + +#: cli/app/volume.go:182 +#, c-format +msgid "%d volumes removed successfully" +msgstr "" + +#: cli/app/list.go:291 +msgid "show app deployment status" +msgstr "" + +#: cli/run.go:28 +msgid "app" +msgstr "" + +#: pkg/lint/recipe.go:141 +msgid "name a servce 'app'" +msgstr "" + +#: pkg/lint/recipe.go:176 +msgid "only annotated tags used for recipe version" +msgstr "" + +#: cli/app/backup.go:167 +#, c-format +msgid "including RETRIES=%s in backupbot exec invocation" +msgstr "" + +#: cli/app/list.go:43 cli/server/list.go:18 +msgid "list [flags]" +msgstr "" + +#: cli/server/prune.go:75 +#, c-format +msgid "volumes pruned: %d; space reclaimed: %s" +msgstr "" + +#: cli/server/add.go:24 +msgid "" +"Add a new server to your configuration so that it can be managed by Abra.\n" +"\n" +"Abra relies on the standard SSH command-line and ~/.ssh/config for client\n" +"connection details. You must configure an entry per-host in your ~/.ssh/" +"config\n" +"for each server:\n" +"\n" +" Host 1312.net 1312\n" +" Hostname 1312.net\n" +" User antifa\n" +" Port 12345\n" +" IdentityFile ~/.ssh/antifa@somewhere\n" +"\n" +"If \"--local\" is passed, then Abra assumes that the current local server " +"is\n" +"intended as the target server. This is useful when you want to have your " +"entire\n" +"Co-op Cloud config located on the server itself, and not on your local\n" +"developer machine. The domain is then set to \"default\"." +msgstr "" + +#: pkg/lint/recipe.go:104 +msgid "publish a recipe version to the catalogue" +msgstr "" + +#: pkg/lint/recipe.go:147 +msgid "deploy labels stanza present" +msgstr "" + +#: pkg/upstream/convert/volume.go:47 +msgid "bind options are incompatible with type volume" +msgstr "" + +#: pkg/envfile/envfile.go:42 pkg/envfile/envfile.go:80 pkg/config/env.go:50 +#, c-format +msgid "read %s from %s" +msgstr "" + +#: cli/app/cmd.go:35 +msgid "" +" # pass args/flags without \"--\"\n" +" abra app cmd 1312.net app my_cmd_arg foo --user bar\n" +"\n" +" # pass args/flags with \"--\"\n" +" abra app cmd 1312.net app my_cmd_args --user bar -- foo -vvv\n" +"\n" +" # drop the [service] arg if using \"--local/-l\"\n" +" abra app cmd 1312.net my_cmd --local" +msgstr "" + +#: cli/app/upgrade.go:152 +#, c-format +msgid "choosing %s as version to upgrade" +msgstr "" + +#: pkg/lint/recipe.go:83 +msgid "use a tag for all images" +msgstr "" + +#: pkg/config/abra.go:34 +#, c-format +msgid "error loading config file: %s" +msgstr "" + +#: pkg/recipe/compose.go:229 +#, c-format +msgid "coop-cloud.${STACK_NAME}.version=%s" +msgstr "" + +#: pkg/git/commit.go:44 +msgid "dry run: no changes commited" +msgstr "" + +#: pkg/git/clone.go:64 pkg/git/clone.go:102 +#, c-format +msgid "git clone %s: cancelled due to interrupt" +msgstr "" + +#: cli/app/secret.go:476 cli/app/secret.go:516 cli/app/secret.go:540 +#: cli/app/secret.go:548 cli/app/restore.go:132 cli/app/ps.go:207 +#: cli/app/cmd.go:273 cli/app/new.go:380 cli/app/check.go:88 +#: cli/app/restart.go:155 cli/app/deploy.go:327 cli/app/cp.go:379 +#: cli/app/backup.go:288 cli/app/backup.go:304 cli/app/labels.go:136 +msgid "C" +msgstr "" + +#: cli/app/cmd.go:264 +msgid "tty" +msgstr "" + +#: cli/app/deploy.go:316 +#, c-format +msgid "version: taking new recipe version: %s" +msgstr "" + +#: cli/app/remove.go:38 +msgid " abra app remove 1312.net" +msgstr "" + +#: cli/app/volume.go:76 +msgid "remove [volume] [flags]" +msgstr "" + +#: cli/run.go:126 +msgid "show debug messages" +msgstr "" + +#: cli/updater/updater.go:103 +msgid "missing arguments or --all/-a flag" +msgstr "" + +#: pkg/upstream/container/exec.go:108 +msgid "Error monitoring TTY size:" +msgstr "" + +#: cli/app/secret.go:137 +msgid "NOW" +msgstr "" + +#: cli/app/deploy.go:276 +#, c-format +msgid "secret not generated: %s" +msgstr "" + +#: cli/run.go:24 +msgid "abra [cmd] [args] [flags]" +msgstr "" + +#: pkg/upstream/commandconn/commandconn.go:255 +#, c-format +msgid "unimplemented call: SetDeadline(%v)" +msgstr "" + +#: pkg/upstream/convert/volume.go:110 +msgid "invalid tmpfs source, source must be empty" +msgstr "" + +#: pkg/git/push.go:31 +msgid "git changes pushed" +msgstr "" + +#: cli/app/restore.go:19 +msgid "" +"Snapshots are restored while apps are deployed.\n" +"\n" +"Some restore scenarios may require service / app restarts." +msgstr "" + +#: cli/app/restore.go:57 +#, c-format +msgid "including TARGET=%s in backupbot exec invocation" +msgstr "" + +#: cli/app/services.go:67 +msgid "SERVICE (LONG)" +msgstr "" + +#: cli/app/restart.go:24 +msgid "" +"This command restarts services within a deployed app.\n" +"\n" +"Run \"abra app ps \" to see a list of service names.\n" +"\n" +"Pass \"--all-services/-a\" to restart all services." +msgstr "" + +#: cli/app/env.go:18 +msgid " abra app env 1312.net" +msgstr "" + +#: cli/app/volume.go:150 +#, c-format +msgid "removing volume %s failed: %s" +msgstr "" + +#: pkg/upstream/commandconn/commandconn.go:259 +#, c-format +msgid "unimplemented call: SetReadDeadline(%v)" +msgstr "" + +#: pkg/recipe/recipe.go:659 +msgid "retrieving recipes" +msgstr "" + +#: cli/app/restore.go:115 cli/app/backup.go:279 +msgid "volumes" +msgstr "" + +#: cli/app/rollback.go:238 +#, c-format +msgid "please select a downgrade (version: %s):" +msgstr "" + +#: cli/app/backup.go:247 +msgid "timestamps" +msgstr "" + +#: pkg/lint/recipe.go:187 +#, c-format +msgid "linting for critical errors in %s configs" +msgstr "" + +#: pkg/upstream/container/tty.go:39 +#, c-format +msgid "error resize: %s" +msgstr "" + +#: pkg/recipe/recipe.go:74 +#, c-format +msgid "choosing %s as latest version of %s" +msgstr "" + +#: pkg/git/read.go:88 +#, c-format +msgid "no %s exists, not reading any global gitignore config" +msgstr "" + +#: pkg/git/init.go:24 +#, c-format +msgid "initialised new git repo in %s" +msgstr "" + +#: cli/app/backup.go:68 +msgid "" +"Downloads a backup.tar.gz to the current working directory.\n" +"\n" +"\"--volumes/-v\" includes data contained in volumes alongide paths specified " +"in\n" +"\"backupbot.backup.path\" labels." +msgstr "" + +#: cli/server/prune.go:101 +msgid "remove volumes" +msgstr "" + +#: cli/server/add.go:84 +msgid "local server successfully added" +msgstr "" + +#: pkg/ssh/ssh.go:16 +#, c-format +msgid "SSH host key verification failed for %s" +msgstr "" + +#: pkg/upstream/container/hijack.go:167 +#, c-format +msgid "error sendStdin: %s" +msgstr "" + +#: pkg/upstream/convert/service.go:815 +#, c-format +msgid "invalid credential spec: cannot specify both %s, and %s" +msgstr "" diff --git a/pkg/lang/lang.go b/pkg/lang/lang.go deleted file mode 100644 index a8f456e8..00000000 --- a/pkg/lang/lang.go +++ /dev/null @@ -1,30 +0,0 @@ -package lang - -import ( - "os" - "strings" -) - -func GetLocale() string { - if loc := os.Getenv("LC_MESSAGES"); loc != "" { - return NormalizeLocale(loc) - } - - if loc := os.Getenv("LANG"); loc != "" { - return NormalizeLocale(loc) - } - - return "C.UTF-8" -} - -func NormalizeLocale(loc string) string { - if idx := strings.Index(loc, "."); idx != -1 { - return loc[:idx] - } - - if idx := strings.Index(loc, "@"); idx != -1 { - return loc[:idx] - } - - return loc -} diff --git a/pkg/lint/recipe.go b/pkg/lint/recipe.go index 1855b6e2..82ef3eb8 100644 --- a/pkg/lint/recipe.go +++ b/pkg/lint/recipe.go @@ -1,11 +1,13 @@ package lint import ( + "errors" "fmt" "net/http" "os" "path" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/recipe" recipePkg "coopcloud.tech/abra/pkg/recipe" @@ -16,8 +18,8 @@ import ( ) var ( - Warn = "warn" - Critical = "critical" + Warn = i18n.G("warn") + Critical = i18n.G("critical") ) type LintFunction func(recipe.Recipe) (bool, error) @@ -47,10 +49,10 @@ func (l LintRule) Skip(recipe recipe.Recipe) bool { if l.SkipCondition != nil { ok, err := l.SkipCondition(recipe) if err != nil { - log.Debugf("%s: skip condition: %s", l.Ref, err) + log.Debug(i18n.G("%s: skip condition: %s", l.Ref, err)) } if ok { - log.Debugf("skipping %s based on skip condition", l.Ref) + log.Debug(i18n.G("skipping %s based on skip condition", l.Ref)) return true } } @@ -62,117 +64,117 @@ var LintRules = map[string][]LintRule{ "warn": { { Ref: "R001", - Level: "warn", - Description: "compose config has expected version", - HowToResolve: "ensure 'version: \"3.8\"' in compose configs", + Level: i18n.G("warn"), + Description: i18n.G("compose config has expected version"), + HowToResolve: i18n.G("ensure 'version: \"3.8\"' in compose configs"), Function: LintComposeVersion, }, { Ref: "R002", - Level: "warn", - Description: "healthcheck enabled for all services", - HowToResolve: "wire up healthchecks", + Level: i18n.G("warn"), + Description: i18n.G("healthcheck enabled for all services"), + HowToResolve: i18n.G("wire up healthchecks"), Function: LintHealthchecks, }, { Ref: "R003", - Level: "warn", - Description: "all images use a tag", - HowToResolve: "use a tag for all images", + Level: i18n.G("warn"), + Description: i18n.G("all images use a tag"), + HowToResolve: i18n.G("use a tag for all images"), Function: LintAllImagesTagged, }, { Ref: "R004", - Level: "warn", - Description: "no unstable tags", - HowToResolve: "tag all images with stable tags", + Level: i18n.G("warn"), + Description: i18n.G("no unstable tags"), + HowToResolve: i18n.G("tag all images with stable tags"), Function: LintNoUnstableTags, }, { Ref: "R005", - Level: "warn", - Description: "tags use semver-like format", - HowToResolve: "use semver-like tags", + Level: i18n.G("warn"), + Description: i18n.G("tags use semver-like format"), + HowToResolve: i18n.G("use semver-like tags"), Function: LintSemverLikeTags, }, { Ref: "R006", - Level: "warn", - Description: "has published catalogue version", - HowToResolve: "publish a recipe version to the catalogue", + Level: i18n.G("warn"), + Description: i18n.G("has published catalogue version"), + HowToResolve: i18n.G("publish a recipe version to the catalogue"), Function: LintHasPublishedVersion, }, { Ref: "R007", - Level: "warn", - Description: "README.md metadata filled in", - HowToResolve: "fill out all the metadata", + Level: i18n.G("warn"), + Description: i18n.G("README.md metadata filled in"), + HowToResolve: i18n.G("fill out all the metadata"), Function: LintMetadataFilledIn, }, { Ref: "R013", - Level: "warn", - Description: "git.coopcloud.tech repo exists", - HowToResolve: "upload your recipe to git.coopcloud.tech/coop-cloud/...", + Level: i18n.G("warn"), + Description: i18n.G("git.coopcloud.tech repo exists"), + HowToResolve: i18n.G("upload your recipe to git.coopcloud.tech/coop-cloud/..."), Function: LintHasRecipeRepo, }, { Ref: "R015", - Level: "warn", - Description: "long secret names", - HowToResolve: "reduce length of secret names to 12 chars", + Level: i18n.G("warn"), + Description: i18n.G("long secret names"), + HowToResolve: i18n.G("reduce length of secret names to 12 chars"), Function: LintSecretLengths, }, }, "error": { { Ref: "R008", - Level: "error", - Description: ".env.sample provided", - HowToResolve: "create an example .env.sample", + Level: i18n.G("error"), + Description: i18n.G(".env.sample provided"), + HowToResolve: i18n.G("create an example .env.sample"), Function: LintEnvConfigPresent, }, { Ref: "R009", - Level: "error", - Description: "one service named 'app'", - HowToResolve: "name a servce 'app'", + Level: i18n.G("error"), + Description: i18n.G("one service named 'app'"), + HowToResolve: i18n.G("name a servce 'app'"), Function: LintAppService, }, { Ref: "R015", - Level: "error", - Description: "deploy labels stanza present", - HowToResolve: "include \"deploy: labels: ...\" stanza", + Level: i18n.G("error"), + Description: i18n.G("deploy labels stanza present"), + HowToResolve: i18n.G("include \"deploy: labels: ...\" stanza"), Function: LintDeployLabelsPresent, }, { Ref: "R010", - Level: "error", - Description: "traefik routing enabled", - HowToResolve: "include \"traefik.enable=true\" deploy label", + Level: i18n.G("error"), + Description: i18n.G("traefik routing enabled"), + HowToResolve: i18n.G("include \"traefik.enable=true\" deploy label"), Function: LintTraefikEnabled, SkipCondition: LintTraefikEnabledSkipCondition, }, { Ref: "R011", - Level: "error", - Description: "all services have images", - HowToResolve: "ensure \"image: ...\" set on all services", + Level: i18n.G("error"), + Description: i18n.G("all services have images"), + HowToResolve: i18n.G("ensure \"image: ...\" set on all services"), Function: LintImagePresent, }, { Ref: "R012", - Level: "error", - Description: "config version are vendored", - HowToResolve: "vendor config versions in an abra.sh", + Level: i18n.G("error"), + Description: i18n.G("config version are vendored"), + HowToResolve: i18n.G("vendor config versions in an abra.sh"), Function: LintAbraShVendors, }, { Ref: "R014", - Level: "error", - Description: "only annotated tags used for recipe version", - HowToResolve: "replace lightweight tag with annotated tag", + Level: i18n.G("error"), + Description: i18n.G("only annotated tags used for recipe version"), + HowToResolve: i18n.G("replace lightweight tag with annotated tag"), Function: LintValidTags, }, }, @@ -182,9 +184,9 @@ var LintRules = map[string][]LintRule{ // used in code paths such as "app deploy" to avoid nasty surprises but not for // the typical linting commands, which do handle other levels. func LintForErrors(recipe recipe.Recipe) error { - log.Debugf("linting for critical errors in %s configs", recipe.Name) + log.Debug(i18n.G("linting for critical errors in %s configs", recipe.Name)) - var errors string + var errs string for level := range LintRules { if level != "error" { @@ -198,19 +200,19 @@ func LintForErrors(recipe recipe.Recipe) error { ok, err := rule.Function(recipe) if err != nil { - errors += fmt.Sprintf("\nlint %s: %s", rule.Ref, err) + errs += i18n.G("\nlint %s: %s", rule.Ref, err) } if !ok { - errors += fmt.Sprintf("\n * %s (%s)", rule.Description, rule.Ref) + errs += fmt.Sprintf("\n * %s (%s)", rule.Description, rule.Ref) } } } - if len(errors) > 0 { - return fmt.Errorf("recipe '%s' failed lint checks:\n"+errors[1:], recipe.Name) + if len(errs) > 0 { + return errors.New(i18n.G("recipe '%s' failed lint checks:\n%s", recipe.Name, errs[1:])) } - log.Debugf("linting successful, %s is well configured", recipe.Name) + log.Debug(i18n.G("linting successful, %s is well configured", recipe.Name)) return nil } @@ -256,7 +258,7 @@ func LintAppService(recipe recipe.Recipe) (bool, error) { func LintTraefikEnabledSkipCondition(r recipe.Recipe) (bool, error) { sampleEnv, err := r.SampleEnv() if err != nil { - return false, fmt.Errorf("Unable to discover .env.sample for %s", r.Name) + return false, errors.New(i18n.G("unable to discover .env.sample for %s", r.Name)) } if _, ok := sampleEnv["DOMAIN"]; !ok { @@ -476,7 +478,7 @@ func LintSecretLengths(recipe recipe.Recipe) (bool, error) { } for name := range config.Secrets { if len(name) > 12 { - return false, fmt.Errorf("secret %s is longer than 12 characters", name) + return false, errors.New(i18n.G("secret %s is longer than 12 characters", name)) } } @@ -486,12 +488,12 @@ func LintSecretLengths(recipe recipe.Recipe) (bool, error) { func LintValidTags(recipe recipe.Recipe) (bool, error) { repo, err := git.PlainOpen(recipe.Dir) if err != nil { - return false, fmt.Errorf("unable to open %s: %s", recipe.Dir, err) + return false, errors.New(i18n.G("unable to open %s: %s", recipe.Dir, err)) } iter, err := repo.Tags() if err != nil { - log.Fatalf("unable to list local tags for %s", recipe.Name) + log.Fatal(i18n.G("unable to list local tags for %s", recipe.Name)) } if err := iter.ForEach(func(ref *plumbing.Reference) error { @@ -499,7 +501,7 @@ func LintValidTags(recipe recipe.Recipe) (bool, error) { if err != nil { switch err { case plumbing.ErrObjectNotFound: - return fmt.Errorf("invalid lightweight tag detected") + return errors.New(i18n.G("invalid lightweight tag detected")) default: return err } diff --git a/pkg/logs/logs.go b/pkg/logs/logs.go index 0820d9dc..d1bf9bb3 100644 --- a/pkg/logs/logs.go +++ b/pkg/logs/logs.go @@ -3,6 +3,7 @@ package logs import ( "bufio" "context" + "errors" "fmt" "io" "os" @@ -13,6 +14,7 @@ import ( containerTypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" dockerClient "github.com/docker/docker/client" + "coopcloud.tech/abra/pkg/i18n" ) type TailOpts struct { @@ -81,7 +83,7 @@ func TailLogs( } if _, err = io.Copy(os.Stdout, logs); err != nil && err != io.EOF { - errCh <- fmt.Errorf("tailLogs: unable to copy buffer: %s", err) + errCh <- errors.New(i18n.G("tailLogs: unable to copy buffer: %s", err)) } } }(service.ID) diff --git a/pkg/recipe/compose.go b/pkg/recipe/compose.go index 736e5f70..88c7d0c5 100644 --- a/pkg/recipe/compose.go +++ b/pkg/recipe/compose.go @@ -1,6 +1,7 @@ package recipe import ( + "errors" "fmt" "io/ioutil" "os" @@ -13,6 +14,7 @@ import ( loader "coopcloud.tech/abra/pkg/upstream/stack" "github.com/distribution/reference" composetypes "github.com/docker/cli/cli/compose/types" + "coopcloud.tech/abra/pkg/i18n" ) // GetComposeFiles gets the list of compose files for an app (or recipe if you @@ -24,7 +26,7 @@ func (r Recipe) GetComposeFiles(appEnv map[string]string) ([]string, error) { if err := ensurePathExists(r.ComposePath); err != nil { return []string{}, err } - log.Debugf("no COMPOSE_FILE detected, loading default: %s", r.ComposePath) + log.Debug(i18n.G("no COMPOSE_FILE detected, loading default: %s", r.ComposePath)) return []string{r.ComposePath}, nil } @@ -33,7 +35,7 @@ func (r Recipe) GetComposeFiles(appEnv map[string]string) ([]string, error) { if err := ensurePathExists(path); err != nil { return []string{}, err } - log.Debugf("COMPOSE_FILE detected, loading %s", path) + log.Debug(i18n.G("COMPOSE_FILE detected, loading %s", path)) return []string{path}, nil } @@ -42,7 +44,7 @@ func (r Recipe) GetComposeFiles(appEnv map[string]string) ([]string, error) { numComposeFiles := strings.Count(composeFileEnvVar, ":") + 1 envVars := strings.SplitN(composeFileEnvVar, ":", numComposeFiles) if len(envVars) != numComposeFiles { - return composeFiles, fmt.Errorf("COMPOSE_FILE (=\"%s\") parsing failed?", composeFileEnvVar) + return composeFiles, errors.New(i18n.G("COMPOSE_FILE (=\"%s\") parsing failed?", composeFileEnvVar)) } for _, file := range envVars { @@ -53,8 +55,8 @@ func (r Recipe) GetComposeFiles(appEnv map[string]string) ([]string, error) { composeFiles = append(composeFiles, path) } - log.Debugf("COMPOSE_FILE detected (%s), loading %s", composeFileEnvVar, strings.Join(envVars, ", ")) - log.Debugf("retrieved %s configs for %s", strings.Join(composeFiles, ", "), r.Name) + log.Debug(i18n.G("COMPOSE_FILE detected (%s), loading %s", composeFileEnvVar, strings.Join(envVars, ", "))) + log.Debug(i18n.G("retrieved %s configs for %s", strings.Join(composeFiles, ", "), r.Name)) return composeFiles, nil } @@ -67,7 +69,7 @@ func (r Recipe) GetComposeConfig(env map[string]string) (*composetypes.Config, e } if len(composeFiles) == 0 { - return nil, fmt.Errorf("%s is missing a compose.yml or compose.*.yml file?", r.Name) + return nil, errors.New(i18n.G("%s is missing a compose.yml or compose.*.yml file?", r.Name)) } if env == nil { @@ -102,7 +104,7 @@ func (r Recipe) GetVersionLabelLocal() (string, error) { } if label == "" { - return label, fmt.Errorf("%s has no version label? try running \"abra recipe sync %s\" first?", r.Name, r.Name) + return label, errors.New(i18n.G("%s has no version label? try running \"abra recipe sync %s\" first?", r.Name, r.Name)) } return label, nil @@ -118,7 +120,7 @@ func (r Recipe) UpdateTag(image, tag string) (bool, error) { return false, err } - log.Debugf("considering %s config(s) for tag update", strings.Join(composeFiles, ", ")) + log.Debug(i18n.G("considering %s config(s) for tag update", strings.Join(composeFiles, ", "))) for _, composeFile := range composeFiles { opts := stack.Deploy{Composefiles: []string{composeFile}} @@ -148,13 +150,13 @@ func (r Recipe) UpdateTag(image, tag string) (bool, error) { case reference.NamedTagged: composeTag = img.(reference.NamedTagged).Tag() default: - log.Debugf("unable to parse %s, skipping", img) + log.Debug(i18n.G("unable to parse %s, skipping", img)) continue } composeImage := formatter.StripTagMeta(reference.Path(img)) - log.Debugf("parsed %s from %s", composeTag, service.Image) + log.Debug(i18n.G("parsed %s from %s", composeTag, service.Image)) if image == composeImage { bytes, err := ioutil.ReadFile(composeFile) @@ -166,7 +168,7 @@ func (r Recipe) UpdateTag(image, tag string) (bool, error) { new := fmt.Sprintf("%s:%s", composeImage, tag) replacedBytes := strings.Replace(string(bytes), old, new, -1) - log.Debugf("updating %s to %s in %s", old, new, compose.Filename) + log.Debug(i18n.G("updating %s to %s in %s", old, new, compose.Filename)) if err := os.WriteFile(compose.Filename, []byte(replacedBytes), 0o764); err != nil { return false, err @@ -186,7 +188,7 @@ func (r Recipe) UpdateLabel(pattern, serviceName, label string) error { return err } - log.Debugf("considering %s config(s) for label update", strings.Join(composeFiles, ", ")) + log.Debug(i18n.G("considering %s config(s) for label update", strings.Join(composeFiles, ", "))) for _, composeFile := range composeFiles { opts := stack.Deploy{Composefiles: []string{composeFile}} @@ -224,27 +226,27 @@ func (r Recipe) UpdateLabel(pattern, serviceName, label string) error { return err } - old := fmt.Sprintf("coop-cloud.${STACK_NAME}.version=%s", value) + old := i18n.G("coop-cloud.${STACK_NAME}.version=%s", value) replacedBytes := strings.Replace(string(bytes), old, label, -1) if old == label { - log.Warnf("%s is already set, nothing to do?", label) + log.Warnf(i18n.G("%s is already set, nothing to do?", label)) return nil } - log.Debugf("updating %s to %s in %s", old, label, compose.Filename) + log.Debug(i18n.G("updating %s to %s in %s", old, label, compose.Filename)) if err := ioutil.WriteFile(compose.Filename, []byte(replacedBytes), 0o764); err != nil { return err } - log.Infof("synced label %s to service %s", label, serviceName) + log.Infof(i18n.G("synced label %s to service %s", label, serviceName)) } } if !discovered { - log.Warn("no existing label found, automagic insertion not supported yet") - log.Fatalf("add '- \"%s\"' manually to the 'app' service in %s", label, composeFile) + log.Warn(i18n.G("no existing label found, automagic insertion not supported yet")) + log.Fatal(i18n.G("add '- \"%s\"' manually to the 'app' service in %s", label, composeFile)) } } diff --git a/pkg/recipe/files.go b/pkg/recipe/files.go index d3408fa4..cfd16942 100644 --- a/pkg/recipe/files.go +++ b/pkg/recipe/files.go @@ -1,18 +1,20 @@ package recipe import ( + "errors" "fmt" "os" "path" "coopcloud.tech/abra/pkg/envfile" "coopcloud.tech/abra/pkg/formatter" + "coopcloud.tech/abra/pkg/i18n" ) func (r Recipe) SampleEnv() (map[string]string, error) { sampleEnv, err := envfile.ReadEnv(r.SampleEnvPath) if err != nil { - return sampleEnv, fmt.Errorf("unable to discover .env.sample for %s", r.Name) + return sampleEnv, errors.New(i18n.G("unable to discover .env.sample for %s", r.Name)) } return sampleEnv, nil } @@ -31,7 +33,7 @@ func (r Recipe) GetReleaseNotes(version string) (string, error) { return "", err } - title := formatter.BoldStyle.Render(fmt.Sprintf("%s release notes:", version)) + title := formatter.BoldStyle.Render(i18n.G("%s release notes:", version)) withTitle := fmt.Sprintf("%s\n%s\n", title, releaseNotes) return withTitle, nil diff --git a/pkg/recipe/git.go b/pkg/recipe/git.go index e430d71a..e27e0b8b 100644 --- a/pkg/recipe/git.go +++ b/pkg/recipe/git.go @@ -1,6 +1,7 @@ package recipe import ( + "errors" "fmt" "os" "slices" @@ -15,6 +16,7 @@ import ( "github.com/distribution/reference" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" + "coopcloud.tech/abra/pkg/i18n" ) type EnsureContext struct { @@ -45,9 +47,9 @@ func (r Recipe) Ensure(ctx EnsureContext) error { } if r.EnvVersion != "" && !ctx.IgnoreEnvVersion { - log.Debugf("ensuring env version %s", r.EnvVersion) + log.Debug(i18n.G("ensuring env version %s", r.EnvVersion)) if strings.Contains(r.EnvVersion, "+U") { - return fmt.Errorf("can not redeploy chaos version (%s) without --chaos", r.EnvVersion) + return errors.New(i18n.G("can not redeploy chaos version (%s) without --chaos", r.EnvVersion)) } if _, err := r.EnsureVersion(r.EnvVersion); err != nil { @@ -146,16 +148,16 @@ func (r Recipe) EnsureVersion(version string) (bool, error) { joinedTags := strings.Join(parsedTags, ", ") if joinedTags != "" { - log.Debugf("read %s as tags for recipe %s", joinedTags, r.Name) + log.Debug(i18n.G("read %s as tags for recipe %s", joinedTags, r.Name)) } var opts *git.CheckoutOptions if tagRef.String() == "" { - log.Debugf("attempting to checkout '%s' as chaos commit", version) + log.Debug(i18n.G("attempting to checkout '%s' as chaos commit", version)) hash, err := repo.ResolveRevision(plumbing.Revision(version)) if err != nil { - log.Fatalf("unable to resolve '%s': %s", version, err) + log.Fatal(i18n.G("unable to resolve '%s': %s", version, err)) } opts = &git.CheckoutOptions{Hash: *hash, Create: false, Force: true} @@ -173,7 +175,7 @@ func (r Recipe) EnsureVersion(version string) (bool, error) { return isChaosCommit, nil } - log.Debugf("successfully checked %s out to %s in %s", r.Name, tagRef.Short(), r.Dir) + log.Debug(i18n.G("successfully checked %s out to %s in %s", r.Name, tagRef.Short(), r.Dir)) return isChaosCommit, nil } @@ -182,11 +184,11 @@ func (r Recipe) EnsureVersion(version string) (bool, error) { func (r Recipe) EnsureIsClean() error { isClean, err := gitPkg.IsClean(r.Dir) if err != nil { - return fmt.Errorf("unable to check git clean status in %s: %s", r.Dir, err) + return errors.New(i18n.G("unable to check git clean status in %s: %s", r.Dir, err)) } if !isClean { - return fmt.Errorf("%s (%s) has locally unstaged changes?", r.Name, r.Dir) + return errors.New(i18n.G("%s (%s) has locally unstaged changes?", r.Name, r.Dir)) } return nil @@ -220,7 +222,7 @@ func (r Recipe) EnsureLatest() error { } if err := worktree.Checkout(checkOutOpts); err != nil { - log.Debugf("failed to check out %s in %s", branch, r.Dir) + log.Debug(i18n.G("failed to check out %s in %s", branch, r.Dir)) return err } @@ -231,33 +233,33 @@ func (r Recipe) EnsureLatest() error { func (r Recipe) EnsureUpToDate() error { repo, err := git.PlainOpen(r.Dir) if err != nil { - return fmt.Errorf("unable to open %s: %s", r.Dir, err) + return errors.New(i18n.G("unable to open %s: %s", r.Dir, err)) } remotes, err := repo.Remotes() if err != nil { - return fmt.Errorf("unable to read remotes in %s: %s", r.Dir, err) + return errors.New(i18n.G("unable to read remotes in %s: %s", r.Dir, err)) } if len(remotes) == 0 { - log.Debugf("cannot ensure %s is up-to-date, no git remotes configured", r.Name) + log.Debug(i18n.G("cannot ensure %s is up-to-date, no git remotes configured", r.Name)) return nil } worktree, err := repo.Worktree() if err != nil { - return fmt.Errorf("unable to open git work tree in %s: %s", r.Dir, err) + return errors.New(i18n.G("unable to open git work tree in %s: %s", r.Dir, err)) } branch, err := gitPkg.CheckoutDefaultBranch(repo, r.Dir) if err != nil { - return fmt.Errorf("unable to check out default branch in %s: %s", r.Dir, err) + return errors.New(i18n.G("unable to check out default branch in %s: %s", r.Dir, err)) } fetchOpts := &git.FetchOptions{Tags: git.AllTags} if err := repo.Fetch(fetchOpts); err != nil { if !strings.Contains(err.Error(), "already up-to-date") { - return fmt.Errorf("unable to fetch tags in %s: %s", r.Dir, err) + return errors.New(i18n.G("unable to fetch tags in %s: %s", r.Dir, err)) } } @@ -269,11 +271,11 @@ func (r Recipe) EnsureUpToDate() error { if err := worktree.Pull(opts); err != nil { if !strings.Contains(err.Error(), "already up-to-date") { - return fmt.Errorf("unable to git pull in %s: %s", r.Dir, err) + return errors.New(i18n.G("unable to git pull in %s: %s", r.Dir, err)) } } - log.Debugf("fetched latest git changes for %s", r.Name) + log.Debug(i18n.G("fetched latest git changes for %s", r.Name)) return nil } @@ -362,7 +364,7 @@ func (r Recipe) Tags() ([]string, error) { return version1.IsLessThan(version2) }) - log.Debugf("detected %s as tags for recipe %s", strings.Join(tags, ", "), r.Name) + log.Debug(i18n.G("detected %s as tags for recipe %s", strings.Join(tags, ", "), r.Name)) return tags, nil } @@ -373,7 +375,7 @@ func (r Recipe) GetRecipeVersions() (RecipeVersions, []string, error) { versions := RecipeVersions{} - log.Debugf("git: opening repository in %s", r.Dir) + log.Debug(i18n.G("git: opening repository in %s", r.Dir)) repo, err := git.PlainOpen(r.Dir) if err != nil { @@ -393,7 +395,7 @@ func (r Recipe) GetRecipeVersions() (RecipeVersions, []string, error) { if err := gitTags.ForEach(func(ref *plumbing.Reference) (err error) { tag := strings.TrimPrefix(string(ref.Name()), "refs/tags/") - log.Debugf("processing %s for %s", tag, r.Name) + log.Debug(i18n.G("processing %s for %s", tag, r.Name)) checkOutOpts := &git.CheckoutOptions{ Create: false, @@ -401,11 +403,11 @@ func (r Recipe) GetRecipeVersions() (RecipeVersions, []string, error) { Branch: plumbing.ReferenceName(ref.Name()), } if err := worktree.Checkout(checkOutOpts); err != nil { - log.Debugf("failed to check out %s in %s", tag, r.Dir) + log.Debug(i18n.G("failed to check out %s in %s", tag, r.Dir)) return err } - log.Debugf("git checkout: %s in %s", ref.Name(), r.Dir) + log.Debug(i18n.G("git checkout: %s in %s", ref.Name(), r.Dir)) config, err := r.GetComposeConfig(nil) if err != nil { @@ -429,7 +431,7 @@ func (r Recipe) GetRecipeVersions() (RecipeVersions, []string, error) { case reference.NamedTagged: tag = img.(reference.NamedTagged).Tag() case reference.Named: - warnMsg = append(warnMsg, fmt.Sprintf("%s service is missing image tag?", path)) + warnMsg = append(warnMsg, i18n.G("%s service is missing image tag?", path)) continue } @@ -453,7 +455,7 @@ func (r Recipe) GetRecipeVersions() (RecipeVersions, []string, error) { sortRecipeVersions(versions) - log.Debugf("collected %s for %s", versions, r.Dir) + log.Debug(i18n.G("collected %s for %s", versions, r.Dir)) var uniqueWarnings []string for _, w := range warnMsg { diff --git a/pkg/recipe/recipe.go b/pkg/recipe/recipe.go index 728fadca..819cd136 100644 --- a/pkg/recipe/recipe.go +++ b/pkg/recipe/recipe.go @@ -13,6 +13,7 @@ import ( "strings" "github.com/go-git/go-git/v5" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/catalogue" "coopcloud.tech/abra/pkg/config" @@ -70,7 +71,7 @@ func (r RecipeMeta) LatestVersion() string { version = tag } - log.Debugf("choosing %s as latest version of %s", version, r.Name) + log.Debug(i18n.G("choosing %s as latest version of %s", version, r.Name)) return version } @@ -126,7 +127,7 @@ func Get(name string) Recipe { if strings.Contains(name, ":") { split := strings.Split(name, ":") if len(split) > 2 { - log.Fatalf("version seems invalid: %s", name) + log.Fatal(i18n.G("version seems invalid: %s", name)) } name = split[0] @@ -134,7 +135,7 @@ func Get(name string) Recipe { versionRaw = version if strings.HasSuffix(version, config.DIRTY_DEFAULT) { version = strings.Replace(split[1], config.DIRTY_DEFAULT, "", 1) - log.Debugf("removed dirty suffix from .env version: %s -> %s", split[1], version) + log.Debug(i18n.G("removed dirty suffix from .env version: %s -> %s", split[1], version)) } } @@ -143,7 +144,7 @@ func Get(name string) Recipe { if strings.Contains(name, "/") { u, err := url.Parse(name) if err != nil { - log.Fatalf("invalid recipe: %s", err) + log.Fatal(i18n.G("invalid recipe: %s", err)) } u.Scheme = "https" gitURL = u.String() + ".git" @@ -171,7 +172,7 @@ func Get(name string) Recipe { dirty, err := r.IsDirty() if err != nil && !errors.Is(err, git.ErrRepositoryNotExists) { - log.Fatalf("failed to check git status of %s: %s", r.Name, err) + log.Fatal(i18n.G("failed to check git status of %s: %s", r.Name, err)) } r.Dirty = dirty @@ -195,16 +196,16 @@ type Recipe struct { // String outputs a human-friendly string representation. func (r Recipe) String() string { - out := fmt.Sprintf("{name: %s, ", r.Name) - out += fmt.Sprintf("version : %s, ", r.EnvVersion) - out += fmt.Sprintf("dirty: %v, ", r.Dirty) - out += fmt.Sprintf("dir: %s, ", r.Dir) - out += fmt.Sprintf("git url: %s, ", r.GitURL) - out += fmt.Sprintf("ssh url: %s, ", r.SSHURL) - out += fmt.Sprintf("compose: %s, ", r.ComposePath) - out += fmt.Sprintf("readme: %s, ", r.ReadmePath) - out += fmt.Sprintf("sample env: %s, ", r.SampleEnvPath) - out += fmt.Sprintf("abra.sh: %s}", r.AbraShPath) + out := i18n.G("{name: %s, ", r.Name) + out += i18n.G("version : %s, ", r.EnvVersion) + out += i18n.G("dirty: %v, ", r.Dirty) + out += i18n.G("dir: %s, ", r.Dir) + out += i18n.G("git url: %s, ", r.GitURL) + out += i18n.G("ssh url: %s, ", r.SSHURL) + out += i18n.G("compose: %s, ", r.ComposePath) + out += i18n.G("readme: %s, ", r.ReadmePath) + out += i18n.G("sample env: %s, ", r.SampleEnvPath) + out += i18n.G("abra.sh: %s}", r.AbraShPath) return out } @@ -233,7 +234,7 @@ func GetRecipeFeaturesAndCategory(r Recipe) (Features, string, []string, error) feat = Features{} ) - log.Debugf("%s: attempt recipe metadata parse", r.ReadmePath) + log.Debug(i18n.G("%s: attempt recipe metadata parse", r.ReadmePath)) readmeFS, err := ioutil.ReadFile(r.ReadmePath) if err != nil { @@ -321,12 +322,12 @@ func GetImageMetadata(imageRowString, recipeName string) (Image, []string, error if imageRowString != "" { warnMsgs = append( warnMsgs, - fmt.Sprintf("%s: image meta has incorrect format: %s", recipeName, imageRowString), + i18n.G("%s: image meta has incorrect format: %s", recipeName, imageRowString), ) } else { warnMsgs = append( warnMsgs, - fmt.Sprintf("%s: image meta is empty?", recipeName), + i18n.G("%s: image meta is empty?", recipeName), ) } @@ -357,14 +358,14 @@ func GetImageMetadata(imageRowString, recipeName string) (Image, []string, error func GetStringInBetween(recipeName, str, start, end string) (result string, err error) { s := strings.Index(str, start) if s == -1 { - return "", fmt.Errorf("%s: marker string %s not found", recipeName, start) + return "", errors.New(i18n.G("%s: marker string %s not found", recipeName, start)) } s += len(start) e := strings.Index(str[s:], end) if e == -1 { - return "", fmt.Errorf("%s: end marker %s not found", recipeName, end) + return "", errors.New(i18n.G("%s: end marker %s not found", recipeName, end)) } return str[s : s+e], nil @@ -402,7 +403,7 @@ func readRecipeCatalogueFS(target interface{}) error { return err } - log.Debugf("read recipe catalogue from file system cache in %s", config.RECIPES_JSON) + log.Debug(i18n.G("read recipe catalogue from file system cache in %s", config.RECIPES_JSON)) return nil } @@ -431,7 +432,7 @@ func VersionsOfService(recipe, serviceName string, offline bool) ([]string, erro } } - log.Debugf("detected versions %s for %s", strings.Join(versions, ", "), recipe) + log.Debug(i18n.G("detected versions %s for %s", strings.Join(versions, ", "), recipe)) return versions, nil } @@ -454,11 +455,11 @@ func GetRecipeMeta(recipeName string, offline bool) (RecipeMeta, error) { recipeMeta, ok := catl[recipeName] if !ok { return RecipeMeta{}, RecipeMissingFromCatalogue{ - err: fmt.Sprintf("recipe %s does not exist?", recipeName), + err: i18n.G("recipe %s does not exist?", recipeName), } } - log.Debugf("recipe metadata retrieved for %s", recipeName) + log.Debug(i18n.G("recipe metadata retrieved for %s", recipeName)) return recipeMeta, nil } @@ -545,13 +546,13 @@ func ReadReposMetadata(debug bool) (RepoCatalogue, error) { reposMeta := make(RepoCatalogue) pageIdx := 1 - bar := formatter.CreateProgressbar(-1, "collecting recipe listing") + bar := formatter.CreateProgressbar(-1, i18n.G("collecting recipe listing")) for { var reposList []RepoMeta pagedURL := fmt.Sprintf("%s?page=%v", ReposMetadataURL, pageIdx) - log.Debugf("fetching repo metadata from %s", pagedURL) + log.Debug(i18n.G("fetching repo metadata from %s", pagedURL)) if err := web.ReadJSON(pagedURL, &reposList); err != nil { return reposMeta, err @@ -655,7 +656,7 @@ func UpdateRepositories(repos RepoCatalogue, recipeName string, debug bool) erro cloneLimiter := limit.New(3) - retrieveBar := formatter.CreateProgressbar(barLength, "retrieving recipes") + retrieveBar := formatter.CreateProgressbar(barLength, i18n.G("retrieving recipes")) ch := make(chan string, barLength) for _, repoMeta := range repos { go func(rm RepoMeta) { diff --git a/pkg/secret/pass.go b/pkg/secret/pass.go index 1763e1f4..6a4dba91 100644 --- a/pkg/secret/pass.go +++ b/pkg/secret/pass.go @@ -6,12 +6,13 @@ import ( "os/exec" "coopcloud.tech/abra/pkg/log" + "coopcloud.tech/abra/pkg/i18n" ) // PassInsertSecret inserts a secret into a pass store. func PassInsertSecret(secretValue, secretName, appName, server string) error { if _, err := exec.LookPath("pass"); err != nil { - return errors.New("pass command not found on $PATH, is it installed?") + return errors.New(i18n.G("pass command not found on $PATH, is it installed?")) } cmd := fmt.Sprintf( @@ -19,13 +20,13 @@ func PassInsertSecret(secretValue, secretName, appName, server string) error { secretValue, server, appName, secretName, ) - log.Debugf("attempting to run %s", cmd) + log.Debug(i18n.G("attempting to run %s", cmd)) if err := exec.Command("bash", "-c", cmd).Run(); err != nil { return err } - log.Infof("%s inserted into pass store", secretName) + log.Infof(i18n.G("%s inserted into pass store", secretName)) return nil } @@ -33,7 +34,7 @@ func PassInsertSecret(secretValue, secretName, appName, server string) error { // PassRmSecret deletes a secret from a pass store. func PassRmSecret(secretName, appName, server string) error { if _, err := exec.LookPath("pass"); err != nil { - return errors.New("pass command not found on $PATH, is it installed?") + return errors.New(i18n.G("pass command not found on $PATH, is it installed?")) } cmd := fmt.Sprintf( @@ -41,13 +42,13 @@ func PassRmSecret(secretName, appName, server string) error { server, appName, secretName, ) - log.Debugf("attempting to run %s", cmd) + log.Debug(i18n.G("attempting to run %s", cmd)) if err := exec.Command("bash", "-c", cmd).Run(); err != nil { return err } - log.Infof("%s removed from pass store", secretName) + log.Infof(i18n.G("%s removed from pass store", secretName)) return nil } diff --git a/pkg/secret/secret.go b/pkg/secret/secret.go index f8366c7b..7b9cc9f3 100644 --- a/pkg/secret/secret.go +++ b/pkg/secret/secret.go @@ -5,6 +5,7 @@ package secret import ( "context" + "errors" "fmt" "slices" "strconv" @@ -21,6 +22,7 @@ import ( "github.com/decentral1se/passgen" "github.com/docker/docker/api/types" dockerClient "github.com/docker/docker/client" + "coopcloud.tech/abra/pkg/i18n" ) // Secret represents a secret. @@ -57,7 +59,7 @@ func GeneratePassword(length uint, charset string) (string, error) { return "", err } - log.Debugf("generated %s", strings.Join(passwords, ", ")) + log.Debug(i18n.G("generated %s", strings.Join(passwords, ", "))) return passwords[0], nil } @@ -75,7 +77,7 @@ func GeneratePassphrase() (string, error) { return "", err } - log.Debugf("generated %s", strings.Join(passphrases, ", ")) + log.Debug(i18n.G("generated %s", strings.Join(passphrases, ", "))) return passphrases[0], nil } @@ -114,18 +116,18 @@ func ReadSecretsConfig(appEnvPath string, composeFiles []string, stackName strin } if len(enabledSecrets) == 0 { - log.Debugf("not generating app secrets, none enabled in recipe config") + log.Debug(i18n.G("not generating app secrets, none enabled in recipe config")) return nil, nil } secretValues := map[string]Secret{} for secretId, secretConfig := range composeConfig.Secrets { if string(secretConfig.Name[len(secretConfig.Name)-1]) == "_" { - return nil, fmt.Errorf("missing version for secret? (%s)", secretId) + return nil, errors.New(i18n.G("missing version for secret? (%s)", secretId)) } if !(slices.Contains(enabledSecrets, secretId)) { - log.Warnf("%s not enabled in recipe config, skipping", secretId) + log.Warnf(i18n.G("%s not enabled in recipe config, skipping", secretId)) continue } @@ -134,7 +136,7 @@ func ReadSecretsConfig(appEnvPath string, composeFiles []string, stackName strin value := Secret{Version: secretVersion, RemoteName: secretConfig.Name} if len(value.RemoteName) > config.MAX_DOCKER_SECRET_LENGTH { - return nil, fmt.Errorf("secret %s is > %d chars when combined with %s", secretId, config.MAX_DOCKER_SECRET_LENGTH, stackName) + return nil, errors.New(i18n.G("secret %s is > %d chars when combined with %s", secretId, config.MAX_DOCKER_SECRET_LENGTH, stackName)) } // Check if the length modifier is set for this secret. @@ -202,12 +204,12 @@ func GenerateSecrets(cl *dockerClient.Client, secrets map[string]Secret, server defer wg.Done() if secret.SkipGenerate { - log.Debugf("skipping generation of %s (generate=false)", secretName) + log.Debug(i18n.G("skipping generation of %s (generate=false)", secretName)) ch <- nil return } - log.Debugf("attempting to generate and store %s on %s", secret.RemoteName, server) + log.Debug(i18n.G("attempting to generate and store %s on %s", secret.RemoteName, server)) if secret.Length > 0 { password, err := GeneratePassword(uint(secret.Length), secret.Charset) @@ -218,7 +220,7 @@ func GenerateSecrets(cl *dockerClient.Client, secrets map[string]Secret, server if err := client.StoreSecret(cl, secret.RemoteName, password, server); err != nil { if strings.Contains(err.Error(), "AlreadyExists") { - log.Warnf("%s already exists", secret.RemoteName) + log.Warnf(i18n.G("%s already exists", secret.RemoteName)) ch <- nil } else { ch <- err @@ -238,7 +240,7 @@ func GenerateSecrets(cl *dockerClient.Client, secrets map[string]Secret, server if err := client.StoreSecret(cl, secret.RemoteName, passphrase, server); err != nil { if strings.Contains(err.Error(), "AlreadyExists") { - log.Warnf("%s already exists", secret.RemoteName) + log.Warnf(i18n.G("%s already exists", secret.RemoteName)) ch <- nil } else { ch <- err @@ -263,7 +265,7 @@ func GenerateSecrets(cl *dockerClient.Client, secrets map[string]Secret, server } } - log.Debugf("generated and stored %v on %s", secrets, server) + log.Debug(i18n.G("generated and stored %v on %s", secrets, server)) return secretsGenerated, nil } diff --git a/pkg/server/server.go b/pkg/server/server.go index 8f723a69..c312209d 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -6,6 +6,7 @@ import ( "coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/log" + "coopcloud.tech/abra/pkg/i18n" ) // CreateServerDir creates a server directory under ~/.abra. @@ -17,11 +18,11 @@ func CreateServerDir(serverName string) error { return err } - log.Debugf("%s already exists", serverPath) + log.Debug(i18n.G("%s already exists", serverPath)) return nil } - log.Debugf("successfully created %s", serverPath) + log.Debug(i18n.G("successfully created %s", serverPath)) return nil } diff --git a/pkg/service/service.go b/pkg/service/service.go index 32d1f8f6..54c1f495 100644 --- a/pkg/service/service.go +++ b/pkg/service/service.go @@ -2,6 +2,7 @@ package service import ( "context" + "errors" "fmt" "strings" @@ -12,6 +13,7 @@ import ( "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/client" + "coopcloud.tech/abra/pkg/i18n" ) // GetService retrieves a service container based on a label. If prompt is true @@ -25,7 +27,7 @@ func GetServiceByLabel(c context.Context, cl *client.Client, label string, promp } if len(services) == 0 { - return swarm.Service{}, fmt.Errorf("no services deployed?") + return swarm.Service{}, errors.New(i18n.G("no services deployed?")) } var matchingServices []swarm.Service @@ -36,7 +38,7 @@ func GetServiceByLabel(c context.Context, cl *client.Client, label string, promp } if len(matchingServices) == 0 { - return swarm.Service{}, fmt.Errorf("no services deployed matching label '%s'?", label) + return swarm.Service{}, errors.New(i18n.G("no services deployed matching label '%s'?", label)) } if len(matchingServices) > 1 { @@ -48,15 +50,15 @@ func GetServiceByLabel(c context.Context, cl *client.Client, label string, promp } if !prompt { - err := fmt.Errorf("expected 1 service but found %v: %s", len(matchingServices), strings.Join(servicesRaw, " ")) + err := errors.New(i18n.G("expected 1 service but found %v: %s", len(matchingServices), strings.Join(servicesRaw, " "))) return swarm.Service{}, err } - log.Warnf("ambiguous service list received, prompting for input") + log.Warnf(i18n.G("ambiguous service list received, prompting for input")) var response string prompt := &survey.Select{ - Message: "which service are you looking for?", + Message: i18n.G("which service are you looking for?"), Options: servicesRaw, } @@ -72,7 +74,7 @@ func GetServiceByLabel(c context.Context, cl *client.Client, label string, promp } } - log.Fatal("failed to match chosen service") + log.Fatal(i18n.G("failed to match chosen service")) } return matchingServices[0], nil @@ -90,7 +92,7 @@ func GetService(c context.Context, cl *client.Client, filters filters.Args, prom if len(services) == 0 { filter := filters.Get("name")[0] - return swarm.Service{}, fmt.Errorf("no services matching the %v filter found?", filter) + return swarm.Service{}, errors.New(i18n.G("no services matching the %v filter found?", filter)) } if len(services) != 1 { @@ -98,19 +100,19 @@ func GetService(c context.Context, cl *client.Client, filters filters.Args, prom for _, service := range services { serviceName := service.Spec.Name created := formatter.HumanDuration(service.CreatedAt.Unix()) - servicesRaw = append(servicesRaw, fmt.Sprintf("%s (created %v)", serviceName, created)) + servicesRaw = append(servicesRaw, i18n.G("%s (created %v)", serviceName, created)) } if !prompt { - err := fmt.Errorf("expected 1 service but found %v: %s", len(services), strings.Join(servicesRaw, " ")) + err := errors.New(i18n.G("expected 1 service but found %v: %s", len(services), strings.Join(servicesRaw, " "))) return swarm.Service{}, err } - log.Warnf("ambiguous service list received, prompting for input") + log.Warnf(i18n.G("ambiguous service list received, prompting for input")) var response string prompt := &survey.Select{ - Message: "which service are you looking for?", + Message: i18n.G("which service are you looking for?"), Options: servicesRaw, } @@ -126,7 +128,7 @@ func GetService(c context.Context, cl *client.Client, filters filters.Args, prom } } - log.Fatal("failed to match chosen service") + log.Fatal(i18n.G("failed to match chosen service")) } return services[0], nil diff --git a/pkg/ssh/ssh.go b/pkg/ssh/ssh.go index 96489f43..99a46efb 100644 --- a/pkg/ssh/ssh.go +++ b/pkg/ssh/ssh.go @@ -1,8 +1,10 @@ package ssh import ( - "fmt" + "errors" "strings" + + "coopcloud.tech/abra/pkg/i18n" ) // Fatal is a error output wrapper which aims to make SSH failures easier to @@ -11,17 +13,17 @@ func Fatal(hostname string, err error) error { out := err.Error() if strings.Contains(out, "Host key verification failed.") { - return fmt.Errorf("SSH host key verification failed for %s", hostname) + return errors.New(i18n.G("SSH host key verification failed for %s", hostname)) } else if strings.Contains(out, "Could not resolve hostname") { - return fmt.Errorf("could not resolve hostname for %s", hostname) + return errors.New(i18n.G("could not resolve hostname for %s", hostname)) } else if strings.Contains(out, "Connection timed out") { - return fmt.Errorf("connection timed out for %s", hostname) + return errors.New(i18n.G("connection timed out for %s", hostname)) } else if strings.Contains(out, "Permission denied") { - return fmt.Errorf("ssh auth: permission denied for %s", hostname) + return errors.New(i18n.G("ssh auth: permission denied for %s", hostname)) } else if strings.Contains(out, "Network is unreachable") { - return fmt.Errorf("unable to connect to %s, please check your SSH config", hostname) + return errors.New(i18n.G("unable to connect to %s, please check your SSH config", hostname)) } else if strings.Contains(out, "Is the docker daemon running") { - return fmt.Errorf("docker: is the daemon running / your user has docker permissions?") + return errors.New(i18n.G("docker: is the daemon running / your user has docker permissions?")) } return err diff --git a/pkg/ui/deploy.go b/pkg/ui/deploy.go index 5b3a8ea8..74d59df8 100644 --- a/pkg/ui/deploy.go +++ b/pkg/ui/deploy.go @@ -3,7 +3,6 @@ package ui import ( "context" "encoding/json" - "fmt" "io" "sort" "strings" @@ -17,6 +16,7 @@ import ( "github.com/docker/docker/api/types/filters" dockerClient "github.com/docker/docker/client" "github.com/docker/docker/pkg/jsonmessage" + "coopcloud.tech/abra/pkg/i18n" ) var IsRunning bool @@ -79,13 +79,13 @@ type stream struct { } func (s stream) String() string { - out := fmt.Sprintf("{decoder: %v, ", s.decoder) - out += fmt.Sprintf("err: %v, ", s.Err) - out += fmt.Sprintf("id: %s, ", s.id) - out += fmt.Sprintf("name: %s, ", s.Name) - out += fmt.Sprintf("reader: %v, ", s.reader) - out += fmt.Sprintf("writer: %v, ", s.writer) - out += fmt.Sprintf("status: %s, ", s.status) + out := i18n.G("{decoder: %v, ", s.decoder) + out += i18n.G("err: %v, ", s.Err) + out += i18n.G("id: %s, ", s.id) + out += i18n.G("name: %s, ", s.Name) + out += i18n.G("reader: %v, ", s.reader) + out += i18n.G("writer: %v, ", s.writer) + out += i18n.G("status: %s, ", s.status) return out } @@ -118,7 +118,7 @@ func (s stream) process() tea.Msg { func (s stream) healthcheck(m Model) tea.Msg { filters := filters.NewArgs() - filters.Add("name", fmt.Sprintf("^%s", s.Name)) + filters.Add("name", i18n.G("^%s", s.Name)) containers, err := m.cl.ContainerList(m.ctx, containerTypes.ListOptions{Filters: filters}) if err != nil { @@ -327,10 +327,10 @@ func (m Model) View() string { status := stream.status if strings.Contains(stream.status, "converged") && !stream.rollback { - status = "succeeded" + status = i18n.G("succeeded") } if strings.Contains(stream.status, "rolled back") { - status = "rolled back" + status = i18n.G("rolled back") } retries := 0 @@ -338,7 +338,7 @@ func (m Model) View() string { retries = stream.retries } - output := fmt.Sprintf("%s: %s (retries: %v, healthcheck: %s)", + output := i18n.G("%s: %s (retries: %v, healthcheck: %s)", formatter.BoldStyle.Render(short), status, retries, diff --git a/pkg/upstream/commandconn/commandconn.go b/pkg/upstream/commandconn/commandconn.go index 9f76c50f..64083500 100644 --- a/pkg/upstream/commandconn/commandconn.go +++ b/pkg/upstream/commandconn/commandconn.go @@ -17,7 +17,6 @@ package commandconn import ( "bytes" "context" - "fmt" "io" "net" "os" @@ -28,6 +27,7 @@ import ( "time" "coopcloud.tech/abra/pkg/log" + "coopcloud.tech/abra/pkg/i18n" "github.com/pkg/errors" exec "golang.org/x/sys/execabs" ) @@ -46,7 +46,7 @@ func New(ctx context.Context, cmd string, args ...string) (net.Conn, error) { ) c.cmd = exec.CommandContext(ctx, cmd, args...) // we assume that args never contains sensitive information - log.Debugf("commandconn: starting %s with %v", cmd, args) + log.Debug(i18n.G("commandconn: starting %s with %v", cmd, args)) c.cmd.Env = os.Environ() c.cmd.SysProcAttr = &syscall.SysProcAttr{} setPdeathsig(c.cmd) @@ -62,7 +62,7 @@ func New(ctx context.Context, cmd string, args ...string) (net.Conn, error) { c.cmd.Stderr = &stderrWriter{ stderrMu: &c.stderrMu, stderr: &c.stderr, - debugPrefix: fmt.Sprintf("commandconn (%s):", cmd), + debugPrefix: i18n.G("commandconn (%s):", cmd), } c.localAddr = dummyAddr{network: "dummy", s: "dummy-0"} c.remoteAddr = dummyAddr{network: "dummy", s: "dummy-1"} @@ -138,7 +138,7 @@ func (c *commandConn) kill() error { return nil } } - return errors.Wrapf(werr, "commandconn: failed to wait") + return errors.Wrap(werr, i18n.G("commandconn: failed to wait")) } func (c *commandConn) onEOF(eof error) error { @@ -159,7 +159,7 @@ func (c *commandConn) onEOF(eof error) error { c.stderrMu.Lock() stderr := c.stderr.String() c.stderrMu.Unlock() - return errors.Errorf("command %v did not exit after %v: stderr=%q", c.cmd.Args, eof, stderr) + return errors.New(i18n.G("command %v did not exit after %v: stderr=%q", c.cmd.Args, eof, stderr)) } } c.cmdMutex.Unlock() @@ -169,7 +169,7 @@ func (c *commandConn) onEOF(eof error) error { c.stderrMu.Lock() stderr := c.stderr.String() c.stderrMu.Unlock() - return errors.Errorf("command %v has exited with %v, please make sure the URL is valid, and Docker 18.09 or later is installed on the remote host: stderr=%s", c.cmd.Args, werr, stderr) + return errors.New(i18n.G("command %v has exited with %v, please make sure the URL is valid, and Docker 18.09 or later is installed on the remote host: stderr=%s", c.cmd.Args, werr, stderr)) } func ignorableCloseError(err error) bool { @@ -236,7 +236,7 @@ func (c *commandConn) Write(p []byte) (int, error) { func (c *commandConn) Close() error { var err error if err = c.CloseRead(); err != nil { - log.Warnf("commandConn.Close: CloseRead: %v", err) + log.Warnf(i18n.G("commandConn.Close: CloseRead: %v", err)) } if err = c.CloseWrite(); err != nil { // muted because https://github.com/docker/compose/issues/8544 @@ -252,15 +252,15 @@ func (c *commandConn) RemoteAddr() net.Addr { return c.remoteAddr } func (c *commandConn) SetDeadline(t time.Time) error { - log.Debugf("unimplemented call: SetDeadline(%v)", t) + log.Debug(i18n.G("unimplemented call: SetDeadline(%v)", t)) return nil } func (c *commandConn) SetReadDeadline(t time.Time) error { - log.Debugf("unimplemented call: SetReadDeadline(%v)", t) + log.Debug(i18n.G("unimplemented call: SetReadDeadline(%v)", t)) return nil } func (c *commandConn) SetWriteDeadline(t time.Time) error { - log.Debugf("unimplemented call: SetWriteDeadline(%v)", t) + log.Debug(i18n.G("unimplemented call: SetWriteDeadline(%v)", t)) return nil } diff --git a/pkg/upstream/commandconn/connection.go b/pkg/upstream/commandconn/connection.go index f48a77af..07badfdf 100644 --- a/pkg/upstream/commandconn/connection.go +++ b/pkg/upstream/commandconn/connection.go @@ -11,6 +11,7 @@ import ( "github.com/docker/cli/cli/context/docker" dCliContextStore "github.com/docker/cli/cli/context/store" dClient "github.com/docker/docker/client" + "coopcloud.tech/abra/pkg/i18n" "github.com/pkg/errors" ) @@ -34,7 +35,7 @@ func getConnectionHelper(daemonURL string, sshFlags []string) (*connhelper.Conne case "ssh": ctxConnDetails, err := ssh.ParseURL(daemonURL) if err != nil { - return nil, errors.Wrap(err, "ssh host connection is not valid") + return nil, errors.Wrap(err, i18n.G("ssh host connection is not valid")) } return &connhelper.ConnectionHelper{ diff --git a/pkg/upstream/container/exec.go b/pkg/upstream/container/exec.go index ff551008..81f6ff95 100644 --- a/pkg/upstream/container/exec.go +++ b/pkg/upstream/container/exec.go @@ -11,6 +11,7 @@ import ( "github.com/docker/cli/cli/command" "github.com/docker/docker/api/types/container" apiclient "github.com/docker/docker/client" + "coopcloud.tech/abra/pkg/i18n" ) // RunExec runs a command on a remote container. io.Writer corresponds to the @@ -39,7 +40,7 @@ func RunExec(dockerCli command.Cli, client *apiclient.Client, containerID string execID := response.ID if execID == "" { - return nil, errors.New("exec ID empty") + return nil, errors.New(i18n.G("exec ID empty")) } if execOptions.Detach { @@ -104,12 +105,12 @@ func interactiveExec(ctx context.Context, dockerCli command.Cli, client *apiclie if execOpts.Tty && dockerCli.In().IsTerminal() { if err := MonitorTtySize(ctx, client, dockerCli, execID, true); err != nil { - fmt.Fprintln(dockerCli.Err(), "Error monitoring TTY size:", err) + fmt.Fprintln(dockerCli.Err(), i18n.G("Error monitoring TTY size:"), err) } } if err := <-errCh; err != nil { - log.Debugf("Error hijack: %s", err) + log.Debug(i18n.G("Error hijack: %s", err)) return out, err } diff --git a/pkg/upstream/container/hijack.go b/pkg/upstream/container/hijack.go index f2a9990e..0eecbb7e 100644 --- a/pkg/upstream/container/hijack.go +++ b/pkg/upstream/container/hijack.go @@ -2,7 +2,7 @@ package container // https://github.com/docker/cli/blob/master/cli/command/conta import ( "context" - "fmt" + "errors" "io" "runtime" "sync" @@ -12,6 +12,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/stdcopy" + "coopcloud.tech/abra/pkg/i18n" "github.com/moby/term" ) @@ -39,7 +40,7 @@ type hijackedIOStreamer struct { func (h *hijackedIOStreamer) stream(ctx context.Context) error { restoreInput, err := h.setupInput() if err != nil { - return fmt.Errorf("unable to setup input stream: %s", err) + return errors.New(i18n.G("unable to setup input stream: %s", err)) } defer restoreInput() @@ -78,7 +79,7 @@ func (h *hijackedIOStreamer) setupInput() (restore func(), err error) { } if err := setRawTerminal(h.streams); err != nil { - return nil, fmt.Errorf("unable to set IO streams as raw terminal: %s", err) + return nil, errors.New(i18n.G("unable to set IO streams as raw terminal: %s", err)) } // Use sync.Once so we may call restore multiple times but ensure we @@ -96,7 +97,7 @@ func (h *hijackedIOStreamer) setupInput() (restore func(), err error) { if h.detachKeys != "" { customEscapeKeys, err := term.ToBytes(h.detachKeys) if err != nil { - log.Warnf("invalid detach escape keys, using default: %s", err) + log.Warnf(i18n.G("invalid detach escape keys, using default: %s", err)) } else { escapeKeys = customEscapeKeys } @@ -128,10 +129,10 @@ func (h *hijackedIOStreamer) beginOutputStream(restoreInput func()) <-chan error _, err = stdcopy.StdCopy(h.outputStream, h.errorStream, h.resp.Reader) } - log.Debug("[hijack] End of stdout") + log.Debug(i18n.G("[hijack] end of stdout")) if err != nil { - log.Debugf("Error receiveStdout: %s", err) + log.Debug(i18n.G("error receiveStdout: %s", err)) } outputDone <- err @@ -152,7 +153,7 @@ func (h *hijackedIOStreamer) beginInputStream(restoreInput func()) (doneC <-chan // messages will be in normal type. restoreInput() - log.Debug("[hijack] End of stdin") + log.Debug(i18n.G("[hijack] End of stdin")) if _, ok := err.(term.EscapeError); ok { detached <- err @@ -163,12 +164,12 @@ func (h *hijackedIOStreamer) beginInputStream(restoreInput func()) (doneC <-chan // This error will also occur on the receive // side (from stdout) where it will be // propagated back to the caller. - log.Debugf("Error sendStdin: %s", err) + log.Debug(i18n.G("error sendStdin: %s", err)) } } if err := h.resp.CloseWrite(); err != nil { - log.Debugf("Couldn't send EOF: %s", err) + log.Debug(i18n.G("couldn't send EOF: %s", err)) } close(inputDone) diff --git a/pkg/upstream/container/tty.go b/pkg/upstream/container/tty.go index 2a5a55ae..0b975c35 100644 --- a/pkg/upstream/container/tty.go +++ b/pkg/upstream/container/tty.go @@ -8,6 +8,7 @@ import ( "runtime" "time" + "coopcloud.tech/abra/pkg/i18n" "coopcloud.tech/abra/pkg/log" "github.com/docker/cli/cli/command" "github.com/docker/docker/api/types/container" @@ -35,7 +36,7 @@ func resizeTtyTo(ctx context.Context, client client.ContainerAPIClient, id strin } if err != nil { - log.Debugf("Error resize: %s\r", err) + log.Debug(fmt.Sprintf("%s\r", i18n.G("error resize: %s", err))) } return err } @@ -62,7 +63,7 @@ func initTtySize(ctx context.Context, client *apiclient.Client, cli command.Cli, } } if err != nil { - fmt.Fprintln(cli.Err(), "failed to resize tty, using default size") + fmt.Fprintln(cli.Err(), i18n.G("failed to resize tty, using default size")) } }() } diff --git a/pkg/upstream/convert/service.go b/pkg/upstream/convert/service.go index 16cd0cfa..626c9a71 100644 --- a/pkg/upstream/convert/service.go +++ b/pkg/upstream/convert/service.go @@ -18,6 +18,7 @@ import ( "github.com/docker/docker/api/types/versions" "github.com/docker/docker/client" "github.com/docker/go-units" + "coopcloud.tech/abra/pkg/i18n" "github.com/pkg/errors" ) @@ -39,7 +40,7 @@ func ParseSecrets(client client.SecretAPIClient, requestedSecrets []*swarmtypes. for _, secret := range requestedSecrets { if _, exists := secretRefs[secret.File.Name]; exists { - return nil, errors.Errorf("duplicate secret target for %s not allowed", secret.SecretName) + return nil, errors.New(i18n.G("duplicate secret target for %s not allowed", secret.SecretName)) } secretRef := new(swarmtypes.SecretReference) *secretRef = *secret @@ -68,7 +69,7 @@ func ParseSecrets(client client.SecretAPIClient, requestedSecrets []*swarmtypes. for _, ref := range secretRefs { id, ok := foundSecrets[ref.SecretName] if !ok { - return nil, errors.Errorf("secret not found: %s", ref.SecretName) + return nil, errors.New(i18n.G("secret not found: %s", ref.SecretName)) } // set the id for the ref to properly assign in swarm @@ -118,7 +119,7 @@ func ParseConfigs(client client.ConfigAPIClient, requestedConfigs []*swarmtypes. } if _, exists := configRefs[config.File.Name]; exists { - return nil, errors.Errorf("duplicate config target for %s not allowed", config.ConfigName) + return nil, errors.New(i18n.G("duplicate config target for %s not allowed", config.ConfigName)) } configRefs[config.File.Name] = configRef @@ -149,7 +150,7 @@ func ParseConfigs(client client.ConfigAPIClient, requestedConfigs []*swarmtypes. for _, ref := range configRefs { id, ok := foundConfigs[ref.ConfigName] if !ok { - return nil, errors.Errorf("config not found: %s", ref.ConfigName) + return nil, errors.New(i18n.G("config not found: %s", ref.ConfigName)) } // set the id for the ref to properly assign in swarm @@ -164,7 +165,7 @@ func ParseConfigs(client client.ConfigAPIClient, requestedConfigs []*swarmtypes. for _, ref := range runtimeRefs { id, ok := foundConfigs[ref.ConfigName] if !ok { - return nil, errors.Errorf("config not found: %s", ref.ConfigName) + return nil, errors.New(i18n.G("config not found: %s", ref.ConfigName)) } ref.ConfigID = id @@ -371,7 +372,7 @@ func convertServiceNetworks( for networkName, network := range networks { networkConfig, ok := networkConfigs[networkName] if !ok && networkName != defaultNetwork { - return nil, errors.Errorf("undefined network %q", networkName) + return nil, errors.New(i18n.G("undefined network %q", networkName)) } var aliases []string if network != nil { @@ -410,7 +411,7 @@ func convertServiceSecrets( lookup := func(key string) (composetypes.FileObjectConfig, error) { secretSpec, exists := secretSpecs[key] if !exists { - return composetypes.FileObjectConfig{}, errors.Errorf("undefined secret %q", key) + return composetypes.FileObjectConfig{}, errors.New(i18n.G("undefined secret %q", key)) } return composetypes.FileObjectConfig(secretSpec), nil } @@ -458,7 +459,7 @@ func convertServiceConfigObjs( lookup := func(key string) (composetypes.FileObjectConfig, error) { configSpec, exists := configSpecs[key] if !exists { - return composetypes.FileObjectConfig{}, errors.Errorf("undefined config %q", key) + return composetypes.FileObjectConfig{}, errors.New(i18n.G("undefined config %q", key)) } return composetypes.FileObjectConfig(configSpec), nil } @@ -600,7 +601,7 @@ func convertHealthcheck(healthcheck *composetypes.HealthCheckConfig) (*container ) if healthcheck.Disable { if len(healthcheck.Test) != 0 { - return nil, errors.Errorf("test and disable can't be set at the same time") + return nil, errors.New(i18n.G("test and disable can't be set at the same time")) } return &container.HealthConfig{ Test: []string{"NONE"}, @@ -648,7 +649,7 @@ func convertRestartPolicy(restart string, source *composetypes.RestartPolicy) (* MaxAttempts: &attempts, }, nil default: - return nil, errors.Errorf("unknown restart policy: %s", restart) + return nil, errors.New(i18n.G("unknown restart policy: %s", restart)) } } @@ -770,13 +771,13 @@ func convertDeployMode(mode string, replicas *uint64) (swarm.ServiceMode, error) switch mode { case "global": if replicas != nil { - return serviceMode, errors.Errorf("replicas can only be used with replicated mode") + return serviceMode, errors.New(i18n.G("replicas can only be used with replicated mode")) } serviceMode.Global = &swarm.GlobalService{} case "replicated", "": serviceMode.Replicated = &swarm.ReplicatedService{Replicas: replicas} default: - return serviceMode, errors.Errorf("Unknown mode: %s", mode) + return serviceMode, errors.New(i18n.G("unknown mode: %s", mode)) } return serviceMode, nil } @@ -809,9 +810,9 @@ func convertCredentialSpec(namespace Namespace, spec composetypes.CredentialSpec case l == 0: return nil, nil case l == 2: - return nil, errors.Errorf("invalid credential spec: cannot specify both %s and %s", o[0], o[1]) + return nil, errors.New(i18n.G("invalid credential spec: cannot specify both %s and %s", o[0], o[1])) case l > 2: - return nil, errors.Errorf("invalid credential spec: cannot specify both %s, and %s", strings.Join(o[:l-1], ", "), o[l-1]) + return nil, errors.New(i18n.G("invalid credential spec: cannot specify both %s, and %s", strings.Join(o[:l-1], ", "), o[l-1])) } swarmCredSpec := swarm.CredentialSpec(spec) // if we're using a swarm Config for the credential spec, over-write it @@ -830,7 +831,7 @@ func convertCredentialSpec(namespace Namespace, spec composetypes.CredentialSpec return &swarmCredSpec, nil } } - return nil, errors.Errorf("invalid credential spec: spec specifies config %v, but no such config can be found", swarmCredSpec.Config) + return nil, errors.New(i18n.G("invalid credential spec: spec specifies config %v, but no such config can be found", swarmCredSpec.Config)) } return &swarmCredSpec, nil } diff --git a/pkg/upstream/convert/volume.go b/pkg/upstream/convert/volume.go index 387fb727..d7606592 100644 --- a/pkg/upstream/convert/volume.go +++ b/pkg/upstream/convert/volume.go @@ -3,6 +3,7 @@ package convert // https://github.com/docker/cli/blob/master/cli/compose/convert import ( composetypes "github.com/docker/cli/cli/compose/types" "github.com/docker/docker/api/types/mount" + "coopcloud.tech/abra/pkg/i18n" "github.com/pkg/errors" ) @@ -40,10 +41,10 @@ func handleVolumeToMount( result := createMountFromVolume(volume) if volume.Tmpfs != nil { - return mount.Mount{}, errors.New("tmpfs options are incompatible with type volume") + return mount.Mount{}, errors.New(i18n.G("tmpfs options are incompatible with type volume")) } if volume.Bind != nil { - return mount.Mount{}, errors.New("bind options are incompatible with type volume") + return mount.Mount{}, errors.New(i18n.G("bind options are incompatible with type volume")) } // Anonymous volumes if volume.Source == "" { @@ -52,7 +53,7 @@ func handleVolumeToMount( stackVolume, exists := stackVolumes[volume.Source] if !exists { - return mount.Mount{}, errors.Errorf("undefined volume %q", volume.Source) + return mount.Mount{}, errors.New(i18n.G("undefined volume %q", volume.Source)) } result.Source = namespace.Scope(volume.Source) @@ -86,13 +87,13 @@ func handleBindToMount(volume composetypes.ServiceVolumeConfig) (mount.Mount, er result := createMountFromVolume(volume) if volume.Source == "" { - return mount.Mount{}, errors.New("invalid bind source, source cannot be empty") + return mount.Mount{}, errors.New(i18n.G("invalid bind source, source cannot be empty")) } if volume.Volume != nil { - return mount.Mount{}, errors.New("volume options are incompatible with type bind") + return mount.Mount{}, errors.New(i18n.G("volume options are incompatible with type bind")) } if volume.Tmpfs != nil { - return mount.Mount{}, errors.New("tmpfs options are incompatible with type bind") + return mount.Mount{}, errors.New(i18n.G("tmpfs options are incompatible with type bind")) } if volume.Bind != nil { result.BindOptions = &mount.BindOptions{ @@ -106,13 +107,13 @@ func handleTmpfsToMount(volume composetypes.ServiceVolumeConfig) (mount.Mount, e result := createMountFromVolume(volume) if volume.Source != "" { - return mount.Mount{}, errors.New("invalid tmpfs source, source must be empty") + return mount.Mount{}, errors.New(i18n.G("invalid tmpfs source, source must be empty")) } if volume.Bind != nil { - return mount.Mount{}, errors.New("bind options are incompatible with type tmpfs") + return mount.Mount{}, errors.New(i18n.G("bind options are incompatible with type tmpfs")) } if volume.Volume != nil { - return mount.Mount{}, errors.New("volume options are incompatible with type tmpfs") + return mount.Mount{}, errors.New(i18n.G("volume options are incompatible with type tmpfs")) } if volume.Tmpfs != nil { result.TmpfsOptions = &mount.TmpfsOptions{ @@ -126,13 +127,13 @@ func handleNpipeToMount(volume composetypes.ServiceVolumeConfig) (mount.Mount, e result := createMountFromVolume(volume) if volume.Source == "" { - return mount.Mount{}, errors.New("invalid npipe source, source cannot be empty") + return mount.Mount{}, errors.New(i18n.G("invalid npipe source, source cannot be empty")) } if volume.Volume != nil { - return mount.Mount{}, errors.New("volume options are incompatible with type npipe") + return mount.Mount{}, errors.New(i18n.G("volume options are incompatible with type npipe")) } if volume.Tmpfs != nil { - return mount.Mount{}, errors.New("tmpfs options are incompatible with type npipe") + return mount.Mount{}, errors.New(i18n.G("tmpfs options are incompatible with type npipe")) } if volume.Bind != nil { result.BindOptions = &mount.BindOptions{ @@ -158,5 +159,5 @@ func convertVolumeToMount( case "npipe": return handleNpipeToMount(volume) } - return mount.Mount{}, errors.New("volume type must be volume, bind, tmpfs or npipe") + return mount.Mount{}, errors.New(i18n.G("volume type must be volume, bind, tmpfs or npipe")) } diff --git a/pkg/web/web.go b/pkg/web/web.go index b1f871ab..09f764ec 100644 --- a/pkg/web/web.go +++ b/pkg/web/web.go @@ -3,11 +3,13 @@ package web import ( "encoding/json" - "fmt" + "errors" "io" "net/http" "os" "time" + + "coopcloud.tech/abra/pkg/i18n" ) // Timeout is the time it takes before a web request bails out waiting for a @@ -40,7 +42,7 @@ func GetFile(filepath string, url string) (err error) { defer resp.Body.Close() if resp.StatusCode != http.StatusOK { - return fmt.Errorf("bad status: %s", resp.Status) + return errors.New(i18n.G("bad status: %s", resp.Status)) } _, err = io.Copy(out, resp.Body) diff --git a/vendor/modules.txt b/vendor/modules.txt index b6d67d59..0595f6a0 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -7,8 +7,6 @@ dario.cat/mergo # git.coopcloud.tech/toolshed/godotenv v1.5.2-0.20250103171850-4d0ca41daa5c ## explicit; go 1.12 git.coopcloud.tech/toolshed/godotenv -# github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 -## explicit; go 1.20 # github.com/AlecAivazis/survey/v2 v2.3.7 ## explicit; go 1.13 github.com/AlecAivazis/survey/v2 @@ -237,8 +235,6 @@ github.com/docker/docker/pkg/streamformatter ## explicit; go 1.21 github.com/docker/docker-credential-helpers/client github.com/docker/docker-credential-helpers/credentials -# github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c -## explicit # github.com/docker/go-connections v0.6.0 ## explicit; go 1.18 github.com/docker/go-connections/nat @@ -267,8 +263,6 @@ github.com/erikgeiser/coninput # github.com/felixge/httpsnoop v1.0.4 ## explicit; go 1.13 github.com/felixge/httpsnoop -# github.com/fsnotify/fsnotify v1.6.0 -## explicit; go 1.16 # github.com/fvbommel/sortorder v1.1.0 ## explicit; go 1.13 github.com/fvbommel/sortorder @@ -433,8 +427,6 @@ github.com/mgutz/ansi # github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db ## explicit github.com/mitchellh/colorstring -# github.com/mitchellh/mapstructure v1.5.0 -## explicit; go 1.14 # github.com/moby/docker-image-spec v1.3.1 ## explicit; go 1.18 github.com/moby/docker-image-spec/specs-go/v1 @@ -449,8 +441,6 @@ github.com/moby/patternmatcher # github.com/moby/sys/atomicwriter v0.1.0 ## explicit; go 1.18 github.com/moby/sys/atomicwriter -# github.com/moby/sys/mountinfo v0.7.2 -## explicit; go 1.17 # github.com/moby/sys/sequential v0.6.0 ## explicit; go 1.17 github.com/moby/sys/sequential @@ -494,8 +484,6 @@ github.com/opencontainers/image-spec/specs-go/v1 ## explicit; go 1.18 # github.com/opencontainers/runtime-spec v1.1.0 ## explicit -# github.com/pelletier/go-toml v1.9.5 -## explicit; go 1.12 # github.com/pjbgf/sha1cd v0.4.0 ## explicit; go 1.21 github.com/pjbgf/sha1cd