mirror of
https://github.com/podman-container-tools/podman.git
synced 2026-10-31 02:07:42 +00:00
Allow automatic generation for shell completion scripts with the internal cobra functions (requires v1.0.0+). This should replace the handwritten completion scripts and even adds support for fish. With this approach it is less likley that completions and code are out of sync. We can now create the scripts with - podman completion bash - podman completion zsh - podman completion fish To test the completion run: source <(podman completion bash) The same works for podman-remote and podman --remote and it will complete your remote containers/images with the correct endpoints values from --url/--connection. The completion logic is written in go and provided by the cobra library. The completion functions lives in `cmd/podman/completion/completion.go`. The unit test at cmd/podman/shell_completion_test.go checks if each command and flag has an autocompletion function set. This prevents that commands and flags have no shell completion set. This commit does not replace the current autocompletion scripts. Closes #6440 Signed-off-by: Paul Holzinger <paul.holzinger@web.de>
148 lines
4.7 KiB
Go
148 lines
4.7 KiB
Go
package pods
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/containers/common/pkg/completion"
|
|
"github.com/containers/common/pkg/report"
|
|
"github.com/containers/podman/v2/cmd/podman/common"
|
|
"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.
|
|
The generated units can later be controlled via systemctl(1).`
|
|
|
|
systemdCmd = &cobra.Command{
|
|
Use: "systemd [options] CTR|POD",
|
|
Short: "Generate systemd units.",
|
|
Long: systemdDescription,
|
|
RunE: systemd,
|
|
Args: cobra.ExactArgs(1),
|
|
ValidArgsFunction: common.AutocompleteContainersAndPods,
|
|
Example: `podman generate systemd CTR
|
|
podman generate systemd --new --time 10 CTR
|
|
podman generate systemd --files --name POD`,
|
|
}
|
|
)
|
|
|
|
func init() {
|
|
registry.Commands = append(registry.Commands, registry.CliCommand{
|
|
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(&files, "files", "f", false, "Generate .service files instead of printing to stdout")
|
|
|
|
timeFlagName := "time"
|
|
flags.UintVarP(&systemdTimeout, timeFlagName, "t", containerConfig.Engine.StopTimeout, "Stop timeout override")
|
|
_ = systemdCmd.RegisterFlagCompletionFunc(timeFlagName, completion.AutocompleteNone)
|
|
flags.BoolVarP(&systemdOptions.New, "new", "", false, "Create a new container instead of starting an existing one")
|
|
|
|
containerPrefixFlagName := "container-prefix"
|
|
flags.StringVar(&systemdOptions.ContainerPrefix, containerPrefixFlagName, "container", "Systemd unit name prefix for containers")
|
|
_ = systemdCmd.RegisterFlagCompletionFunc(containerPrefixFlagName, completion.AutocompleteNone)
|
|
|
|
podPrefixFlagName := "pod-prefix"
|
|
flags.StringVar(&systemdOptions.PodPrefix, podPrefixFlagName, "pod", "Systemd unit name prefix for pods")
|
|
_ = systemdCmd.RegisterFlagCompletionFunc(podPrefixFlagName, completion.AutocompleteNone)
|
|
|
|
separatorFlagName := "separator"
|
|
flags.StringVar(&systemdOptions.Separator, separatorFlagName, "-", "Systemd unit name separator between name/id and prefix")
|
|
_ = systemdCmd.RegisterFlagCompletionFunc(separatorFlagName, completion.AutocompleteNone)
|
|
|
|
restartPolicyFlagName := "restart-policy"
|
|
flags.StringVar(&systemdOptions.RestartPolicy, restartPolicyFlagName, "on-failure", "Systemd restart-policy")
|
|
_ = systemdCmd.RegisterFlagCompletionFunc(restartPolicyFlagName, common.AutocompleteSystemdRestartOptions)
|
|
|
|
formatFlagName := "format"
|
|
flags.StringVar(&format, formatFlagName, "", "Print the created units in specified format (json)")
|
|
_ = systemdCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat)
|
|
|
|
flags.SetNormalizeFunc(utils.AliasFlags)
|
|
}
|
|
|
|
func systemd(cmd *cobra.Command, args []string) error {
|
|
if cmd.Flags().Changed("time") {
|
|
systemdOptions.StopTimeout = &systemdTimeout
|
|
}
|
|
|
|
if registry.IsRemote() {
|
|
logrus.Warnln("The generated units should be placed on your remote system")
|
|
}
|
|
|
|
reports, err := registry.ContainerEngine().GenerateSystemd(registry.GetContext(), args[0], systemdOptions)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if files {
|
|
cwd, err := os.Getwd()
|
|
if err != nil {
|
|
return errors.Wrap(err, "error getting current working directory")
|
|
}
|
|
for name, content := range reports.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
|
|
reports.Units[name] = path
|
|
}
|
|
}
|
|
|
|
switch {
|
|
case report.IsJSON(format):
|
|
return printJSON(reports.Units)
|
|
case format == "":
|
|
return printDefault(reports.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
|
|
}
|