From ebfea2f4f89328ec3f74a8deedb3e727ce89ea59 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Wed, 5 Aug 2020 09:29:59 +0200 Subject: APIv2 add generate systemd endpoint Add support for generating systemd units via the api and podman-remote. Change the GenerateSystemdReport type to return the units as map[string]string with the unit name as key. Add `--format` flag to `podman generate systemd` to allow the output to be formatted as json. Signed-off-by: Paul Holzinger --- cmd/podman/generate/systemd.go | 71 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 3 deletions(-) (limited to 'cmd') diff --git a/cmd/podman/generate/systemd.go b/cmd/podman/generate/systemd.go index 851a104bc..f690836a4 100644 --- a/cmd/podman/generate/systemd.go +++ b/cmd/podman/generate/systemd.go @@ -1,15 +1,22 @@ package pods import ( + "encoding/json" "fmt" + "os" + "path/filepath" "github.com/containers/podman/v2/cmd/podman/registry" "github.com/containers/podman/v2/cmd/podman/utils" "github.com/containers/podman/v2/pkg/domain/entities" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) var ( + files bool + format string systemdTimeout uint systemdOptions = entities.GenerateSystemdOptions{} systemdDescription = `Generate systemd units for a pod or container. @@ -29,19 +36,20 @@ var ( func init() { registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode}, + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, Command: systemdCmd, Parent: generateCmd, }) flags := systemdCmd.Flags() flags.BoolVarP(&systemdOptions.Name, "name", "n", false, "Use container/pod names instead of IDs") - flags.BoolVarP(&systemdOptions.Files, "files", "f", false, "Generate .service files instead of printing to stdout") + flags.BoolVarP(&files, "files", "f", false, "Generate .service files instead of printing to stdout") flags.UintVarP(&systemdTimeout, "time", "t", containerConfig.Engine.StopTimeout, "Stop timeout override") flags.StringVar(&systemdOptions.RestartPolicy, "restart-policy", "on-failure", "Systemd restart-policy") flags.BoolVarP(&systemdOptions.New, "new", "", false, "Create a new container instead of starting an existing one") flags.StringVar(&systemdOptions.ContainerPrefix, "container-prefix", "container", "Systemd unit name prefix for containers") flags.StringVar(&systemdOptions.PodPrefix, "pod-prefix", "pod", "Systemd unit name prefix for pods") flags.StringVar(&systemdOptions.Separator, "separator", "-", "Systemd unit name separator between name/id and prefix") + flags.StringVar(&format, "format", "", "Print the created units in specified format (json)") flags.SetNormalizeFunc(utils.AliasFlags) } @@ -50,11 +58,68 @@ func systemd(cmd *cobra.Command, args []string) error { systemdOptions.StopTimeout = &systemdTimeout } + if registry.IsRemote() { + logrus.Warnln("The generated units should be placed on your remote system") + } + report, err := registry.ContainerEngine().GenerateSystemd(registry.GetContext(), args[0], systemdOptions) if err != nil { return err } - fmt.Println(report.Output) + if files { + cwd, err := os.Getwd() + if err != nil { + return errors.Wrap(err, "error getting current working directory") + } + for name, content := range report.Units { + path := filepath.Join(cwd, fmt.Sprintf("%s.service", name)) + f, err := os.Create(path) + if err != nil { + return err + } + _, err = f.WriteString(content) + if err != nil { + return err + } + err = f.Close() + if err != nil { + return err + } + + // add newline if default format is given + if format == "" { + path += "\n" + } + // modify in place so we can print the + // paths when --files is set + report.Units[name] = path + } + } + + switch format { + case "json": + return printJSON(report.Units) + case "": + return printDefault(report.Units) + default: + return errors.Errorf("unknown --format argument: %s", format) + } + +} + +func printDefault(units map[string]string) error { + for _, content := range units { + fmt.Print(content) + } + return nil +} + +func printJSON(units map[string]string) error { + b, err := json.MarshalIndent(units, "", " ") + if err != nil { + return err + } + fmt.Println(string(b)) return nil } -- cgit v1.2.3-54-g00ecf