617 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			617 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Go
		
	
	
	
| package main
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"fmt"
 | |
| 	"os"
 | |
| 	"path/filepath"
 | |
| 	"strings"
 | |
| 
 | |
| 	"github.com/containers/buildah"
 | |
| 	"github.com/containers/libpod/cmd/podman/cliconfig"
 | |
| 	"github.com/containers/libpod/libpod"
 | |
| 	"github.com/containers/libpod/pkg/rootless"
 | |
| 	"github.com/containers/storage"
 | |
| 	"github.com/fatih/camelcase"
 | |
| 	jsoniter "github.com/json-iterator/go"
 | |
| 	"github.com/pkg/errors"
 | |
| 	"github.com/spf13/cobra"
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	stores = make(map[storage.Store]struct{})
 | |
| 	json   = jsoniter.ConfigCompatibleWithStandardLibrary
 | |
| )
 | |
| 
 | |
| const (
 | |
| 	idTruncLength = 12
 | |
| )
 | |
| 
 | |
| func splitCamelCase(src string) string {
 | |
| 	entries := camelcase.Split(src)
 | |
| 	return strings.Join(entries, " ")
 | |
| }
 | |
| 
 | |
| func shortID(id string) string {
 | |
| 	if len(id) > idTruncLength {
 | |
| 		return id[:idTruncLength]
 | |
| 	}
 | |
| 	return id
 | |
| }
 | |
| 
 | |
| // checkAllAndLatest checks that --all and --latest are used correctly
 | |
| func checkAllAndLatest(c *cobra.Command, args []string, ignoreArgLen bool) error {
 | |
| 	argLen := len(args)
 | |
| 	if c.Flags().Lookup("all") == nil || c.Flags().Lookup("latest") == nil {
 | |
| 		return errors.New("unable to lookup values for 'latest' or 'all'")
 | |
| 	}
 | |
| 	all, _ := c.Flags().GetBool("all")
 | |
| 	latest, _ := c.Flags().GetBool("latest")
 | |
| 	if all && latest {
 | |
| 		return errors.Errorf("--all and --latest cannot be used together")
 | |
| 	}
 | |
| 	if ignoreArgLen {
 | |
| 		return nil
 | |
| 	}
 | |
| 	if (all || latest) && argLen > 0 {
 | |
| 		return errors.Errorf("no arguments are needed with --all or --latest")
 | |
| 	}
 | |
| 	if argLen < 1 && !all && !latest {
 | |
| 		return errors.Errorf("you must provide at least one name or id")
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // noSubArgs checks that there are no further positional parameters
 | |
| func noSubArgs(c *cobra.Command, args []string) error {
 | |
| 	if len(args) > 0 {
 | |
| 		return errors.Errorf("`%s` takes no arguments", c.CommandPath())
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func commandRunE() func(*cobra.Command, []string) error {
 | |
| 	return func(cmd *cobra.Command, args []string) error {
 | |
| 		if len(args) > 0 {
 | |
| 			return errors.Errorf("unrecognized command `%s %s`\nTry '%s --help' for more information.", cmd.CommandPath(), args[0], cmd.CommandPath())
 | |
| 		} else {
 | |
| 			return errors.Errorf("missing command '%s COMMAND'\nTry '%s --help' for more information.", cmd.CommandPath(), cmd.CommandPath())
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // getAllOrLatestContainers tries to return the correct list of containers
 | |
| // depending if --all, --latest or <container-id> is used.
 | |
| // It requires the Context (c) and the Runtime (runtime). As different
 | |
| // commands are using different container state for the --all option
 | |
| // the desired state has to be specified in filterState. If no filter
 | |
| // is desired a -1 can be used to get all containers. For a better
 | |
| // error message, if the filter fails, a corresponding verb can be
 | |
| // specified which will then appear in the error message.
 | |
| func getAllOrLatestContainers(c *cliconfig.PodmanCommand, runtime *libpod.Runtime, filterState libpod.ContainerStatus, verb string) ([]*libpod.Container, error) {
 | |
| 	var containers []*libpod.Container
 | |
| 	var lastError error
 | |
| 	var err error
 | |
| 	if c.Bool("all") {
 | |
| 		if filterState != -1 {
 | |
| 			var filterFuncs []libpod.ContainerFilter
 | |
| 			filterFuncs = append(filterFuncs, func(c *libpod.Container) bool {
 | |
| 				state, _ := c.State()
 | |
| 				return state == filterState
 | |
| 			})
 | |
| 			containers, err = runtime.GetContainers(filterFuncs...)
 | |
| 		} else {
 | |
| 			containers, err = runtime.GetContainers()
 | |
| 		}
 | |
| 		if err != nil {
 | |
| 			return nil, errors.Wrapf(err, "unable to get %s containers", verb)
 | |
| 		}
 | |
| 	} else if c.Bool("latest") {
 | |
| 		lastCtr, err := runtime.GetLatestContainer()
 | |
| 		if err != nil {
 | |
| 			return nil, errors.Wrapf(err, "unable to get latest container")
 | |
| 		}
 | |
| 		containers = append(containers, lastCtr)
 | |
| 	} else {
 | |
| 		args := c.InputArgs
 | |
| 		for _, i := range args {
 | |
| 			container, err := runtime.LookupContainer(i)
 | |
| 			if err != nil {
 | |
| 				if lastError != nil {
 | |
| 					fmt.Fprintln(os.Stderr, lastError)
 | |
| 				}
 | |
| 				lastError = errors.Wrapf(err, "unable to find container %s", i)
 | |
| 			}
 | |
| 			if container != nil {
 | |
| 				// This is here to make sure this does not return [<nil>] but only nil
 | |
| 				containers = append(containers, container)
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return containers, lastError
 | |
| }
 | |
| 
 | |
| // getContext returns a non-nil, empty context
 | |
| func getContext() context.Context {
 | |
| 	if Ctx != nil {
 | |
| 		return Ctx
 | |
| 	}
 | |
| 	return context.TODO()
 | |
| }
 | |
| 
 | |
| func getDefaultNetwork() string {
 | |
| 	if rootless.IsRootless() {
 | |
| 		return "slirp4netns"
 | |
| 	}
 | |
| 	return "bridge"
 | |
| }
 | |
| 
 | |
| func getCreateFlags(c *cliconfig.PodmanCommand) {
 | |
| 
 | |
| 	createFlags := c.Flags()
 | |
| 
 | |
| 	createFlags.StringSlice(
 | |
| 		"add-host", []string{},
 | |
| 		"Add a custom host-to-IP mapping (host:ip) (default [])",
 | |
| 	)
 | |
| 	createFlags.StringSlice(
 | |
| 		"annotation", []string{},
 | |
| 		"Add annotations to container (key:value) (default [])",
 | |
| 	)
 | |
| 	createFlags.StringSliceP(
 | |
| 		"attach", "a", []string{},
 | |
| 		"Attach to STDIN, STDOUT or STDERR (default [])",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"authfile", getAuthFile(""),
 | |
| 		"Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"blkio-weight", "",
 | |
| 		"Block IO weight (relative weight) accepts a weight value between 10 and 1000.",
 | |
| 	)
 | |
| 	createFlags.StringSlice(
 | |
| 		"blkio-weight-device", []string{},
 | |
| 		"Block IO weight (relative device weight, format: `DEVICE_NAME:WEIGHT`)",
 | |
| 	)
 | |
| 	createFlags.StringSlice(
 | |
| 		"cap-add", []string{},
 | |
| 		"Add capabilities to the container",
 | |
| 	)
 | |
| 	createFlags.StringSlice(
 | |
| 		"cap-drop", []string{},
 | |
| 		"Drop capabilities from the container",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"cgroup-parent", "",
 | |
| 		"Optional parent cgroup for the container",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"cidfile", "",
 | |
| 		"Write the container ID to the file",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"conmon-pidfile", "",
 | |
| 		"Path to the file that will receive the PID of conmon",
 | |
| 	)
 | |
| 	createFlags.Uint64(
 | |
| 		"cpu-period", 0,
 | |
| 		"Limit the CPU CFS (Completely Fair Scheduler) period",
 | |
| 	)
 | |
| 	createFlags.Int64(
 | |
| 		"cpu-quota", 0,
 | |
| 		"Limit the CPU CFS (Completely Fair Scheduler) quota",
 | |
| 	)
 | |
| 	createFlags.Uint64(
 | |
| 		"cpu-rt-period", 0,
 | |
| 		"Limit the CPU real-time period in microseconds",
 | |
| 	)
 | |
| 	createFlags.Int64(
 | |
| 		"cpu-rt-runtime", 0,
 | |
| 		"Limit the CPU real-time runtime in microseconds",
 | |
| 	)
 | |
| 	createFlags.Uint64(
 | |
| 		"cpu-shares", 0,
 | |
| 		"CPU shares (relative weight)",
 | |
| 	)
 | |
| 	createFlags.Float64(
 | |
| 		"cpus", 0,
 | |
| 		"Number of CPUs. The default is 0.000 which means no limit",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"cpuset-cpus", "",
 | |
| 		"CPUs in which to allow execution (0-3, 0,1)",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"cpuset-mems", "",
 | |
| 		"Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems.",
 | |
| 	)
 | |
| 	createFlags.BoolP(
 | |
| 		"detach", "d", false,
 | |
| 		"Run container in background and print container ID",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"detach-keys", "",
 | |
| 		"Override the key sequence for detaching a container. Format is a single character `[a-Z]` or `ctrl-<value>` where `<value>` is one of: `a-z`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`",
 | |
| 	)
 | |
| 	createFlags.StringSlice(
 | |
| 		"device", []string{},
 | |
| 		"Add a host device to the container (default [])",
 | |
| 	)
 | |
| 	createFlags.StringSlice(
 | |
| 		"device-read-bps", []string{},
 | |
| 		"Limit read rate (bytes per second) from a device (e.g. --device-read-bps=/dev/sda:1mb)",
 | |
| 	)
 | |
| 	createFlags.StringSlice(
 | |
| 		"device-read-iops", []string{},
 | |
| 		"Limit read rate (IO per second) from a device (e.g. --device-read-iops=/dev/sda:1000)",
 | |
| 	)
 | |
| 	createFlags.StringSlice(
 | |
| 		"device-write-bps", []string{},
 | |
| 		"Limit write rate (bytes per second) to a device (e.g. --device-write-bps=/dev/sda:1mb)",
 | |
| 	)
 | |
| 	createFlags.StringSlice(
 | |
| 		"device-write-iops", []string{},
 | |
| 		"Limit write rate (IO per second) to a device (e.g. --device-write-iops=/dev/sda:1000)",
 | |
| 	)
 | |
| 	createFlags.StringSlice(
 | |
| 		"dns", []string{},
 | |
| 		"Set custom DNS servers",
 | |
| 	)
 | |
| 	createFlags.StringSlice(
 | |
| 		"dns-opt", []string{},
 | |
| 		"Set custom DNS options",
 | |
| 	)
 | |
| 	createFlags.StringSlice(
 | |
| 		"dns-search", []string{},
 | |
| 		"Set custom DNS search domains",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"entrypoint", "",
 | |
| 		"Overwrite the default ENTRYPOINT of the image",
 | |
| 	)
 | |
| 	createFlags.StringArrayP(
 | |
| 		"env", "e", []string{},
 | |
| 		"Set environment variables in container",
 | |
| 	)
 | |
| 	createFlags.StringSlice(
 | |
| 		"env-file", []string{},
 | |
| 		"Read in a file of environment variables",
 | |
| 	)
 | |
| 	createFlags.StringSlice(
 | |
| 		"expose", []string{},
 | |
| 		"Expose a port or a range of ports (default [])",
 | |
| 	)
 | |
| 	createFlags.StringSlice(
 | |
| 		"gidmap", []string{},
 | |
| 		"GID map to use for the user namespace",
 | |
| 	)
 | |
| 	createFlags.StringSlice(
 | |
| 		"group-add", []string{},
 | |
| 		"Add additional groups to join (default [])",
 | |
| 	)
 | |
| 	createFlags.Bool(
 | |
| 		"help", false, "",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"healthcheck-command", "",
 | |
| 		"set a healthcheck command for the container ('none' disables the existing healthcheck)",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"healthcheck-interval", cliconfig.DefaultHealthCheckInterval,
 | |
| 		"set an interval for the healthchecks (a value of disable results in no automatic timer setup)",
 | |
| 	)
 | |
| 	createFlags.Uint(
 | |
| 		"healthcheck-retries", cliconfig.DefaultHealthCheckRetries,
 | |
| 		"the number of retries allowed before a healthcheck is considered to be unhealthy",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"healthcheck-start-period", cliconfig.DefaultHealthCheckStartPeriod,
 | |
| 		"the initialization time needed for a container to bootstrap",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"healthcheck-timeout", cliconfig.DefaultHealthCheckTimeout,
 | |
| 		"the maximum time allowed to complete the healthcheck before an interval is considered failed",
 | |
| 	)
 | |
| 	createFlags.StringP(
 | |
| 		"hostname", "h", "",
 | |
| 		"Set container hostname",
 | |
| 	)
 | |
| 	createFlags.Bool(
 | |
| 		"http-proxy", true,
 | |
| 		"Set proxy environment variables in the container based on the host proxy vars",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"image-volume", cliconfig.DefaultImageVolume,
 | |
| 		"Tells podman how to handle the builtin image volumes. The options are: 'bind', 'tmpfs', or 'ignore'",
 | |
| 	)
 | |
| 	createFlags.Bool(
 | |
| 		"init", false,
 | |
| 		"Run an init binary inside the container that forwards signals and reaps processes",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"init-path", "",
 | |
| 		// Do not use  the Value field for setting the default value to determine user input (i.e., non-empty string)
 | |
| 		fmt.Sprintf("Path to the container-init binary (default: %q)", libpod.DefaultInitPath),
 | |
| 	)
 | |
| 	createFlags.BoolP(
 | |
| 		"interactive", "i", false,
 | |
| 		"Keep STDIN open even if not attached",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"ip", "",
 | |
| 		"Specify a static IPv4 address for the container",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"ipc", "",
 | |
| 		"IPC namespace to use",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"kernel-memory", "",
 | |
| 		"Kernel memory limit (format: `<number>[<unit>]`, where unit = b, k, m or g)",
 | |
| 	)
 | |
| 	createFlags.StringArrayP(
 | |
| 		"label", "l", []string{},
 | |
| 		"Set metadata on container (default [])",
 | |
| 	)
 | |
| 	createFlags.StringSlice(
 | |
| 		"label-file", []string{},
 | |
| 		"Read in a line delimited file of labels (default [])",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"log-driver", "",
 | |
| 		"Logging driver for the container",
 | |
| 	)
 | |
| 	createFlags.StringSlice(
 | |
| 		"log-opt", []string{},
 | |
| 		"Logging driver options (default [])",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"mac-address", "",
 | |
| 		"Container MAC address (e.g. 92:d0:c6:0a:29:33), not currently supported",
 | |
| 	)
 | |
| 	createFlags.StringP(
 | |
| 		"memory", "m", "",
 | |
| 		"Memory limit (format: <number>[<unit>], where unit = b, k, m or g)",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"memory-reservation", "",
 | |
| 		"Memory soft limit (format: <number>[<unit>], where unit = b, k, m or g)",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"memory-swap", "",
 | |
| 		"Swap limit equal to memory plus swap: '-1' to enable unlimited swap",
 | |
| 	)
 | |
| 	createFlags.Int64(
 | |
| 		"memory-swappiness", -1,
 | |
| 		"Tune container memory swappiness (0 to 100, or -1 for system default)",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"name", "",
 | |
| 		"Assign a name to the container",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"net", getDefaultNetwork(),
 | |
| 		"Connect a container to a network",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"network", getDefaultNetwork(),
 | |
| 		"Connect a container to a network",
 | |
| 	)
 | |
| 	createFlags.Bool(
 | |
| 		"no-hosts", false,
 | |
| 		"Do not create /etc/hosts within the container, instead use the version from the image",
 | |
| 	)
 | |
| 	createFlags.Bool(
 | |
| 		"oom-kill-disable", false,
 | |
| 		"Disable OOM Killer",
 | |
| 	)
 | |
| 	createFlags.Int(
 | |
| 		"oom-score-adj", 0,
 | |
| 		"Tune the host's OOM preferences (-1000 to 1000)",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"pid", "",
 | |
| 		"PID namespace to use",
 | |
| 	)
 | |
| 	createFlags.Int64(
 | |
| 		"pids-limit", 0,
 | |
| 		"Tune container pids limit (set -1 for unlimited)",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"pod", "",
 | |
| 		"Run container in an existing pod",
 | |
| 	)
 | |
| 	createFlags.Bool(
 | |
| 		"privileged", false,
 | |
| 		"Give extended privileges to container",
 | |
| 	)
 | |
| 	createFlags.StringSliceP(
 | |
| 		"publish", "p", []string{},
 | |
| 		"Publish a container's port, or a range of ports, to the host (default [])",
 | |
| 	)
 | |
| 	createFlags.BoolP(
 | |
| 		"publish-all", "P", false,
 | |
| 		"Publish all exposed ports to random ports on the host interface",
 | |
| 	)
 | |
| 	createFlags.BoolP(
 | |
| 		"quiet", "q", false,
 | |
| 		"Suppress output information when pulling images",
 | |
| 	)
 | |
| 	createFlags.Bool(
 | |
| 		"read-only", false,
 | |
| 		"Make containers root filesystem read-only",
 | |
| 	)
 | |
| 	createFlags.Bool(
 | |
| 		"read-only-tmpfs", true,
 | |
| 		"When running containers in read-only mode mount a read-write tmpfs on /run, /tmp and /var/tmp",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"restart", "",
 | |
| 		"Restart policy to apply when a container exits",
 | |
| 	)
 | |
| 	createFlags.Bool(
 | |
| 		"rm", false,
 | |
| 		"Remove container (and pod if created) after exit",
 | |
| 	)
 | |
| 	createFlags.Bool(
 | |
| 		"rootfs", false,
 | |
| 		"The first argument is not an image but the rootfs to the exploded container",
 | |
| 	)
 | |
| 	createFlags.StringArray(
 | |
| 		"security-opt", []string{},
 | |
| 		"Security Options (default [])",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"shm-size", cliconfig.DefaultShmSize,
 | |
| 		"Size of `/dev/shm`. The format is `<number><unit>`",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"stop-signal", "",
 | |
| 		"Signal to stop a container. Default is SIGTERM",
 | |
| 	)
 | |
| 	createFlags.Uint(
 | |
| 		"stop-timeout", libpod.CtrRemoveTimeout,
 | |
| 		"Timeout (in seconds) to stop a container. Default is 10",
 | |
| 	)
 | |
| 	createFlags.StringSlice(
 | |
| 		"storage-opt", []string{},
 | |
| 		"Storage driver options per container (default [])",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"subgidname", "",
 | |
| 		"Name of range listed in /etc/subgid for use in user namespace",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"subuidname", "",
 | |
| 		"Name of range listed in /etc/subuid for use in user namespace",
 | |
| 	)
 | |
| 
 | |
| 	createFlags.StringSlice(
 | |
| 		"sysctl", []string{},
 | |
| 		"Sysctl options (default [])",
 | |
| 	)
 | |
| 	createFlags.Bool(
 | |
| 		"systemd", cliconfig.DefaultSystemD,
 | |
| 		"Run container in systemd mode if the command executable is systemd or init",
 | |
| 	)
 | |
| 	createFlags.StringSlice(
 | |
| 		"tmpfs", []string{},
 | |
| 		"Mount a temporary filesystem (`tmpfs`) into a container (default [])",
 | |
| 	)
 | |
| 	createFlags.BoolP(
 | |
| 		"tty", "t", false,
 | |
| 		"Allocate a pseudo-TTY for container",
 | |
| 	)
 | |
| 	createFlags.StringSlice(
 | |
| 		"uidmap", []string{},
 | |
| 		"UID map to use for the user namespace",
 | |
| 	)
 | |
| 	createFlags.StringSlice(
 | |
| 		"ulimit", []string{},
 | |
| 		"Ulimit options (default [])",
 | |
| 	)
 | |
| 	createFlags.StringP(
 | |
| 		"user", "u", "",
 | |
| 		"Username or UID (format: <name|uid>[:<group|gid>])",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"userns", os.Getenv("PODMAN_USERNS"),
 | |
| 		"User namespace to use",
 | |
| 	)
 | |
| 	createFlags.String(
 | |
| 		"uts", "",
 | |
| 		"UTS namespace to use",
 | |
| 	)
 | |
| 	createFlags.StringArray(
 | |
| 		"mount", []string{},
 | |
| 		"Attach a filesystem mount to the container (default [])",
 | |
| 	)
 | |
| 	createFlags.StringArrayP(
 | |
| 		"volume", "v", []string{},
 | |
| 		"Bind mount a volume into the container (default [])",
 | |
| 	)
 | |
| 	createFlags.StringSlice(
 | |
| 		"volumes-from", []string{},
 | |
| 		"Mount volumes from the specified container(s) (default [])",
 | |
| 	)
 | |
| 	createFlags.StringP(
 | |
| 		"workdir", "w", "",
 | |
| 		"Working directory inside the container",
 | |
| 	)
 | |
| }
 | |
| 
 | |
| func getFormat(c *cliconfig.PodmanCommand) (string, error) {
 | |
| 	format := strings.ToLower(c.String("format"))
 | |
| 	if strings.HasPrefix(format, buildah.OCI) {
 | |
| 		return buildah.OCIv1ImageManifest, nil
 | |
| 	}
 | |
| 
 | |
| 	if strings.HasPrefix(format, buildah.DOCKER) {
 | |
| 		return buildah.Dockerv2ImageManifest, nil
 | |
| 	}
 | |
| 	return "", errors.Errorf("unrecognized image type %q", format)
 | |
| }
 | |
| 
 | |
| func getAuthFile(authfile string) string {
 | |
| 	if authfile != "" {
 | |
| 		return authfile
 | |
| 	}
 | |
| 	if remote {
 | |
| 		return ""
 | |
| 	}
 | |
| 	authfile = os.Getenv("REGISTRY_AUTH_FILE")
 | |
| 	if authfile != "" {
 | |
| 		return authfile
 | |
| 	}
 | |
| 	runtimeDir := os.Getenv("XDG_RUNTIME_DIR")
 | |
| 	if runtimeDir != "" {
 | |
| 		return filepath.Join(runtimeDir, "containers/auth.json")
 | |
| 	}
 | |
| 	return ""
 | |
| }
 | |
| 
 | |
| // scrubServer removes 'http://' or 'https://' from the front of the
 | |
| // server/registry string if either is there.  This will be mostly used
 | |
| // for user input from 'podman login' and 'podman logout'.
 | |
| func scrubServer(server string) string {
 | |
| 	server = strings.TrimPrefix(server, "https://")
 | |
| 	return strings.TrimPrefix(server, "http://")
 | |
| }
 | |
| 
 | |
| // HelpTemplate returns the help template for podman commands
 | |
| // This uses the short and long options.
 | |
| // command should not use this.
 | |
| func HelpTemplate() string {
 | |
| 	return `{{.Short}}
 | |
| 
 | |
| Description:
 | |
|   {{.Long}}
 | |
| 
 | |
| {{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`
 | |
| }
 | |
| 
 | |
| // UsageTemplate returns the usage template for podman commands
 | |
| // This blocks the desplaying of the global options. The main podman
 | |
| // command should not use this.
 | |
| func UsageTemplate() string {
 | |
| 	return `Usage:{{if (and .Runnable (not .HasAvailableSubCommands))}}
 | |
|   {{.UseLine}}{{end}}{{if .HasAvailableSubCommands}}
 | |
|   {{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}}
 | |
| 
 | |
| Aliases:
 | |
|   {{.NameAndAliases}}{{end}}{{if .HasExample}}
 | |
| 
 | |
| Examples:
 | |
|   {{.Example}}{{end}}{{if .HasAvailableSubCommands}}
 | |
| 
 | |
| Available Commands:{{range .Commands}}{{if (or .IsAvailableCommand (eq .Name "help"))}}
 | |
|   {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}}
 | |
| 
 | |
| Flags:
 | |
| {{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}}
 | |
| {{end}}
 | |
| `
 | |
| }
 |