forked from toolshed/abra
		
	| @ -10,6 +10,7 @@ import ( | ||||
| 	"coopcloud.tech/abra/pkg/config" | ||||
| 	contextPkg "coopcloud.tech/abra/pkg/context" | ||||
| 	"coopcloud.tech/abra/pkg/dns" | ||||
| 	"coopcloud.tech/abra/pkg/i18n" | ||||
| 	"coopcloud.tech/abra/pkg/log" | ||||
| 	"coopcloud.tech/abra/pkg/server" | ||||
| 	sshPkg "coopcloud.tech/abra/pkg/ssh" | ||||
| @ -17,10 +18,10 @@ import ( | ||||
| ) | ||||
|  | ||||
| var ServerAddCommand = &cobra.Command{ | ||||
| 	Use:     "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. | ||||
| 	Use:     i18n.G("add [[server] | --local] [flags]"), | ||||
| 	Aliases: []string{i18n.G("a")}, | ||||
| 	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 | ||||
| 	} | ||||
| @ -195,9 +196,9 @@ var ( | ||||
| func init() { | ||||
| 	ServerAddCommand.Flags().BoolVarP( | ||||
| 		&local, | ||||
| 		"local", | ||||
| 		"l", | ||||
| 		i18n.G("local"), | ||||
| 		i18n.G("l"), | ||||
| 		false, | ||||
| 		"use local server", | ||||
| 		i18n.G("use local server"), | ||||
| 	) | ||||
| } | ||||
|  | ||||
| @ -8,15 +8,16 @@ import ( | ||||
| 	"coopcloud.tech/abra/pkg/config" | ||||
| 	contextPkg "coopcloud.tech/abra/pkg/context" | ||||
| 	"coopcloud.tech/abra/pkg/formatter" | ||||
| 	"coopcloud.tech/abra/pkg/i18n" | ||||
| 	"coopcloud.tech/abra/pkg/log" | ||||
| 	"github.com/docker/cli/cli/connhelper/ssh" | ||||
| 	"github.com/spf13/cobra" | ||||
| ) | ||||
|  | ||||
| var ServerListCommand = &cobra.Command{ | ||||
| 	Use:     "list [flags]", | ||||
| 	Aliases: []string{"ls"}, | ||||
| 	Short:   "List managed servers", | ||||
| 	Use:     i18n.G("list [flags]"), | ||||
| 	Aliases: []string{i18n.G("ls")}, | ||||
| 	Short:   i18n.G("List managed servers"), | ||||
| 	Args:    cobra.NoArgs, | ||||
| 	Run: func(cmd *cobra.Command, args []string) { | ||||
| 		dockerContextStore := contextPkg.NewDefaultDockerContextStore() | ||||
| @ -30,7 +31,7 @@ var ServerListCommand = &cobra.Command{ | ||||
| 			log.Fatal(err) | ||||
| 		} | ||||
|  | ||||
| 		headers := []string{"NAME", "HOST"} | ||||
| 		headers := []string{i18n.G("NAME"), i18n.G("HOST")} | ||||
| 		table.Headers(headers...) | ||||
|  | ||||
| 		serverNames, err := config.ReadServerNames() | ||||
| @ -55,7 +56,7 @@ var ServerListCommand = &cobra.Command{ | ||||
| 					} | ||||
|  | ||||
| 					if sp.Host == "" { | ||||
| 						sp.Host = "unknown" | ||||
| 						sp.Host = i18n.G("unknown") | ||||
| 					} | ||||
|  | ||||
| 					row = []string{serverName, sp.Host} | ||||
| @ -65,9 +66,9 @@ var ServerListCommand = &cobra.Command{ | ||||
|  | ||||
| 			if len(row) == 0 { | ||||
| 				if serverName == "default" { | ||||
| 					row = []string{serverName, "local"} | ||||
| 					row = []string{serverName, i18n.G("local")} | ||||
| 				} else { | ||||
| 					row = []string{serverName, "unknown"} | ||||
| 					row = []string{serverName, i18n.G("unknown")} | ||||
| 				} | ||||
| 				rows = append(rows, row) | ||||
| 			} | ||||
| @ -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) | ||||
| @ -95,9 +96,9 @@ var ServerListCommand = &cobra.Command{ | ||||
| func init() { | ||||
| 	ServerListCommand.Flags().BoolVarP( | ||||
| 		&internal.MachineReadable, | ||||
| 		"machine", | ||||
| 		"m", | ||||
| 		i18n.G("machine"), | ||||
| 		i18n.G("m"), | ||||
| 		false, | ||||
| 		"print machine-readable output", | ||||
| 		i18n.G("print machine-readable output"), | ||||
| 	) | ||||
| } | ||||
|  | ||||
| @ -5,19 +5,20 @@ 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" | ||||
| 	"github.com/docker/docker/api/types/filters" | ||||
| 	"github.com/spf13/cobra" | ||||
| ) | ||||
|  | ||||
| var ServerPruneCommand = &cobra.Command{ | ||||
| 	Use:     "prune <server> [flags]", | ||||
| 	Aliases: []string{"p"}, | ||||
| 	Short:   "Prune resources on a server", | ||||
| 	Long: `Prunes unused containers, networks, and dangling images. | ||||
| 	Use:     i18n.G("prune <server> [flags]"), | ||||
| 	Aliases: []string{i18n.G("p")}, | ||||
| 	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 | ||||
| @ -86,17 +87,17 @@ var ( | ||||
| func init() { | ||||
| 	ServerPruneCommand.Flags().BoolVarP( | ||||
| 		&allFilter, | ||||
| 		"all", | ||||
| 		"a", | ||||
| 		i18n.G("all"), | ||||
| 		i18n.G("a"), | ||||
| 		false, | ||||
| 		"remove all unused images", | ||||
| 		i18n.G("remove all unused images"), | ||||
| 	) | ||||
|  | ||||
| 	ServerPruneCommand.Flags().BoolVarP( | ||||
| 		&volumesFilter, | ||||
| 		"volumes", | ||||
| 		"v", | ||||
| 		i18n.G("volumes"), | ||||
| 		i18n.G("v"), | ||||
| 		false, | ||||
| 		"remove volumes", | ||||
| 		i18n.G("remove volumes"), | ||||
| 	) | ||||
| } | ||||
|  | ||||
| @ -8,19 +8,20 @@ import ( | ||||
| 	"coopcloud.tech/abra/pkg/autocomplete" | ||||
| 	"coopcloud.tech/abra/pkg/client" | ||||
| 	"coopcloud.tech/abra/pkg/config" | ||||
| 	"coopcloud.tech/abra/pkg/i18n" | ||||
| 	"coopcloud.tech/abra/pkg/log" | ||||
| 	"github.com/spf13/cobra" | ||||
| ) | ||||
|  | ||||
| var ServerRemoveCommand = &cobra.Command{ | ||||
| 	Use:     "remove <server> [flags]", | ||||
| 	Aliases: []string{"rm"}, | ||||
| 	Short:   "Remove a managed server", | ||||
| 	Long: `Remove a managed server. | ||||
| 	Use:     i18n.G("remove <server> [flags]"), | ||||
| 	Aliases: []string{i18n.G("rm")}, | ||||
| 	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 | ||||
| 	}, | ||||
|  | ||||
| @ -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]", | ||||
| 	Aliases: []string{"s"}, | ||||
| 	Short:   "Manage servers", | ||||
| 	Use:     i18n.G("server [cmd] [args] [flags]"), | ||||
| 	Aliases: []string{i18n.G("s")}, | ||||
| 	Short:   i18n.G("Manage servers"), | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user