diff options
Diffstat (limited to 'cmd/podmanV2')
86 files changed, 0 insertions, 7818 deletions
diff --git a/cmd/podmanV2/Makefile b/cmd/podmanV2/Makefile deleted file mode 100644 index b847a9385..000000000 --- a/cmd/podmanV2/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - CGO_ENABLED=1 GO111MODULE=off go build -tags 'ABISupport systemd seccomp' diff --git a/cmd/podmanV2/README.md b/cmd/podmanV2/README.md deleted file mode 100644 index a17e6f850..000000000 --- a/cmd/podmanV2/README.md +++ /dev/null @@ -1,113 +0,0 @@ -# Adding a podman V2 commands - -## Build podman V2 - -```shell script -$ cd $GOPATH/src/github.com/containers/libpod/cmd/podmanV2 -``` -If you wish to include the libpod library in your program, -```shell script -$ go build -tags 'ABISupport' . -``` -The `--remote` flag may be used to connect to the Podman service using the API. -Otherwise, direct calls will be made to the Libpod library. -```shell script -$ go build -tags '!ABISupport' . -``` -The Libpod library is not linked into the executable. -All calls are made via the API and `--remote=False` is an error condition. - -## Adding a new command `podman manifests` -```shell script -$ mkdir -p $GOPATH/src/github.com/containers/libpod/cmd/podmanV2/manifests -``` -Create the file ```$GOPATH/src/github.com/containers/libpod/cmd/podmanV2/manifests/manifest.go``` -```go -package manifests - -import ( - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - // podman _manifests_ - manifestCmd = &cobra.Command{ - Use: "manifest", - Short: "Manage manifests", - Long: "Manage manifests", - Example: "podman manifests IMAGE", - TraverseChildren: true, - PersistentPreRunE: preRunE, - RunE: registry.SubCommandExists, // Report error if there is no sub command given - } -) -func init() { - // Subscribe command to podman - registry.Commands = append(registry.Commands, registry.CliCommand{ - // _podman manifest_ will support both ABIMode and TunnelMode - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - // The definition for this command - Command: manifestCmd, - }) - // Setup cobra templates, sub commands will inherit - manifestCmd.SetHelpTemplate(registry.HelpTemplate()) - manifestCmd.SetUsageTemplate(registry.UsageTemplate()) -} - -// preRunE populates the image engine for sub commands -func preRunE(cmd *cobra.Command, args []string) error { - _, err := registry.NewImageEngine(cmd, args) - return err -} -``` -To "wire" in the `manifest` command, edit the file ```$GOPATH/src/github.com/containers/libpod/cmd/podmanV2/main.go``` to add: -```go -package main - -import _ "github.com/containers/libpod/cmd/podmanV2/manifests" -``` - -## Adding a new sub command `podman manifests list` -Create the file ```$GOPATH/src/github.com/containers/libpod/cmd/podmanV2/manifests/inspect.go``` -```go -package manifests - -import ( - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - // podman manifests _inspect_ - inspectCmd = &cobra.Command{ - Use: "inspect IMAGE", - Short: "Display manifest from image", - Long: "Displays the low-level information on a manifest identified by image name or ID", - RunE: inspect, - Example: "podman manifest DEADBEEF", - } -) - -func init() { - // Subscribe inspect sub command to manifest command - registry.Commands = append(registry.Commands, registry.CliCommand{ - // _podman manifest inspect_ will support both ABIMode and TunnelMode - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - // The definition for this command - Command: inspectCmd, - Parent: manifestCmd, - }) - - // This is where you would configure the cobra flags using inspectCmd.Flags() -} - -// Business logic: cmd is inspectCmd, args is the positional arguments from os.Args -func inspect(cmd *cobra.Command, args []string) error { - // Business logic using registry.ImageEngine - // Do not pull from libpod directly use the domain objects and types - return nil -} -``` diff --git a/cmd/podmanV2/common/create.go b/cmd/podmanV2/common/create.go deleted file mode 100644 index e2eb8cbda..000000000 --- a/cmd/podmanV2/common/create.go +++ /dev/null @@ -1,533 +0,0 @@ -package common - -import ( - "fmt" - "os" - - buildahcli "github.com/containers/buildah/pkg/cli" - "github.com/containers/common/pkg/config" - "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/sirupsen/logrus" - "github.com/spf13/pflag" -) - -const ( - sizeWithUnitFormat = "(format: `<number>[<unit>]`, where unit = b (bytes), k (kilobytes), m (megabytes), or g (gigabytes))" -) - -var ( - defaultContainerConfig = getDefaultContainerConfig() -) - -func getDefaultContainerConfig() *config.Config { - defaultContainerConfig, err := config.Default() - if err != nil { - logrus.Error(err) - os.Exit(1) - } - return defaultContainerConfig -} - -func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet { - createFlags := pflag.FlagSet{} - createFlags.StringSliceVar( - &cf.Annotation, - "annotation", []string{}, - "Add annotations to container (key:value)", - ) - createFlags.StringSliceVarP( - &cf.Attach, - "attach", "a", []string{}, - "Attach to STDIN, STDOUT or STDERR", - ) - createFlags.StringVar( - &cf.Authfile, - "authfile", buildahcli.GetDefaultAuthFile(), - "Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override", - ) - createFlags.StringVar( - &cf.BlkIOWeight, - "blkio-weight", "", - "Block IO weight (relative weight) accepts a weight value between 10 and 1000.", - ) - createFlags.StringSliceVar( - &cf.BlkIOWeightDevice, - "blkio-weight-device", []string{}, - "Block IO weight (relative device weight, format: `DEVICE_NAME:WEIGHT`)", - ) - createFlags.StringSliceVar( - &cf.CapAdd, - "cap-add", []string{}, - "Add capabilities to the container", - ) - createFlags.StringSliceVar( - &cf.CapDrop, - "cap-drop", []string{}, - "Drop capabilities from the container", - ) - createFlags.StringVar( - &cf.CGroupsNS, - "cgroupns", getDefaultCgroupNS(), - "cgroup namespace to use", - ) - createFlags.StringVar( - &cf.CGroups, - "cgroups", "enabled", - `control container cgroup configuration ("enabled"|"disabled"|"no-conmon")`, - ) - createFlags.StringVar( - &cf.CGroupParent, - "cgroup-parent", "", - "Optional parent cgroup for the container", - ) - createFlags.StringVar( - &cf.CIDFile, - "cidfile", "", - "Write the container ID to the file", - ) - createFlags.StringVar( - &cf.ConmonPIDFile, - "conmon-pidfile", "", - "Path to the file that will receive the PID of conmon", - ) - createFlags.Uint64Var( - &cf.CPUPeriod, - "cpu-period", 0, - "Limit the CPU CFS (Completely Fair Scheduler) period", - ) - createFlags.Int64Var( - &cf.CPUQuota, - "cpu-quota", 0, - "Limit the CPU CFS (Completely Fair Scheduler) quota", - ) - createFlags.Uint64Var( - &cf.CPURTPeriod, - "cpu-rt-period", 0, - "Limit the CPU real-time period in microseconds", - ) - createFlags.Int64Var( - &cf.CPURTRuntime, - "cpu-rt-runtime", 0, - "Limit the CPU real-time runtime in microseconds", - ) - createFlags.Uint64Var( - &cf.CPUShares, - "cpu-shares", 0, - "CPU shares (relative weight)", - ) - createFlags.Float64Var( - &cf.CPUS, - "cpus", 0, - "Number of CPUs. The default is 0.000 which means no limit", - ) - createFlags.StringVar( - &cf.CPUSetCPUs, - "cpuset-cpus", "", - "CPUs in which to allow execution (0-3, 0,1)", - ) - createFlags.StringVar( - &cf.CPUSetMems, - "cpuset-mems", "", - "Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems.", - ) - createFlags.BoolVarP( - &cf.Detach, - "detach", "d", false, - "Run container in background and print container ID", - ) - createFlags.StringVar( - &cf.DetachKeys, - "detach-keys", GetDefaultDetachKeys(), - "Override the key sequence for detaching a container. Format is a single character `[a-Z]` or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-cf`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`", - ) - createFlags.StringSliceVar( - &cf.Device, - "device", getDefaultDevices(), - fmt.Sprintf("Add a host device to the container"), - ) - createFlags.StringSliceVar( - &cf.DeviceCGroupRule, - "device-cgroup-rule", []string{}, - "Add a rule to the cgroup allowed devices list", - ) - createFlags.StringSliceVar( - &cf.DeviceReadBPs, - "device-read-bps", []string{}, - "Limit read rate (bytes per second) from a device (e.g. --device-read-bps=/dev/sda:1mb)", - ) - createFlags.StringSliceVar( - &cf.DeviceReadIOPs, - "device-read-iops", []string{}, - "Limit read rate (IO per second) from a device (e.g. --device-read-iops=/dev/sda:1000)", - ) - createFlags.StringSliceVar( - &cf.DeviceWriteBPs, - "device-write-bps", []string{}, - "Limit write rate (bytes per second) to a device (e.g. --device-write-bps=/dev/sda:1mb)", - ) - createFlags.StringSliceVar( - &cf.DeviceWriteIOPs, - "device-write-iops", []string{}, - "Limit write rate (IO per second) to a device (e.g. --device-write-iops=/dev/sda:1000)", - ) - createFlags.StringVar( - &cf.Entrypoint, - "entrypoint", "", - "Overwrite the default ENTRYPOINT of the image", - ) - createFlags.StringArrayVarP( - &cf.env, - "env", "e", getDefaultEnv(), - "Set environment variables in container", - ) - createFlags.BoolVar( - &cf.EnvHost, - "env-host", false, "Use all current host environment variables in container", - ) - createFlags.StringSliceVar( - &cf.EnvFile, - "env-file", []string{}, - "Read in a file of environment variables", - ) - createFlags.StringSliceVar( - &cf.Expose, - "expose", []string{}, - "Expose a port or a range of ports", - ) - createFlags.StringSliceVar( - &cf.GIDMap, - "gidmap", []string{}, - "GID map to use for the user namespace", - ) - createFlags.StringSliceVar( - &cf.GroupAdd, - "group-add", []string{}, - "Add additional groups to join", - ) - createFlags.Bool( - "help", false, "", - ) - createFlags.StringVar( - &cf.HealthCmd, - "health-cmd", "", - "set a healthcheck command for the container ('none' disables the existing healthcheck)", - ) - createFlags.StringVar( - &cf.HealthInterval, - "health-interval", cliconfig.DefaultHealthCheckInterval, - "set an interval for the healthchecks (a value of disable results in no automatic timer setup)", - ) - createFlags.UintVar( - &cf.HealthRetries, - "health-retries", cliconfig.DefaultHealthCheckRetries, - "the number of retries allowed before a healthcheck is considered to be unhealthy", - ) - createFlags.StringVar( - &cf.HealthStartPeriod, - "health-start-period", cliconfig.DefaultHealthCheckStartPeriod, - "the initialization time needed for a container to bootstrap", - ) - createFlags.StringVar( - &cf.HealthTimeout, - "health-timeout", cliconfig.DefaultHealthCheckTimeout, - "the maximum time allowed to complete the healthcheck before an interval is considered failed", - ) - createFlags.StringVarP( - &cf.Hostname, - "hostname", "h", "", - "Set container hostname", - ) - createFlags.BoolVar( - &cf.HTTPProxy, - "http-proxy", true, - "Set proxy environment variables in the container based on the host proxy vars", - ) - createFlags.StringVar( - &cf.ImageVolume, - "image-volume", cliconfig.DefaultImageVolume, - `Tells podman how to handle the builtin image volumes ("bind"|"tmpfs"|"ignore")`, - ) - createFlags.BoolVar( - &cf.Init, - "init", false, - "Run an init binary inside the container that forwards signals and reaps processes", - ) - createFlags.StringVar( - &cf.InitPath, - "init-path", getDefaultInitPath(), - // 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"), - ) - createFlags.BoolVarP( - &cf.Interactive, - "interactive", "i", false, - "Keep STDIN open even if not attached", - ) - createFlags.StringVar( - &cf.IPC, - "ipc", getDefaultIPCNS(), - "IPC namespace to use", - ) - createFlags.StringVar( - &cf.KernelMemory, - "kernel-memory", "", - "Kernel memory limit "+sizeWithUnitFormat, - ) - createFlags.StringArrayVarP( - &cf.Label, - "label", "l", []string{}, - "Set metadata on container", - ) - createFlags.StringSliceVar( - &cf.LabelFile, - "label-file", []string{}, - "Read in a line delimited file of labels", - ) - createFlags.StringVar( - &cf.LogDriver, - "log-driver", "", - "Logging driver for the container", - ) - createFlags.StringSliceVar( - &cf.LogOptions, - "log-opt", []string{}, - "Logging driver options", - ) - createFlags.StringVarP( - &cf.Memory, - "memory", "m", "", - "Memory limit "+sizeWithUnitFormat, - ) - createFlags.StringVar( - &cf.MemoryReservation, - "memory-reservation", "", - "Memory soft limit "+sizeWithUnitFormat, - ) - createFlags.StringVar( - &cf.MemorySwap, - "memory-swap", "", - "Swap limit equal to memory plus swap: '-1' to enable unlimited swap", - ) - createFlags.Int64Var( - &cf.MemorySwappiness, - "memory-swappiness", -1, - "Tune container memory swappiness (0 to 100, or -1 for system default)", - ) - createFlags.StringVar( - &cf.Name, - "name", "", - "Assign a name to the container", - ) - createFlags.BoolVar( - &cf.NoHealthCheck, - "no-healthcheck", false, - "Disable healthchecks on container", - ) - createFlags.BoolVar( - &cf.OOMKillDisable, - "oom-kill-disable", false, - "Disable OOM Killer", - ) - createFlags.IntVar( - &cf.OOMScoreAdj, - "oom-score-adj", 0, - "Tune the host's OOM preferences (-1000 to 1000)", - ) - createFlags.StringVar( - &cf.OverrideArch, - "override-arch", "", - "use `ARCH` instead of the architecture of the machine for choosing images", - ) - //markFlagHidden(createFlags, "override-arch") - createFlags.StringVar( - &cf.OverrideOS, - "override-os", "", - "use `OS` instead of the running OS for choosing images", - ) - //markFlagHidden(createFlags, "override-os") - createFlags.StringVar( - &cf.PID, - "pid", getDefaultPidNS(), - "PID namespace to use", - ) - createFlags.Int64Var( - &cf.PIDsLimit, - "pids-limit", getDefaultPidsLimit(), - getDefaultPidsDescription(), - ) - createFlags.StringVar( - &cf.Pod, - "pod", "", - "Run container in an existing pod", - ) - createFlags.BoolVar( - &cf.Privileged, - "privileged", false, - "Give extended privileges to container", - ) - createFlags.BoolVarP( - &cf.PublishAll, - "publish-all", "P", false, - "Publish all exposed ports to random ports on the host interface", - ) - createFlags.StringVar( - &cf.Pull, - "pull", "missing", - `Pull image before creating ("always"|"missing"|"never")`, - ) - createFlags.BoolVarP( - &cf.Quiet, - "quiet", "q", false, - "Suppress output information when pulling images", - ) - createFlags.BoolVar( - &cf.ReadOnly, - "read-only", false, - "Make containers root filesystem read-only", - ) - createFlags.BoolVar( - &cf.ReadOnlyTmpFS, - "read-only-tmpfs", true, - "When running containers in read-only mode mount a read-write tmpfs on /run, /tmp and /var/tmp", - ) - createFlags.StringVar( - &cf.Restart, - "restart", "", - `Restart policy to apply when a container exits ("always"|"no"|"on-failure")`, - ) - createFlags.BoolVar( - &cf.Rm, - "rm", false, - "Remove container (and pod if created) after exit", - ) - createFlags.BoolVar( - &cf.RootFS, - "rootfs", false, - "The first argument is not an image but the rootfs to the exploded container", - ) - createFlags.StringArrayVar( - &cf.SecurityOpt, - "security-opt", getDefaultSecurityOptions(), - fmt.Sprintf("Security Options"), - ) - createFlags.StringVar( - &cf.ShmSize, - "shm-size", getDefaultShmSize(), - "Size of /dev/shm "+sizeWithUnitFormat, - ) - createFlags.StringVar( - &cf.StopSignal, - "stop-signal", "", - "Signal to stop a container. Default is SIGTERM", - ) - createFlags.UintVar( - &cf.StopTimeout, - "stop-timeout", defaultContainerConfig.Engine.StopTimeout, - "Timeout (in seconds) to stop a container. Default is 10", - ) - createFlags.StringSliceVar( - &cf.StoreageOpt, - "storage-opt", []string{}, - "Storage driver options per container", - ) - createFlags.StringVar( - &cf.SubUIDName, - "subgidname", "", - "Name of range listed in /etc/subgid for use in user namespace", - ) - createFlags.StringVar( - &cf.SubGIDName, - "subuidname", "", - "Name of range listed in /etc/subuid for use in user namespace", - ) - - createFlags.StringSliceVar( - &cf.Sysctl, - "sysctl", getDefaultSysctls(), - "Sysctl options", - ) - createFlags.StringVar( - &cf.SystemdD, - "systemd", "true", - `Run container in systemd mode ("true"|"false"|"always")`, - ) - createFlags.StringArrayVar( - &cf.TmpFS, - "tmpfs", []string{}, - "Mount a temporary filesystem (`tmpfs`) into a container", - ) - createFlags.BoolVarP( - &cf.TTY, - "tty", "t", false, - "Allocate a pseudo-TTY for container", - ) - createFlags.StringSliceVar( - &cf.UIDMap, - "uidmap", []string{}, - "UID map to use for the user namespace", - ) - createFlags.StringSliceVar( - &cf.Ulimit, - "ulimit", getDefaultUlimits(), - "Ulimit options", - ) - createFlags.StringVarP( - &cf.User, - "user", "u", "", - "Username or UID (format: <name|uid>[:<group|gid>])", - ) - createFlags.StringVar( - &cf.UserNS, - "userns", getDefaultUserNS(), - "User namespace to use", - ) - createFlags.StringVar( - &cf.UTS, - "uts", getDefaultUTSNS(), - "UTS namespace to use", - ) - createFlags.StringArrayVar( - &cf.Mount, - "mount", []string{}, - "Attach a filesystem mount to the container", - ) - createFlags.StringArrayVarP( - &cf.Volume, - "volume", "v", getDefaultVolumes(), - "Bind mount a volume into the container", - ) - createFlags.StringSliceVar( - &cf.VolumesFrom, - "volumes-from", []string{}, - "Mount volumes from the specified container(s)", - ) - createFlags.StringVarP( - &cf.Workdir, - "workdir", "w", "", - "Working directory inside the container", - ) - createFlags.StringVar( - &cf.SeccompPolicy, - "seccomp-policy", "default", - "Policy for selecting a seccomp profile (experimental)", - ) - return &createFlags -} - -func AliasFlags(f *pflag.FlagSet, name string) pflag.NormalizedName { - switch name { - case "healthcheck-command": - name = "health-cmd" - case "healthcheck-interval": - name = "health-interval" - case "healthcheck-retries": - name = "health-retries" - case "healthcheck-start-period": - name = "health-start-period" - case "healthcheck-timeout": - name = "health-timeout" - case "net": - name = "network" - } - return pflag.NormalizedName(name) -} diff --git a/cmd/podmanV2/common/create_opts.go b/cmd/podmanV2/common/create_opts.go deleted file mode 100644 index 9d12e4b26..000000000 --- a/cmd/podmanV2/common/create_opts.go +++ /dev/null @@ -1,103 +0,0 @@ -package common - -import "github.com/containers/libpod/pkg/domain/entities" - -type ContainerCLIOpts struct { - Annotation []string - Attach []string - Authfile string - BlkIOWeight string - BlkIOWeightDevice []string - CapAdd []string - CapDrop []string - CGroupsNS string - CGroups string - CGroupParent string - CIDFile string - ConmonPIDFile string - CPUPeriod uint64 - CPUQuota int64 - CPURTPeriod uint64 - CPURTRuntime int64 - CPUShares uint64 - CPUS float64 - CPUSetCPUs string - CPUSetMems string - Detach bool - DetachKeys string - Device []string - DeviceCGroupRule []string - DeviceReadBPs []string - DeviceReadIOPs []string - DeviceWriteBPs []string - DeviceWriteIOPs []string - Entrypoint string - env []string - EnvHost bool - EnvFile []string - Expose []string - GIDMap []string - GroupAdd []string - HealthCmd string - HealthInterval string - HealthRetries uint - HealthStartPeriod string - HealthTimeout string - Hostname string - HTTPProxy bool - ImageVolume string - Init bool - InitPath string - Interactive bool - IPC string - KernelMemory string - Label []string - LabelFile []string - LogDriver string - LogOptions []string - Memory string - MemoryReservation string - MemorySwap string - MemorySwappiness int64 - Name string - NoHealthCheck bool - OOMKillDisable bool - OOMScoreAdj int - OverrideArch string - OverrideOS string - PID string - PIDsLimit int64 - Pod string - Privileged bool - PublishAll bool - Pull string - Quiet bool - ReadOnly bool - ReadOnlyTmpFS bool - Restart string - Rm bool - RootFS bool - SecurityOpt []string - ShmSize string - StopSignal string - StopTimeout uint - StoreageOpt []string - SubUIDName string - SubGIDName string - Sysctl []string - SystemdD string - TmpFS []string - TTY bool - UIDMap []string - Ulimit []string - User string - UserNS string - UTS string - Mount []string - Volume []string - VolumesFrom []string - Workdir string - SeccompPolicy string - - Net *entities.NetOptions -} diff --git a/cmd/podmanV2/common/createparse.go b/cmd/podmanV2/common/createparse.go deleted file mode 100644 index 89524a04b..000000000 --- a/cmd/podmanV2/common/createparse.go +++ /dev/null @@ -1,51 +0,0 @@ -package common - -import ( - "github.com/containers/libpod/cmd/podmanV2/parse" - "github.com/containers/libpod/pkg/util" - "github.com/pkg/errors" -) - -// validate determines if the flags and values given by the user are valid. things checked -// by validate must not need any state information on the flag (i.e. changed) -func (c *ContainerCLIOpts) validate() error { - var () - if c.Rm && c.Restart != "" && c.Restart != "no" { - return errors.Errorf("the --rm option conflicts with --restart") - } - - if _, err := util.ValidatePullType(c.Pull); err != nil { - return err - } - // Verify the additional hosts are in correct format - for _, host := range c.Net.AddHosts { - if _, err := parse.ValidateExtraHost(host); err != nil { - return err - } - } - - if dnsSearches := c.Net.DNSSearch; len(dnsSearches) > 0 { - // Validate domains are good - for _, dom := range dnsSearches { - if dom == "." { - if len(dnsSearches) > 1 { - return errors.Errorf("cannot pass additional search domains when also specifying '.'") - } - continue - } - if _, err := parse.ValidateDomain(dom); err != nil { - return err - } - } - } - var imageVolType = map[string]string{ - "bind": "", - "tmpfs": "", - "ignore": "", - } - if _, ok := imageVolType[c.ImageVolume]; !ok { - return errors.Errorf("invalid image-volume type %q. Pick one of bind, tmpfs, or ignore", c.ImageVolume) - } - return nil - -} diff --git a/cmd/podmanV2/common/default.go b/cmd/podmanV2/common/default.go deleted file mode 100644 index b71fcb6f0..000000000 --- a/cmd/podmanV2/common/default.go +++ /dev/null @@ -1,121 +0,0 @@ -package common - -import ( - "fmt" - "os" - - "github.com/containers/buildah/pkg/parse" - "github.com/containers/libpod/pkg/apparmor" - "github.com/containers/libpod/pkg/cgroups" - "github.com/containers/libpod/pkg/rootless" - "github.com/containers/libpod/pkg/sysinfo" - "github.com/opencontainers/selinux/go-selinux" -) - -// TODO these options are directly embedded into many of the CLI cobra values, as such -// this approach will not work in a remote client. so we will need to likely do something like a -// supported and unsupported approach here and backload these options into the specgen -// once we are "on" the host system. -func getDefaultSecurityOptions() []string { - securityOpts := []string{} - if defaultContainerConfig.Containers.SeccompProfile != "" && defaultContainerConfig.Containers.SeccompProfile != parse.SeccompDefaultPath { - securityOpts = append(securityOpts, fmt.Sprintf("seccomp=%s", defaultContainerConfig.Containers.SeccompProfile)) - } - if apparmor.IsEnabled() && defaultContainerConfig.Containers.ApparmorProfile != "" { - securityOpts = append(securityOpts, fmt.Sprintf("apparmor=%s", defaultContainerConfig.Containers.ApparmorProfile)) - } - if selinux.GetEnabled() && !defaultContainerConfig.Containers.EnableLabeling { - securityOpts = append(securityOpts, fmt.Sprintf("label=%s", selinux.DisableSecOpt()[0])) - } - return securityOpts -} - -// getDefaultSysctls -func getDefaultSysctls() []string { - return defaultContainerConfig.Containers.DefaultSysctls -} - -func getDefaultVolumes() []string { - return defaultContainerConfig.Containers.Volumes -} - -func getDefaultDevices() []string { - return defaultContainerConfig.Containers.Devices -} - -func getDefaultDNSServers() []string { //nolint - return defaultContainerConfig.Containers.DNSServers -} - -func getDefaultDNSSearches() []string { //nolint - return defaultContainerConfig.Containers.DNSSearches -} - -func getDefaultDNSOptions() []string { //nolint - return defaultContainerConfig.Containers.DNSOptions -} - -func getDefaultEnv() []string { - return defaultContainerConfig.Containers.Env -} - -func getDefaultInitPath() string { - return defaultContainerConfig.Containers.InitPath -} - -func getDefaultIPCNS() string { - return defaultContainerConfig.Containers.IPCNS -} - -func getDefaultPidNS() string { - return defaultContainerConfig.Containers.PidNS -} - -func getDefaultNetNS() string { //nolint - if defaultContainerConfig.Containers.NetNS == "private" && rootless.IsRootless() { - return "slirp4netns" - } - return defaultContainerConfig.Containers.NetNS -} - -func getDefaultCgroupNS() string { - return defaultContainerConfig.Containers.CgroupNS -} - -func getDefaultUTSNS() string { - return defaultContainerConfig.Containers.UTSNS -} - -func getDefaultShmSize() string { - return defaultContainerConfig.Containers.ShmSize -} - -func getDefaultUlimits() []string { - return defaultContainerConfig.Containers.DefaultUlimits -} - -func getDefaultUserNS() string { - userns := os.Getenv("PODMAN_USERNS") - if userns != "" { - return userns - } - return defaultContainerConfig.Containers.UserNS -} - -func getDefaultPidsLimit() int64 { - if rootless.IsRootless() { - cgroup2, _ := cgroups.IsCgroup2UnifiedMode() - if cgroup2 { - return defaultContainerConfig.Containers.PidsLimit - } - } - return sysinfo.GetDefaultPidsLimit() -} - -func getDefaultPidsDescription() string { - return "Tune container pids limit (set 0 for unlimited)" -} - -func GetDefaultDetachKeys() string { - return defaultContainerConfig.Engine.DetachKeys -} diff --git a/cmd/podmanV2/common/inspect.go b/cmd/podmanV2/common/inspect.go deleted file mode 100644 index dfc6fe679..000000000 --- a/cmd/podmanV2/common/inspect.go +++ /dev/null @@ -1,18 +0,0 @@ -package common - -import ( - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -// AddInspectFlagSet takes a command and adds the inspect flags and returns an InspectOptions object -// Since this cannot live in `package main` it lives here until a better home is found -func AddInspectFlagSet(cmd *cobra.Command) *entities.InspectOptions { - opts := entities.InspectOptions{} - - flags := cmd.Flags() - flags.BoolVarP(&opts.Size, "size", "s", false, "Display total file size") - flags.StringVarP(&opts.Format, "format", "f", "", "Change the output format to a Go template") - - return &opts -} diff --git a/cmd/podmanV2/common/netflags.go b/cmd/podmanV2/common/netflags.go deleted file mode 100644 index 758f155c8..000000000 --- a/cmd/podmanV2/common/netflags.go +++ /dev/null @@ -1,108 +0,0 @@ -package common - -import ( - "net" - - "github.com/containers/libpod/pkg/domain/entities" - "github.com/containers/libpod/pkg/rootless" - "github.com/spf13/cobra" - "github.com/spf13/pflag" -) - -func getDefaultNetwork() string { - if rootless.IsRootless() { - return "slirp4netns" - } - return "bridge" -} - -func GetNetFlags() *pflag.FlagSet { - netFlags := pflag.FlagSet{} - netFlags.StringSlice( - "add-host", []string{}, - "Add a custom host-to-IP mapping (host:ip) (default [])", - ) - netFlags.StringSlice( - "dns", []string{}, - "Set custom DNS servers", - ) - netFlags.StringSlice( - "dns-opt", []string{}, - "Set custom DNS options", - ) - netFlags.StringSlice( - "dns-search", []string{}, - "Set custom DNS search domains", - ) - netFlags.String( - "ip", "", - "Specify a static IPv4 address for the container", - ) - netFlags.String( - "mac-address", "", - "Container MAC address (e.g. 92:d0:c6:0a:29:33)", - ) - netFlags.String( - "network", getDefaultNetwork(), - "Connect a container to a network", - ) - netFlags.StringSliceP( - "publish", "p", []string{}, - "Publish a container's port, or a range of ports, to the host (default [])", - ) - netFlags.Bool( - "no-hosts", false, - "Do not create /etc/hosts within the container, instead use the version from the image", - ) - return &netFlags -} - -func NetFlagsToNetOptions(cmd *cobra.Command) (*entities.NetOptions, error) { - var ( - err error - ) - opts := entities.NetOptions{} - opts.AddHosts, err = cmd.Flags().GetStringSlice("add-host") - if err != nil { - return nil, err - } - servers, err := cmd.Flags().GetStringSlice("dns") - if err != nil { - return nil, err - } - for _, d := range servers { - if d == "none" { - opts.DNSHost = true - break - } - opts.DNSServers = append(opts.DNSServers, net.ParseIP(d)) - } - opts.DNSSearch, err = cmd.Flags().GetStringSlice("dns-search") - if err != nil { - return nil, err - } - - m, err := cmd.Flags().GetString("mac-address") - if err != nil { - return nil, err - } - if len(m) > 0 { - mac, err := net.ParseMAC(m) - if err != nil { - return nil, err - } - opts.StaticMAC = &mac - } - inputPorts, err := cmd.Flags().GetStringSlice("publish") - if err != nil { - return nil, err - } - if len(inputPorts) > 0 { - opts.PublishPorts, err = createPortBindings(inputPorts) - if err != nil { - return nil, err - } - } - opts.NoHosts, err = cmd.Flags().GetBool("no-hosts") - return &opts, err -} diff --git a/cmd/podmanV2/common/ports.go b/cmd/podmanV2/common/ports.go deleted file mode 100644 index 7e2b1e79d..000000000 --- a/cmd/podmanV2/common/ports.go +++ /dev/null @@ -1,126 +0,0 @@ -package common - -import ( - "fmt" - "net" - "strconv" - - "github.com/cri-o/ocicni/pkg/ocicni" - "github.com/docker/go-connections/nat" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" -) - -// ExposedPorts parses user and image ports and returns binding information -func ExposedPorts(expose []string, publish []ocicni.PortMapping, publishAll bool, imageExposedPorts map[string]struct{}) ([]ocicni.PortMapping, error) { - containerPorts := make(map[string]string) - - // TODO this needs to be added into a something that - // has access to an imageengine - // add expose ports from the image itself - //for expose := range imageExposedPorts { - // _, port := nat.SplitProtoPort(expose) - // containerPorts[port] = "" - //} - - // add the expose ports from the user (--expose) - // can be single or a range - for _, expose := range expose { - //support two formats for expose, original format <portnum>/[<proto>] or <startport-endport>/[<proto>] - _, port := nat.SplitProtoPort(expose) - //parse the start and end port and create a sequence of ports to expose - //if expose a port, the start and end port are the same - start, end, err := nat.ParsePortRange(port) - if err != nil { - return nil, fmt.Errorf("invalid range format for --expose: %s, error: %s", expose, err) - } - for i := start; i <= end; i++ { - containerPorts[strconv.Itoa(int(i))] = "" - } - } - - // TODO/FIXME this is hell reencarnated - // parse user inputted port bindings - pbPorts, portBindings, err := nat.ParsePortSpecs([]string{}) - if err != nil { - return nil, err - } - - // delete exposed container ports if being used by -p - for i := range pbPorts { - delete(containerPorts, i.Port()) - } - - // iterate container ports and make port bindings from them - if publishAll { - for e := range containerPorts { - //support two formats for expose, original format <portnum>/[<proto>] or <startport-endport>/[<proto>] - //proto, port := nat.SplitProtoPort(e) - p, err := nat.NewPort("tcp", e) - if err != nil { - return nil, err - } - rp, err := getRandomPort() - if err != nil { - return nil, err - } - logrus.Debug(fmt.Sprintf("Using random host port %d with container port %d", rp, p.Int())) - portBindings[p] = CreatePortBinding(rp, "") - } - } - - // We need to see if any host ports are not populated and if so, we need to assign a - // random port to them. - for k, pb := range portBindings { - if pb[0].HostPort == "" { - hostPort, err := getRandomPort() - if err != nil { - return nil, err - } - logrus.Debug(fmt.Sprintf("Using random host port %d with container port %s", hostPort, k.Port())) - pb[0].HostPort = strconv.Itoa(hostPort) - } - } - var pms []ocicni.PortMapping - for k, v := range portBindings { - for _, pb := range v { - hp, err := strconv.Atoi(pb.HostPort) - if err != nil { - return nil, err - } - pms = append(pms, ocicni.PortMapping{ - HostPort: int32(hp), - ContainerPort: int32(k.Int()), - //Protocol: "", - HostIP: pb.HostIP, - }) - } - } - return pms, nil -} - -func getRandomPort() (int, error) { - l, err := net.Listen("tcp", ":0") - if err != nil { - return 0, errors.Wrapf(err, "unable to get free port") - } - defer l.Close() - _, randomPort, err := net.SplitHostPort(l.Addr().String()) - if err != nil { - return 0, errors.Wrapf(err, "unable to determine free port") - } - rp, err := strconv.Atoi(randomPort) - if err != nil { - return 0, errors.Wrapf(err, "unable to convert random port to int") - } - return rp, nil -} - -//CreatePortBinding takes port (int) and IP (string) and creates an array of portbinding structs -func CreatePortBinding(hostPort int, hostIP string) []nat.PortBinding { - pb := nat.PortBinding{ - HostPort: strconv.Itoa(hostPort), - } - pb.HostIP = hostIP - return []nat.PortBinding{pb} -} diff --git a/cmd/podmanV2/common/specgen.go b/cmd/podmanV2/common/specgen.go deleted file mode 100644 index 5245e206e..000000000 --- a/cmd/podmanV2/common/specgen.go +++ /dev/null @@ -1,647 +0,0 @@ -package common - -import ( - "encoding/json" - "fmt" - "os" - "path/filepath" - "strconv" - "strings" - "time" - - "github.com/containers/image/v5/manifest" - "github.com/containers/libpod/cmd/podmanV2/parse" - "github.com/containers/libpod/libpod" - ann "github.com/containers/libpod/pkg/annotations" - envLib "github.com/containers/libpod/pkg/env" - ns "github.com/containers/libpod/pkg/namespaces" - "github.com/containers/libpod/pkg/specgen" - systemdGen "github.com/containers/libpod/pkg/systemd/generate" - "github.com/containers/libpod/pkg/util" - "github.com/docker/go-units" - "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" -) - -func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string) error { - var ( - err error - //namespaces map[string]string - ) - - // validate flags as needed - if err := c.validate(); err != nil { - return nil - } - - inputCommand := args[1:] - if len(c.HealthCmd) > 0 { - s.HealthConfig, err = makeHealthCheckFromCli(c.HealthCmd, c.HealthInterval, c.HealthRetries, c.HealthTimeout, c.HealthStartPeriod) - if err != nil { - return err - } - } - - s.IDMappings, err = util.ParseIDMapping(ns.UsernsMode(c.UserNS), c.UIDMap, c.GIDMap, c.SubUIDName, c.SubGIDName) - if err != nil { - return err - } - if m := c.Memory; len(m) > 0 { - ml, err := units.RAMInBytes(m) - if err != nil { - return errors.Wrapf(err, "invalid value for memory") - } - s.ResourceLimits.Memory.Limit = &ml - } - if m := c.MemoryReservation; len(m) > 0 { - mr, err := units.RAMInBytes(m) - if err != nil { - return errors.Wrapf(err, "invalid value for memory") - } - s.ResourceLimits.Memory.Reservation = &mr - } - if m := c.MemorySwap; len(m) > 0 { - var ms int64 - if m == "-1" { - ms = int64(-1) - s.ResourceLimits.Memory.Swap = &ms - } else { - ms, err = units.RAMInBytes(m) - if err != nil { - return errors.Wrapf(err, "invalid value for memory") - } - } - s.ResourceLimits.Memory.Swap = &ms - } - if m := c.KernelMemory; len(m) > 0 { - mk, err := units.RAMInBytes(m) - if err != nil { - return errors.Wrapf(err, "invalid value for kernel-memory") - } - s.ResourceLimits.Memory.Kernel = &mk - } - if b := c.BlkIOWeight; len(b) > 0 { - u, err := strconv.ParseUint(b, 10, 16) - if err != nil { - return errors.Wrapf(err, "invalid value for blkio-weight") - } - nu := uint16(u) - s.ResourceLimits.BlockIO.Weight = &nu - } - - s.Terminal = c.TTY - ep, err := ExposedPorts(c.Expose, c.Net.PublishPorts, c.PublishAll, nil) - if err != nil { - return err - } - s.PortMappings = ep - s.Pod = c.Pod - - //s.CgroupNS = specgen.Namespace{ - // NSMode: , - // Value: "", - //} - - //s.UserNS = specgen.Namespace{} - - // Kernel Namespaces - // TODO Fix handling of namespace from pod - // Instead of integrating here, should be done in libpod - // However, that also involves setting up security opts - // when the pod's namespace is integrated - //namespaces = map[string]string{ - // "cgroup": c.CGroupsNS, - // "pid": c.PID, - // //"net": c.Net.Network.Value, // TODO need help here - // "ipc": c.IPC, - // "user": c.User, - // "uts": c.UTS, - //} - // - //if len(c.PID) > 0 { - // split := strings.SplitN(c.PID, ":", 2) - // // need a way to do thsi - // specgen.Namespace{ - // NSMode: split[0], - // } - // //Value: split1 if len allows - //} - // TODO this is going to have be done after things like pod creation are done because - // pod creation changes these values. - //pidMode := ns.PidMode(namespaces["pid"]) - //usernsMode := ns.UsernsMode(namespaces["user"]) - //utsMode := ns.UTSMode(namespaces["uts"]) - //cgroupMode := ns.CgroupMode(namespaces["cgroup"]) - //ipcMode := ns.IpcMode(namespaces["ipc"]) - //// Make sure if network is set to container namespace, port binding is not also being asked for - //netMode := ns.NetworkMode(namespaces["net"]) - //if netMode.IsContainer() { - // if len(portBindings) > 0 { - // return nil, errors.Errorf("cannot set port bindings on an existing container network namespace") - // } - //} - - // TODO Remove when done with namespaces for realz - // Setting a default for IPC to get this working - s.IpcNS = specgen.Namespace{ - NSMode: specgen.Private, - Value: "", - } - - // TODO this is going to have to be done the libpod/server end of things - // USER - //user := c.String("user") - //if user == "" { - // switch { - // case usernsMode.IsKeepID(): - // user = fmt.Sprintf("%d:%d", rootless.GetRootlessUID(), rootless.GetRootlessGID()) - // case data == nil: - // user = "0" - // default: - // user = data.Config.User - // } - //} - - // STOP SIGNAL - signalString := "TERM" - if sig := c.StopSignal; len(sig) > 0 { - signalString = sig - } - stopSignal, err := util.ParseSignal(signalString) - if err != nil { - return err - } - s.StopSignal = &stopSignal - - // ENVIRONMENT VARIABLES - // - // Precedence order (higher index wins): - // 1) env-host, 2) image data, 3) env-file, 4) env - env := map[string]string{ - "container": "podman", - } - - // First transform the os env into a map. We need it for the labels later in - // any case. - osEnv, err := envLib.ParseSlice(os.Environ()) - if err != nil { - return errors.Wrap(err, "error parsing host environment variables") - } - - if c.EnvHost { - env = envLib.Join(env, osEnv) - } - // env-file overrides any previous variables - for _, f := range c.EnvFile { - fileEnv, err := envLib.ParseFile(f) - if err != nil { - return err - } - // File env is overridden by env. - env = envLib.Join(env, fileEnv) - } - - // env overrides any previous variables - if cmdLineEnv := c.env; len(cmdLineEnv) > 0 { - parsedEnv, err := envLib.ParseSlice(cmdLineEnv) - if err != nil { - return err - } - env = envLib.Join(env, parsedEnv) - } - s.Env = env - - // LABEL VARIABLES - labels, err := parse.GetAllLabels(c.LabelFile, c.Label) - if err != nil { - return errors.Wrapf(err, "unable to process labels") - } - - if systemdUnit, exists := osEnv[systemdGen.EnvVariable]; exists { - labels[systemdGen.EnvVariable] = systemdUnit - } - - s.Labels = labels - - // ANNOTATIONS - annotations := make(map[string]string) - - // First, add our default annotations - annotations[ann.TTY] = "false" - if c.TTY { - annotations[ann.TTY] = "true" - } - - // Last, add user annotations - for _, annotation := range c.Annotation { - splitAnnotation := strings.SplitN(annotation, "=", 2) - if len(splitAnnotation) < 2 { - return errors.Errorf("Annotations must be formatted KEY=VALUE") - } - annotations[splitAnnotation[0]] = splitAnnotation[1] - } - s.Annotations = annotations - - workDir := "/" - if wd := c.Workdir; len(wd) > 0 { - workDir = wd - } - s.WorkDir = workDir - entrypoint := []string{} - userCommand := []string{} - if ep := c.Entrypoint; len(ep) > 0 { - // Check if entrypoint specified is json - if err := json.Unmarshal([]byte(c.Entrypoint), &entrypoint); err != nil { - entrypoint = append(entrypoint, ep) - } - } - - var command []string - - // Build the command - // If we have an entry point, it goes first - if len(entrypoint) > 0 { - command = entrypoint - } - if len(inputCommand) > 0 { - // User command overrides data CMD - command = append(command, inputCommand...) - userCommand = append(userCommand, inputCommand...) - } - - if len(inputCommand) > 0 { - s.Command = userCommand - } else { - s.Command = command - } - - // SHM Size - shmSize, err := units.FromHumanSize(c.ShmSize) - if err != nil { - return errors.Wrapf(err, "unable to translate --shm-size") - } - s.ShmSize = &shmSize - s.HostAdd = c.Net.AddHosts - s.DNSServer = c.Net.DNSServers - s.DNSSearch = c.Net.DNSSearch - s.DNSOption = c.Net.DNSOptions - - // deferred, must be added on libpod side - //var ImageVolumes map[string]struct{} - //if data != nil && c.String("image-volume") != "ignore" { - // ImageVolumes = data.Config.Volumes - //} - - s.ImageVolumeMode = c.ImageVolume - systemd := c.SystemdD == "always" - if !systemd && command != nil { - x, err := strconv.ParseBool(c.SystemdD) - if err != nil { - return errors.Wrapf(err, "cannot parse bool %s", c.SystemdD) - } - if x && (command[0] == "/usr/sbin/init" || command[0] == "/sbin/init" || (filepath.Base(command[0]) == "systemd")) { - systemd = true - } - } - if systemd { - if s.StopSignal == nil { - stopSignal, err = util.ParseSignal("RTMIN+3") - if err != nil { - return errors.Wrapf(err, "error parsing systemd signal") - } - s.StopSignal = &stopSignal - } - } - swappiness := uint64(c.MemorySwappiness) - if s.ResourceLimits == nil { - s.ResourceLimits = &specs.LinuxResources{} - } - if s.ResourceLimits.Memory == nil { - s.ResourceLimits.Memory = &specs.LinuxMemory{} - } - s.ResourceLimits.Memory.Swappiness = &swappiness - - if s.LogConfiguration == nil { - s.LogConfiguration = &specgen.LogConfig{} - } - s.LogConfiguration.Driver = libpod.KubernetesLogging - if ld := c.LogDriver; len(ld) > 0 { - s.LogConfiguration.Driver = ld - } - if s.ResourceLimits.Pids == nil { - s.ResourceLimits.Pids = &specs.LinuxPids{} - } - s.ResourceLimits.Pids.Limit = c.PIDsLimit - if c.CGroups == "disabled" && c.PIDsLimit > 0 { - s.ResourceLimits.Pids.Limit = -1 - } - // TODO WTF - //cgroup := &cc.CgroupConfig{ - // Cgroups: c.String("cgroups"), - // Cgroupns: c.String("cgroupns"), - // CgroupParent: c.String("cgroup-parent"), - // CgroupMode: cgroupMode, - //} - // - //userns := &cc.UserConfig{ - // GroupAdd: c.StringSlice("group-add"), - // IDMappings: idmappings, - // UsernsMode: usernsMode, - // User: user, - //} - // - //uts := &cc.UtsConfig{ - // UtsMode: utsMode, - // NoHosts: c.Bool("no-hosts"), - // HostAdd: c.StringSlice("add-host"), - // Hostname: c.String("hostname"), - //} - - sysctl := map[string]string{} - if ctl := c.Sysctl; len(ctl) > 0 { - sysctl, err = util.ValidateSysctls(ctl) - if err != nil { - return err - } - } - s.Sysctl = sysctl - - s.CapAdd = c.CapAdd - s.CapDrop = c.CapDrop - s.Privileged = c.Privileged - s.ReadOnlyFilesystem = c.ReadOnly - - // TODO - // ouitside of specgen and oci though - // defaults to true, check spec/storage - //s.readon = c.ReadOnlyTmpFS - // TODO convert to map? - // check if key=value and convert - sysmap := make(map[string]string) - for _, ctl := range c.Sysctl { - splitCtl := strings.SplitN(ctl, "=", 2) - if len(splitCtl) < 2 { - return errors.Errorf("invalid sysctl value %q", ctl) - } - sysmap[splitCtl[0]] = splitCtl[1] - } - s.Sysctl = sysmap - - for _, opt := range c.SecurityOpt { - if opt == "no-new-privileges" { - s.ContainerSecurityConfig.NoNewPrivileges = true - } else { - con := strings.SplitN(opt, "=", 2) - if len(con) != 2 { - return fmt.Errorf("invalid --security-opt 1: %q", opt) - } - - switch con[0] { - case "label": - // TODO selinux opts and label opts are the same thing - s.ContainerSecurityConfig.SelinuxOpts = append(s.ContainerSecurityConfig.SelinuxOpts, con[1]) - case "apparmor": - s.ContainerSecurityConfig.ApparmorProfile = con[1] - case "seccomp": - s.SeccompProfilePath = con[1] - default: - return fmt.Errorf("invalid --security-opt 2: %q", opt) - } - } - } - - // TODO any idea why this was done - // storage.go from spec/ - // grab it - //volumes := rtc.Containers.Volumes - // TODO conflict on populate? - //if v := c.Volume; len(v)> 0 { - // s.Volumes = append(volumes, c.StringSlice("volume")...) - //} - //s.volu - - //s.Mounts = c.Mount - s.VolumesFrom = c.VolumesFrom - - // TODO any idea why this was done - //devices := rtc.Containers.Devices - // TODO conflict on populate? - // - //if c.Changed("device") { - // devices = append(devices, c.StringSlice("device")...) - //} - - // TODO things i cannot find in spec - // we dont think these are in the spec - // init - initbinary - // initpath - s.Stdin = c.Interactive - // quiet - //DeviceCgroupRules: c.StringSlice("device-cgroup-rule"), - - if bps := c.DeviceReadBPs; len(bps) > 0 { - if s.ThrottleReadBpsDevice, err = parseThrottleBPSDevices(bps); err != nil { - return err - } - } - - if bps := c.DeviceWriteBPs; len(bps) > 0 { - if s.ThrottleWriteBpsDevice, err = parseThrottleBPSDevices(bps); err != nil { - return err - } - } - - if iops := c.DeviceReadIOPs; len(iops) > 0 { - if s.ThrottleReadIOPSDevice, err = parseThrottleIOPsDevices(iops); err != nil { - return err - } - } - - if iops := c.DeviceWriteIOPs; len(iops) > 0 { - if s.ThrottleWriteIOPSDevice, err = parseThrottleIOPsDevices(iops); err != nil { - return err - } - } - - s.ResourceLimits.Memory.DisableOOMKiller = &c.OOMKillDisable - - // Rlimits/Ulimits - for _, u := range c.Ulimit { - if u == "host" { - s.Rlimits = nil - break - } - ul, err := units.ParseUlimit(u) - if err != nil { - return errors.Wrapf(err, "ulimit option %q requires name=SOFT:HARD, failed to be parsed", u) - } - rl := specs.POSIXRlimit{ - Type: ul.Name, - Hard: uint64(ul.Hard), - Soft: uint64(ul.Soft), - } - s.Rlimits = append(s.Rlimits, rl) - } - - //Tmpfs: c.StringArray("tmpfs"), - - // TODO how to handle this? - //Syslog: c.Bool("syslog"), - - logOpts := make(map[string]string) - for _, o := range c.LogOptions { - split := strings.SplitN(o, "=", 2) - if len(split) < 2 { - return errors.Errorf("invalid log option %q", o) - } - logOpts[split[0]] = split[1] - } - s.LogConfiguration.Options = logOpts - s.Name = c.Name - - if err := parseWeightDevices(c.BlkIOWeightDevice, s); err != nil { - return err - } - - if s.ResourceLimits.CPU == nil { - s.ResourceLimits.CPU = &specs.LinuxCPU{} - } - s.ResourceLimits.CPU.Shares = &c.CPUShares - s.ResourceLimits.CPU.Period = &c.CPUPeriod - - // TODO research these - //s.ResourceLimits.CPU.Cpus = c.CPUS - //s.ResourceLimits.CPU.Cpus = c.CPUSetCPUs - - //s.ResourceLimits.CPU. = c.CPUSetCPUs - s.ResourceLimits.CPU.Mems = c.CPUSetMems - s.ResourceLimits.CPU.Quota = &c.CPUQuota - s.ResourceLimits.CPU.RealtimePeriod = &c.CPURTPeriod - s.ResourceLimits.CPU.RealtimeRuntime = &c.CPURTRuntime - s.OOMScoreAdj = &c.OOMScoreAdj - s.RestartPolicy = c.Restart - s.Remove = c.Rm - s.StopTimeout = &c.StopTimeout - - // TODO where should we do this? - //func verifyContainerResources(config *cc.CreateConfig, update bool) ([]string, error) { - return nil -} - -func makeHealthCheckFromCli(inCmd, interval string, retries uint, timeout, startPeriod string) (*manifest.Schema2HealthConfig, error) { - // Every healthcheck requires a command - if len(inCmd) == 0 { - return nil, errors.New("Must define a healthcheck command for all healthchecks") - } - - // first try to parse option value as JSON array of strings... - cmd := []string{} - err := json.Unmarshal([]byte(inCmd), &cmd) - if err != nil { - // ...otherwise pass it to "/bin/sh -c" inside the container - cmd = []string{"CMD-SHELL", inCmd} - } - hc := manifest.Schema2HealthConfig{ - Test: cmd, - } - - if interval == "disable" { - interval = "0" - } - intervalDuration, err := time.ParseDuration(interval) - if err != nil { - return nil, errors.Wrapf(err, "invalid healthcheck-interval %s ", interval) - } - - hc.Interval = intervalDuration - - if retries < 1 { - return nil, errors.New("healthcheck-retries must be greater than 0.") - } - hc.Retries = int(retries) - timeoutDuration, err := time.ParseDuration(timeout) - if err != nil { - return nil, errors.Wrapf(err, "invalid healthcheck-timeout %s", timeout) - } - if timeoutDuration < time.Duration(1) { - return nil, errors.New("healthcheck-timeout must be at least 1 second") - } - hc.Timeout = timeoutDuration - - startPeriodDuration, err := time.ParseDuration(startPeriod) - if err != nil { - return nil, errors.Wrapf(err, "invalid healthcheck-start-period %s", startPeriod) - } - if startPeriodDuration < time.Duration(0) { - return nil, errors.New("healthcheck-start-period must be 0 seconds or greater") - } - hc.StartPeriod = startPeriodDuration - - return &hc, nil -} - -func parseWeightDevices(weightDevs []string, s *specgen.SpecGenerator) error { - for _, val := range weightDevs { - split := strings.SplitN(val, ":", 2) - if len(split) != 2 { - return fmt.Errorf("bad format: %s", val) - } - if !strings.HasPrefix(split[0], "/dev/") { - return fmt.Errorf("bad format for device path: %s", val) - } - weight, err := strconv.ParseUint(split[1], 10, 0) - if err != nil { - return fmt.Errorf("invalid weight for device: %s", val) - } - if weight > 0 && (weight < 10 || weight > 1000) { - return fmt.Errorf("invalid weight for device: %s", val) - } - w := uint16(weight) - s.WeightDevice[split[0]] = specs.LinuxWeightDevice{ - Weight: &w, - LeafWeight: nil, - } - } - return nil -} - -func parseThrottleBPSDevices(bpsDevices []string) (map[string]specs.LinuxThrottleDevice, error) { - td := make(map[string]specs.LinuxThrottleDevice) - for _, val := range bpsDevices { - split := strings.SplitN(val, ":", 2) - if len(split) != 2 { - return nil, fmt.Errorf("bad format: %s", val) - } - if !strings.HasPrefix(split[0], "/dev/") { - return nil, fmt.Errorf("bad format for device path: %s", val) - } - rate, err := units.RAMInBytes(split[1]) - if err != nil { - return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>[<unit>]. Number must be a positive integer. Unit is optional and can be kb, mb, or gb", val) - } - if rate < 0 { - return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>[<unit>]. Number must be a positive integer. Unit is optional and can be kb, mb, or gb", val) - } - td[split[0]] = specs.LinuxThrottleDevice{Rate: uint64(rate)} - } - return td, nil -} - -func parseThrottleIOPsDevices(iopsDevices []string) (map[string]specs.LinuxThrottleDevice, error) { - td := make(map[string]specs.LinuxThrottleDevice) - for _, val := range iopsDevices { - split := strings.SplitN(val, ":", 2) - if len(split) != 2 { - return nil, fmt.Errorf("bad format: %s", val) - } - if !strings.HasPrefix(split[0], "/dev/") { - return nil, fmt.Errorf("bad format for device path: %s", val) - } - rate, err := strconv.ParseUint(split[1], 10, 64) - if err != nil { - return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>. Number must be a positive integer", val) - } - td[split[0]] = specs.LinuxThrottleDevice{Rate: rate} - } - return td, nil -} diff --git a/cmd/podmanV2/common/types.go b/cmd/podmanV2/common/types.go deleted file mode 100644 index 2427ae975..000000000 --- a/cmd/podmanV2/common/types.go +++ /dev/null @@ -1,3 +0,0 @@ -package common - -var DefaultKernelNamespaces = "cgroup,ipc,net,uts" diff --git a/cmd/podmanV2/common/util.go b/cmd/podmanV2/common/util.go deleted file mode 100644 index 47bbe12fa..000000000 --- a/cmd/podmanV2/common/util.go +++ /dev/null @@ -1,43 +0,0 @@ -package common - -import ( - "strconv" - - "github.com/cri-o/ocicni/pkg/ocicni" - "github.com/docker/go-connections/nat" - "github.com/pkg/errors" -) - -// createPortBindings iterates ports mappings and exposed ports into a format CNI understands -func createPortBindings(ports []string) ([]ocicni.PortMapping, error) { - // TODO wants someone to rewrite this code in the future - var portBindings []ocicni.PortMapping - // The conversion from []string to natBindings is temporary while mheon reworks the port - // deduplication code. Eventually that step will not be required. - _, natBindings, err := nat.ParsePortSpecs(ports) - if err != nil { - return nil, err - } - for containerPb, hostPb := range natBindings { - var pm ocicni.PortMapping - pm.ContainerPort = int32(containerPb.Int()) - for _, i := range hostPb { - var hostPort int - var err error - pm.HostIP = i.HostIP - if i.HostPort == "" { - hostPort = containerPb.Int() - } else { - hostPort, err = strconv.Atoi(i.HostPort) - if err != nil { - return nil, errors.Wrapf(err, "unable to convert host port to integer") - } - } - - pm.HostPort = int32(hostPort) - pm.Protocol = containerPb.Proto() - portBindings = append(portBindings, pm) - } - } - return portBindings, nil -} diff --git a/cmd/podmanV2/containers/attach.go b/cmd/podmanV2/containers/attach.go deleted file mode 100644 index d62dcff86..000000000 --- a/cmd/podmanV2/containers/attach.go +++ /dev/null @@ -1,60 +0,0 @@ -package containers - -import ( - "os" - - "github.com/containers/libpod/cmd/podmanV2/common" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - attachDescription = "The podman attach command allows you to attach to a running container using the container's ID or name, either to view its ongoing output or to control it interactively." - attachCommand = &cobra.Command{ - Use: "attach [flags] CONTAINER", - Short: "Attach to a running container", - Long: attachDescription, - RunE: attach, - Args: func(cmd *cobra.Command, args []string) error { - if len(args) > 1 || (len(args) == 0 && !cmd.Flag("latest").Changed) { - return errors.Errorf("attach requires the name or id of one running container or the latest flag") - } - return nil - }, - PreRunE: preRunE, - Example: `podman attach ctrID - podman attach 1234 - podman attach --no-stdin foobar`, - } -) - -var ( - attachOpts entities.AttachOptions -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode}, - Command: attachCommand, - }) - flags := attachCommand.Flags() - flags.StringVar(&attachOpts.DetachKeys, "detach-keys", common.GetDefaultDetachKeys(), "Select the key sequence for detaching a container. Format is a single character `[a-Z]` or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-z`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`") - flags.BoolVar(&attachOpts.NoStdin, "no-stdin", false, "Do not attach STDIN. The default is false") - flags.BoolVar(&attachOpts.SigProxy, "sig-proxy", true, "Proxy received signals to the process") - flags.BoolVarP(&attachOpts.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - if registry.IsRemote() { - _ = flags.MarkHidden("latest") - } -} - -func attach(cmd *cobra.Command, args []string) error { - attachOpts.Stdin = os.Stdin - if attachOpts.NoStdin { - attachOpts.Stdin = nil - } - attachOpts.Stdout = os.Stdout - attachOpts.Stderr = os.Stderr - return registry.ContainerEngine().ContainerAttach(registry.GetContext(), args[0], attachOpts) -} diff --git a/cmd/podmanV2/containers/checkpoint.go b/cmd/podmanV2/containers/checkpoint.go deleted file mode 100644 index 7c3e551bc..000000000 --- a/cmd/podmanV2/containers/checkpoint.go +++ /dev/null @@ -1,79 +0,0 @@ -package containers - -import ( - "context" - "fmt" - - "github.com/containers/libpod/cmd/podmanV2/parse" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/cmd/podmanV2/utils" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/containers/libpod/pkg/rootless" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - checkpointDescription = ` - podman container checkpoint - - Checkpoints one or more running containers. The container name or ID can be used. -` - checkpointCommand = &cobra.Command{ - Use: "checkpoint [flags] CONTAINER [CONTAINER...]", - Short: "Checkpoints one or more containers", - Long: checkpointDescription, - RunE: checkpoint, - Args: func(cmd *cobra.Command, args []string) error { - return parse.CheckAllLatestAndCIDFile(cmd, args, false, false) - }, - Example: `podman container checkpoint --keep ctrID - podman container checkpoint --all - podman container checkpoint --leave-running --latest`, - } -) - -var ( - checkpointOptions entities.CheckpointOptions -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: checkpointCommand, - Parent: containerCmd, - }) - flags := checkpointCommand.Flags() - flags.BoolVarP(&checkpointOptions.Keep, "keep", "k", false, "Keep all temporary checkpoint files") - flags.BoolVarP(&checkpointOptions.LeaveRuninng, "leave-running", "R", false, "Leave the container running after writing checkpoint to disk") - flags.BoolVar(&checkpointOptions.TCPEstablished, "tcp-established", false, "Checkpoint a container with established TCP connections") - flags.BoolVarP(&checkpointOptions.All, "all", "a", false, "Checkpoint all running containers") - flags.BoolVarP(&checkpointOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - flags.StringVarP(&checkpointOptions.Export, "export", "e", "", "Export the checkpoint image to a tar.gz") - flags.BoolVar(&checkpointOptions.IgnoreRootFS, "ignore-rootfs", false, "Do not include root file-system changes when exporting") - if registry.IsRemote() { - _ = flags.MarkHidden("latest") - } -} - -func checkpoint(cmd *cobra.Command, args []string) error { - var errs utils.OutputErrors - if rootless.IsRootless() { - return errors.New("checkpointing a container requires root") - } - if checkpointOptions.Export == "" && checkpointOptions.IgnoreRootFS { - return errors.Errorf("--ignore-rootfs can only be used with --export") - } - responses, err := registry.ContainerEngine().ContainerCheckpoint(context.Background(), args, checkpointOptions) - if err != nil { - return err - } - for _, r := range responses { - if r.Err == nil { - fmt.Println(r.Id) - } else { - errs = append(errs, r.Err) - } - } - return errs.PrintErrors() -} diff --git a/cmd/podmanV2/containers/commit.go b/cmd/podmanV2/containers/commit.go deleted file mode 100644 index 28eb42f33..000000000 --- a/cmd/podmanV2/containers/commit.go +++ /dev/null @@ -1,79 +0,0 @@ -package containers - -import ( - "context" - "fmt" - "io/ioutil" - "os" - "strings" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - commitDescription = `Create an image from a container's changes. Optionally tag the image created, set the author with the --author flag, set the commit message with the --message flag, and make changes to the instructions with the --change flag.` - - commitCommand = &cobra.Command{ - Use: "commit [flags] CONTAINER [IMAGE]", - Short: "Create new image based on the changed container", - Long: commitDescription, - RunE: commit, - PreRunE: preRunE, - Args: cobra.MinimumNArgs(1), - Example: `podman commit -q --message "committing container to image" reverent_golick image-committed - podman commit -q --author "firstName lastName" reverent_golick image-committed - podman commit -q --pause=false containerID image-committed - podman commit containerID`, - } - - // ChangeCmds is the list of valid Changes commands to passed to the Commit call - ChangeCmds = []string{"CMD", "ENTRYPOINT", "ENV", "EXPOSE", "LABEL", "ONBUILD", "STOPSIGNAL", "USER", "VOLUME", "WORKDIR"} -) - -var ( - commitOptions = entities.CommitOptions{ - ImageName: "", - } - iidFile string -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: commitCommand, - }) - flags := commitCommand.Flags() - flags.StringArrayVarP(&commitOptions.Changes, "change", "c", []string{}, "Apply the following possible instructions to the created image (default []): "+strings.Join(ChangeCmds, " | ")) - flags.StringVarP(&commitOptions.Format, "format", "f", "oci", "`Format` of the image manifest and metadata") - flags.StringVarP(&iidFile, "iidfile", "", "", "`file` to write the image ID to") - flags.StringVarP(&commitOptions.Message, "message", "m", "", "Set commit message for imported image") - flags.StringVarP(&commitOptions.Author, "author", "a", "", "Set the author for the image committed") - flags.BoolVarP(&commitOptions.Pause, "pause", "p", false, "Pause container during commit") - flags.BoolVarP(&commitOptions.Quiet, "quiet", "q", false, "Suppress output") - flags.BoolVar(&commitOptions.IncludeVolumes, "include-volumes", false, "Include container volumes as image volumes") - -} -func commit(cmd *cobra.Command, args []string) error { - container := args[0] - if len(args) > 1 { - commitOptions.ImageName = args[1] - } - if !commitOptions.Quiet { - commitOptions.Writer = os.Stderr - } - - response, err := registry.ContainerEngine().ContainerCommit(context.Background(), container, commitOptions) - if err != nil { - return err - } - if len(iidFile) > 0 { - if err = ioutil.WriteFile(iidFile, []byte(response.Id), 0644); err != nil { - return errors.Wrapf(err, "failed to write image ID to file %q", iidFile) - } - } - fmt.Println(response.Id) - return nil -} diff --git a/cmd/podmanV2/containers/container.go b/cmd/podmanV2/containers/container.go deleted file mode 100644 index b922eea05..000000000 --- a/cmd/podmanV2/containers/container.go +++ /dev/null @@ -1,48 +0,0 @@ -package containers - -import ( - "os" - - "github.com/containers/common/pkg/config" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/sirupsen/logrus" - "github.com/spf13/cobra" -) - -var ( - // Command: podman _container_ - containerCmd = &cobra.Command{ - Use: "container", - Short: "Manage containers", - Long: "Manage containers", - TraverseChildren: true, - PersistentPreRunE: preRunE, - RunE: registry.SubCommandExists, - } - - defaultContainerConfig = getDefaultContainerConfig() -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: containerCmd, - }) - containerCmd.SetHelpTemplate(registry.HelpTemplate()) - containerCmd.SetUsageTemplate(registry.UsageTemplate()) -} - -func preRunE(cmd *cobra.Command, args []string) error { - _, err := registry.NewContainerEngine(cmd, args) - return err -} - -func getDefaultContainerConfig() *config.Config { - defaultContainerConfig, err := config.Default() - if err != nil { - logrus.Error(err) - os.Exit(1) - } - return defaultContainerConfig -} diff --git a/cmd/podmanV2/containers/create.go b/cmd/podmanV2/containers/create.go deleted file mode 100644 index fd5300966..000000000 --- a/cmd/podmanV2/containers/create.go +++ /dev/null @@ -1,102 +0,0 @@ -package containers - -import ( - "fmt" - - "github.com/containers/libpod/cmd/podmanV2/common" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/containers/libpod/pkg/specgen" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" - "github.com/spf13/cobra" -) - -var ( - createDescription = `Creates a new container from the given image or storage and prepares it for running the specified command. - - The container ID is then printed to stdout. You can then start it at any time with the podman start <container_id> command. The container will be created with the initial state 'created'.` - createCommand = &cobra.Command{ - Use: "create [flags] IMAGE [COMMAND [ARG...]]", - Short: "Create but do not start a container", - Long: createDescription, - RunE: create, - PersistentPreRunE: preRunE, - Args: cobra.MinimumNArgs(1), - Example: `podman create alpine ls - podman create --annotation HELLO=WORLD alpine ls - podman create -t -i --name myctr alpine ls`, - } -) - -var ( - cliVals common.ContainerCLIOpts -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: createCommand, - }) - //common.GetCreateFlags(createCommand) - flags := createCommand.Flags() - flags.AddFlagSet(common.GetCreateFlags(&cliVals)) - flags.AddFlagSet(common.GetNetFlags()) - flags.SetNormalizeFunc(common.AliasFlags) -} - -func create(cmd *cobra.Command, args []string) error { - var ( - err error - rawImageInput string - ) - cliVals.Net, err = common.NetFlagsToNetOptions(cmd) - if err != nil { - return err - } - if rfs := cliVals.RootFS; !rfs { - rawImageInput = args[0] - } - - if err := createInit(cmd); err != nil { - return err - } - //TODO rootfs still - s := specgen.NewSpecGenerator(rawImageInput) - if err := common.FillOutSpecGen(s, &cliVals, args); err != nil { - return err - } - - report, err := registry.ContainerEngine().ContainerCreate(registry.GetContext(), s) - if err != nil { - return err - } - fmt.Println(report.Id) - return nil -} - -func createInit(c *cobra.Command) error { - if c.Flag("privileged").Changed && c.Flag("security-opt").Changed { - logrus.Warn("setting security options with --privileged has no effect") - } - - if (c.Flag("dns").Changed || c.Flag("dns-opt").Changed || c.Flag("dns-search").Changed) && (cliVals.Net.Network.NSMode == specgen.NoNetwork || cliVals.Net.Network.IsContainer()) { - return errors.Errorf("conflicting options: dns and the network mode.") - } - - if c.Flag("cpu-period").Changed && c.Flag("cpus").Changed { - return errors.Errorf("--cpu-period and --cpus cannot be set together") - } - if c.Flag("cpu-quota").Changed && c.Flag("cpus").Changed { - return errors.Errorf("--cpu-quota and --cpus cannot be set together") - } - - if c.Flag("no-hosts").Changed && c.Flag("add-host").Changed { - return errors.Errorf("--no-hosts and --add-host cannot be set together") - } - - // Docker-compatibility: the "-h" flag for run/create is reserved for - // the hostname (see https://github.com/containers/libpod/issues/1367). - - return nil -} diff --git a/cmd/podmanV2/containers/exec.go b/cmd/podmanV2/containers/exec.go deleted file mode 100644 index 4bff57dbb..000000000 --- a/cmd/podmanV2/containers/exec.go +++ /dev/null @@ -1,93 +0,0 @@ -package containers - -import ( - "bufio" - "os" - - "github.com/containers/libpod/cmd/podmanV2/common" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - envLib "github.com/containers/libpod/pkg/env" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - execDescription = `Execute the specified command inside a running container. -` - execCommand = &cobra.Command{ - Use: "exec [flags] CONTAINER [COMMAND [ARG...]]", - Short: "Run a process in a running container", - Long: execDescription, - PreRunE: preRunE, - RunE: exec, - Example: `podman exec -it ctrID ls - podman exec -it -w /tmp myCtr pwd - podman exec --user root ctrID ls`, - } -) - -var ( - envInput, envFile []string - execOpts entities.ExecOptions -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode}, - Command: execCommand, - }) - flags := execCommand.Flags() - flags.SetInterspersed(false) - flags.StringVar(&execOpts.DetachKeys, "detach-keys", common.GetDefaultDetachKeys(), "Select 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 _") - flags.StringArrayVarP(&envInput, "env", "e", []string{}, "Set environment variables") - flags.StringSliceVar(&envFile, "env-file", []string{}, "Read in a file of environment variables") - flags.BoolVarP(&execOpts.Interactive, "interactive", "i", false, "Keep STDIN open even if not attached") - flags.BoolVarP(&execOpts.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - flags.BoolVar(&execOpts.Privileged, "privileged", false, "Give the process extended Linux capabilities inside the container. The default is false") - flags.BoolVarP(&execOpts.Tty, "tty", "t", false, "Allocate a pseudo-TTY. The default is false") - flags.StringVarP(&execOpts.User, "user", "u", "", "Sets the username or UID used and optionally the groupname or GID for the specified command") - flags.UintVar(&execOpts.PreserveFDs, "preserve-fds", 0, "Pass N additional file descriptors to the container") - flags.StringVarP(&execOpts.WorkDir, "workdir", "w", "", "Working directory inside the container") - if registry.IsRemote() { - _ = flags.MarkHidden("latest") - _ = flags.MarkHidden("preserve-fds") - } - -} -func exec(cmd *cobra.Command, args []string) error { - var nameOrId string - execOpts.Cmd = args - if !execOpts.Latest { - execOpts.Cmd = args[1:] - nameOrId = args[0] - } - // Validate given environment variables - execOpts.Envs = make(map[string]string) - for _, f := range envFile { - fileEnv, err := envLib.ParseFile(f) - if err != nil { - return err - } - execOpts.Envs = envLib.Join(execOpts.Envs, fileEnv) - } - - cliEnv, err := envLib.ParseSlice(envInput) - if err != nil { - return errors.Wrap(err, "error parsing environment variables") - } - - execOpts.Envs = envLib.Join(execOpts.Envs, cliEnv) - execOpts.Streams.OutputStream = os.Stdout - execOpts.Streams.ErrorStream = os.Stderr - if execOpts.Interactive { - execOpts.Streams.InputStream = bufio.NewReader(os.Stdin) - execOpts.Streams.AttachInput = true - } - execOpts.Streams.AttachOutput = true - execOpts.Streams.AttachError = true - - exitCode, err := registry.ContainerEngine().ContainerExec(registry.GetContext(), nameOrId, execOpts) - registry.SetExitCode(exitCode) - return err -} diff --git a/cmd/podmanV2/containers/exists.go b/cmd/podmanV2/containers/exists.go deleted file mode 100644 index 22c798fcd..000000000 --- a/cmd/podmanV2/containers/exists.go +++ /dev/null @@ -1,43 +0,0 @@ -package containers - -import ( - "context" - "os" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - containerExistsDescription = `If the named container exists in local storage, podman container exists exits with 0, otherwise the exit code will be 1.` - - existsCommand = &cobra.Command{ - Use: "exists CONTAINER", - Short: "Check if a container exists in local storage", - Long: containerExistsDescription, - Example: `podman container exists containerID - podman container exists myctr || podman run --name myctr [etc...]`, - RunE: exists, - Args: cobra.ExactArgs(1), - } -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: existsCommand, - Parent: containerCmd, - }) -} - -func exists(cmd *cobra.Command, args []string) error { - response, err := registry.ContainerEngine().ContainerExists(context.Background(), args[0]) - if err != nil { - return err - } - if !response.Value { - os.Exit(1) - } - return nil -} diff --git a/cmd/podmanV2/containers/export.go b/cmd/podmanV2/containers/export.go deleted file mode 100644 index b93b60878..000000000 --- a/cmd/podmanV2/containers/export.go +++ /dev/null @@ -1,57 +0,0 @@ -package containers - -import ( - "context" - "os" - - "github.com/containers/libpod/cmd/podmanV2/parse" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/pkg/errors" - "github.com/spf13/cobra" - "golang.org/x/crypto/ssh/terminal" -) - -var ( - exportDescription = "Exports container's filesystem contents as a tar archive" + - " and saves it on the local machine." - - exportCommand = &cobra.Command{ - Use: "export [flags] CONTAINER", - Short: "Export container's filesystem contents as a tar archive", - Long: exportDescription, - PersistentPreRunE: preRunE, - RunE: export, - Args: cobra.ExactArgs(1), - Example: `podman export ctrID > myCtr.tar - podman export --output="myCtr.tar" ctrID`, - } -) - -var ( - exportOpts entities.ContainerExportOptions -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: exportCommand, - }) - exportCommand.SetHelpTemplate(registry.HelpTemplate()) - exportCommand.SetUsageTemplate(registry.UsageTemplate()) - flags := exportCommand.Flags() - flags.StringVarP(&exportOpts.Output, "output", "o", "", "Write to a specified file (default: stdout, which must be redirected)") -} - -func export(cmd *cobra.Command, args []string) error { - if len(exportOpts.Output) == 0 { - file := os.Stdout - if terminal.IsTerminal(int(file.Fd())) { - return errors.Errorf("refusing to export to terminal. Use -o flag or redirect") - } - exportOpts.Output = "/dev/stdout" - } else if err := parse.ValidateFileName(exportOpts.Output); err != nil { - return err - } - return registry.ContainerEngine().ContainerExport(context.Background(), args[0], exportOpts) -} diff --git a/cmd/podmanV2/containers/inspect.go b/cmd/podmanV2/containers/inspect.go deleted file mode 100644 index 3147426cb..000000000 --- a/cmd/podmanV2/containers/inspect.go +++ /dev/null @@ -1,79 +0,0 @@ -package containers - -import ( - "context" - "fmt" - "os" - "strings" - "text/template" - - "github.com/containers/libpod/cmd/podmanV2/common" - "github.com/containers/libpod/cmd/podmanV2/registry" - - "github.com/containers/libpod/pkg/domain/entities" - json "github.com/json-iterator/go" - "github.com/spf13/cobra" -) - -var ( - // podman container _inspect_ - inspectCmd = &cobra.Command{ - Use: "inspect [flags] CONTAINER", - Short: "Display the configuration of a container", - Long: `Displays the low-level information on a container identified by name or ID.`, - PreRunE: preRunE, - RunE: inspect, - Example: `podman container inspect myCtr - podman container inspect -l --format '{{.Id}} {{.Config.Labels}}'`, - } - inspectOpts *entities.InspectOptions -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: inspectCmd, - Parent: containerCmd, - }) - inspectOpts = common.AddInspectFlagSet(inspectCmd) - flags := inspectCmd.Flags() - - if !registry.IsRemote() { - flags.BoolVarP(&inspectOpts.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - } - -} - -func inspect(cmd *cobra.Command, args []string) error { - responses, err := registry.ContainerEngine().ContainerInspect(context.Background(), args, *inspectOpts) - if err != nil { - return err - } - if inspectOpts.Format == "" { - b, err := json.MarshalIndent(responses, "", " ") - if err != nil { - return err - } - fmt.Println(string(b)) - return nil - } - format := inspectOpts.Format - if !strings.HasSuffix(format, "\n") { - format += "\n" - } - tmpl, err := template.New("inspect").Parse(format) - if err != nil { - return err - } - for _, i := range responses { - if err := tmpl.Execute(os.Stdout, i); err != nil { - return err - } - } - return nil -} - -func Inspect(cmd *cobra.Command, args []string, options *entities.InspectOptions) error { - inspectOpts = options - return inspect(cmd, args) -} diff --git a/cmd/podmanV2/containers/kill.go b/cmd/podmanV2/containers/kill.go deleted file mode 100644 index 6e6debfec..000000000 --- a/cmd/podmanV2/containers/kill.go +++ /dev/null @@ -1,72 +0,0 @@ -package containers - -import ( - "context" - "fmt" - - "github.com/containers/libpod/cmd/podmanV2/parse" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/cmd/podmanV2/utils" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/containers/libpod/pkg/signal" - "github.com/spf13/cobra" -) - -var ( - killDescription = "The main process inside each container specified will be sent SIGKILL, or any signal specified with option --signal." - killCommand = &cobra.Command{ - Use: "kill [flags] CONTAINER [CONTAINER...]", - Short: "Kill one or more running containers with a specific signal", - Long: killDescription, - RunE: kill, - PersistentPreRunE: preRunE, - Args: func(cmd *cobra.Command, args []string) error { - return parse.CheckAllLatestAndCIDFile(cmd, args, false, false) - }, - Example: `podman kill mywebserver - podman kill 860a4b23 - podman kill --signal TERM ctrID`, - } -) - -var ( - killOptions = entities.KillOptions{} -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: killCommand, - }) - flags := killCommand.Flags() - flags.BoolVarP(&killOptions.All, "all", "a", false, "Signal all running containers") - flags.StringVarP(&killOptions.Signal, "signal", "s", "KILL", "Signal to send to the container") - flags.BoolVarP(&killOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - if registry.IsRemote() { - _ = flags.MarkHidden("latest") - } -} - -func kill(cmd *cobra.Command, args []string) error { - var ( - err error - errs utils.OutputErrors - ) - // Check if the signalString provided by the user is valid - // Invalid signals will return err - if _, err = signal.ParseSignalNameOrNumber(killOptions.Signal); err != nil { - return err - } - responses, err := registry.ContainerEngine().ContainerKill(context.Background(), args, killOptions) - if err != nil { - return err - } - for _, r := range responses { - if r.Err == nil { - fmt.Println(r.Id) - } else { - errs = append(errs, r.Err) - } - } - return errs.PrintErrors() -} diff --git a/cmd/podmanV2/containers/list.go b/cmd/podmanV2/containers/list.go deleted file mode 100644 index 630d9bbc7..000000000 --- a/cmd/podmanV2/containers/list.go +++ /dev/null @@ -1,34 +0,0 @@ -package containers - -import ( - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - // podman container _list_ - listCmd = &cobra.Command{ - Use: "list", - Aliases: []string{"ls"}, - Args: cobra.NoArgs, - Short: "List containers", - Long: "Prints out information about the containers", - RunE: containers, - Example: `podman container list -a - podman container list -a --format "{{.ID}} {{.Image}} {{.Labels}} {{.Mounts}}" - podman container list --size --sort names`, - } -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: listCmd, - Parent: containerCmd, - }) -} - -func containers(cmd *cobra.Command, args []string) error { - return nil -} diff --git a/cmd/podmanV2/containers/pause.go b/cmd/podmanV2/containers/pause.go deleted file mode 100644 index a9b91b68f..000000000 --- a/cmd/podmanV2/containers/pause.go +++ /dev/null @@ -1,64 +0,0 @@ -package containers - -import ( - "context" - "fmt" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/cmd/podmanV2/utils" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/containers/libpod/pkg/rootless" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - pauseDescription = `Pauses one or more running containers. The container name or ID can be used.` - pauseCommand = &cobra.Command{ - Use: "pause [flags] CONTAINER [CONTAINER...]", - Short: "Pause all the processes in one or more containers", - Long: pauseDescription, - RunE: pause, - PersistentPreRunE: preRunE, - Example: `podman pause mywebserver - podman pause 860a4b23 - podman pause -a`, - } - - pauseOpts = entities.PauseUnPauseOptions{} -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: pauseCommand, - }) - flags := pauseCommand.Flags() - flags.BoolVarP(&pauseOpts.All, "all", "a", false, "Pause all running containers") - pauseCommand.SetHelpTemplate(registry.HelpTemplate()) - pauseCommand.SetUsageTemplate(registry.UsageTemplate()) -} - -func pause(cmd *cobra.Command, args []string) error { - var ( - errs utils.OutputErrors - ) - if rootless.IsRootless() && !registry.IsRemote() { - return errors.New("pause is not supported for rootless containers") - } - if len(args) < 1 && !pauseOpts.All { - return errors.Errorf("you must provide at least one container name or id") - } - responses, err := registry.ContainerEngine().ContainerPause(context.Background(), args, pauseOpts) - if err != nil { - return err - } - for _, r := range responses { - if r.Err == nil { - fmt.Println(r.Id) - } else { - errs = append(errs, r.Err) - } - } - return errs.PrintErrors() -} diff --git a/cmd/podmanV2/containers/ps.go b/cmd/podmanV2/containers/ps.go deleted file mode 100644 index 2397eb8c0..000000000 --- a/cmd/podmanV2/containers/ps.go +++ /dev/null @@ -1,379 +0,0 @@ -package containers - -import ( - "encoding/json" - "fmt" - "os" - "sort" - "strconv" - "strings" - "text/tabwriter" - "text/template" - "time" - - tm "github.com/buger/goterm" - "github.com/containers/buildah/pkg/formats" - "github.com/containers/libpod/cmd/podman/shared" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/cmd/podmanV2/report" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/cri-o/ocicni/pkg/ocicni" - "github.com/docker/go-units" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - psDescription = "Prints out information about the containers" - psCommand = &cobra.Command{ - Use: "ps", - Args: checkFlags, - Short: "List containers", - Long: psDescription, - RunE: ps, - PreRunE: preRunE, - Example: `podman ps -a - podman ps -a --format "{{.ID}} {{.Image}} {{.Labels}} {{.Mounts}}" - podman ps --size --sort names`, - } -) -var ( - listOpts = entities.ContainerListOptions{ - Filters: make(map[string][]string), - } - filters []string - noTrunc bool - defaultHeaders string = "CONTAINER ID\tIMAGE\tCOMMAND\tCREATED\tSTATUS\tPORTS\tNAMES" - -// CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES - -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: psCommand, - }) - flags := psCommand.Flags() - flags.BoolVarP(&listOpts.All, "all", "a", false, "Show all the containers, default is only running containers") - flags.StringSliceVarP(&filters, "filter", "f", []string{}, "Filter output based on conditions given") - flags.StringVar(&listOpts.Format, "format", "", "Pretty-print containers to JSON or using a Go template") - flags.IntVarP(&listOpts.Last, "last", "n", -1, "Print the n last created containers (all states)") - flags.BoolVarP(&listOpts.Latest, "latest", "l", false, "Show the latest container created (all states)") - flags.BoolVar(&listOpts.Namespace, "namespace", false, "Display namespace information") - flags.BoolVar(&listOpts.Namespace, "ns", false, "Display namespace information") - flags.BoolVar(&noTrunc, "no-trunc", false, "Display the extended information") - flags.BoolVarP(&listOpts.Pod, "pod", "p", false, "Print the ID and name of the pod the containers are associated with") - flags.BoolVarP(&listOpts.Quiet, "quiet", "q", false, "Print the numeric IDs of the containers only") - flags.BoolVarP(&listOpts.Size, "size", "s", false, "Display the total file sizes") - flags.StringVar(&listOpts.Sort, "sort", "created", "Sort output by command, created, id, image, names, runningfor, size, or status") - flags.BoolVar(&listOpts.Sync, "sync", false, "Sync container state with OCI runtime") - flags.UintVarP(&listOpts.Watch, "watch", "w", 0, "Watch the ps output on an interval in seconds") - if registry.IsRemote() { - _ = flags.MarkHidden("latest") - } -} -func checkFlags(c *cobra.Command, args []string) error { - // latest, and last are mutually exclusive. - if listOpts.Last >= 0 && listOpts.Latest { - return errors.Errorf("last and latest are mutually exclusive") - } - // Filter on status forces all - for _, filter := range filters { - splitFilter := strings.SplitN(filter, "=", 2) - if strings.ToLower(splitFilter[0]) == "status" { - listOpts.All = true - break - } - } - // Quiet conflicts with size and namespace and is overridden by a Go - // template. - if listOpts.Quiet { - if listOpts.Size || listOpts.Namespace { - return errors.Errorf("quiet conflicts with size and namespace") - } - if c.Flag("format").Changed && listOpts.Format != formats.JSONString { - // Quiet is overridden by Go template output. - listOpts.Quiet = false - } - } - // Size and namespace conflict with each other - if listOpts.Size && listOpts.Namespace { - return errors.Errorf("size and namespace options conflict") - } - - if listOpts.Watch > 0 && listOpts.Latest { - return errors.New("the watch and latest flags cannot be used together") - } - return nil -} - -func jsonOut(responses []entities.ListContainer) error { - b, err := json.MarshalIndent(responses, "", " ") - if err != nil { - return err - } - fmt.Println(string(b)) - return nil -} - -func quietOut(responses []entities.ListContainer) error { - for _, r := range responses { - id := r.ID - if !noTrunc { - id = id[0:12] - } - fmt.Println(id) - } - return nil -} - -func getResponses() ([]entities.ListContainer, error) { - responses, err := registry.ContainerEngine().ContainerList(registry.GetContext(), listOpts) - if err != nil { - return nil, err - } - if len(listOpts.Sort) > 0 { - responses, err = entities.SortPsOutput(listOpts.Sort, responses) - if err != nil { - return nil, err - } - } - return responses, nil -} - -func ps(cmd *cobra.Command, args []string) error { - // []string to map[string][]string - for _, f := range filters { - split := strings.SplitN(f, "=", 2) - if len(split) == 1 { - return errors.Errorf("invalid filter %q", f) - } - listOpts.Filters[split[0]] = append(listOpts.Filters[split[0]], split[1]) - } - responses, err := getResponses() - if err != nil { - return err - } - if len(listOpts.Sort) > 0 { - responses, err = entities.SortPsOutput(listOpts.Sort, responses) - if err != nil { - return err - } - } - if listOpts.Format == "json" { - return jsonOut(responses) - } - if listOpts.Quiet { - return quietOut(responses) - } - headers, row := createPsOut() - if cmd.Flag("format").Changed { - row = listOpts.Format - if !strings.HasPrefix(row, "\n") { - row += "\n" - } - } - format := "{{range . }}" + row + "{{end}}" - if !listOpts.Quiet && !cmd.Flag("format").Changed { - format = headers + format - } - funcs := report.AppendFuncMap(psFuncMap) - tmpl, err := template.New("listPods").Funcs(funcs).Parse(format) - if err != nil { - return err - } - w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0) - if listOpts.Watch > 0 { - for { - tm.Clear() - tm.MoveCursor(1, 1) - tm.Flush() - responses, err := getResponses() - if err != nil { - return err - } - if err := tmpl.Execute(w, responses); err != nil { - return nil - } - if err := w.Flush(); err != nil { - return err - } - time.Sleep(time.Duration(listOpts.Watch) * time.Second) - tm.Clear() - tm.MoveCursor(1, 1) - tm.Flush() - } - } else if listOpts.Watch < 1 { - if err := tmpl.Execute(w, responses); err != nil { - return err - } - return w.Flush() - } - return nil -} - -func createPsOut() (string, string) { - var row string - if listOpts.Namespace { - headers := "CONTAINER ID\tNAMES\tPID\tCGROUPNS\tIPC\tMNT\tNET\tPIDN\tUSERNS\tUTS\n" - row := "{{.ID}}\t{{names .Names}}\t{{.Pid}}\t{{.Namespaces.Cgroup}}\t{{.Namespaces.IPC}}\t{{.Namespaces.MNT}}\t{{.Namespaces.NET}}\t{{.Namespaces.PIDNS}}\t{{.Namespaces.User}}\t{{.Namespaces.UTS}}\n" - return headers, row - } - headers := defaultHeaders - if noTrunc { - row += "{{.ID}}" - } else { - row += "{{slice .ID 0 12}}" - } - row += "\t{{.Image}}\t{{cmd .Command}}\t{{humanDuration .Created}}\t{{state .}}\t{{ports .Ports}}\t{{names .Names}}" - - if listOpts.Pod { - headers += "\tPOD ID\tPODNAME" - if noTrunc { - row += "\t{{.Pod}}" - } else { - row += "\t{{slice .Pod 0 12}}" - } - row += "\t{{.PodName}}" - } - - if listOpts.Size { - headers += "\tSIZE" - row += "\t{{consize .Size}}" - } - if !strings.HasSuffix(headers, "\n") { - headers += "\n" - } - if !strings.HasSuffix(row, "\n") { - row += "\n" - } - return headers, row -} - -var psFuncMap = template.FuncMap{ - "cmd": func(conCommand []string) string { - return strings.Join(conCommand, " ") - }, - "state": func(con entities.ListContainer) string { - var state string - switch con.State { - case "running": - t := units.HumanDuration(time.Since(time.Unix(con.StartedAt, 0))) - state = "Up " + t + " ago" - case "configured": - state = "Created" - case "exited": - t := units.HumanDuration(time.Since(time.Unix(con.ExitedAt, 0))) - state = fmt.Sprintf("Exited (%d) %s ago", con.ExitCode, t) - default: - state = con.State - } - return state - }, - "ports": func(ports []ocicni.PortMapping) string { - if len(ports) == 0 { - return "" - } - return portsToString(ports) - }, - "names": func(names []string) string { - return names[0] - }, - "consize": func(csize shared.ContainerSize) string { - virt := units.HumanSizeWithPrecision(float64(csize.RootFsSize), 3) - s := units.HumanSizeWithPrecision(float64(csize.RwSize), 3) - return fmt.Sprintf("%s (virtual %s)", s, virt) - }, -} - -// portsToString converts the ports used to a string of the from "port1, port2" -// and also groups a continuous list of ports into a readable format. -func portsToString(ports []ocicni.PortMapping) string { - type portGroup struct { - first int32 - last int32 - } - var portDisplay []string - if len(ports) == 0 { - return "" - } - //Sort the ports, so grouping continuous ports become easy. - sort.Slice(ports, func(i, j int) bool { - return comparePorts(ports[i], ports[j]) - }) - - // portGroupMap is used for grouping continuous ports. - portGroupMap := make(map[string]*portGroup) - var groupKeyList []string - - for _, v := range ports { - - hostIP := v.HostIP - if hostIP == "" { - hostIP = "0.0.0.0" - } - // If hostPort and containerPort are not same, consider as individual port. - if v.ContainerPort != v.HostPort { - portDisplay = append(portDisplay, fmt.Sprintf("%s:%d->%d/%s", hostIP, v.HostPort, v.ContainerPort, v.Protocol)) - continue - } - - portMapKey := fmt.Sprintf("%s/%s", hostIP, v.Protocol) - - portgroup, ok := portGroupMap[portMapKey] - if !ok { - portGroupMap[portMapKey] = &portGroup{first: v.ContainerPort, last: v.ContainerPort} - // This list is required to traverse portGroupMap. - groupKeyList = append(groupKeyList, portMapKey) - continue - } - - if portgroup.last == (v.ContainerPort - 1) { - portgroup.last = v.ContainerPort - continue - } - } - // For each portMapKey, format group list and appned to output string. - for _, portKey := range groupKeyList { - group := portGroupMap[portKey] - portDisplay = append(portDisplay, formatGroup(portKey, group.first, group.last)) - } - return strings.Join(portDisplay, ", ") -} - -func comparePorts(i, j ocicni.PortMapping) bool { - if i.ContainerPort != j.ContainerPort { - return i.ContainerPort < j.ContainerPort - } - - if i.HostIP != j.HostIP { - return i.HostIP < j.HostIP - } - - if i.HostPort != j.HostPort { - return i.HostPort < j.HostPort - } - - return i.Protocol < j.Protocol -} - -// formatGroup returns the group as <IP:startPort:lastPort->startPort:lastPort/Proto> -// e.g 0.0.0.0:1000-1006->1000-1006/tcp. -func formatGroup(key string, start, last int32) string { - parts := strings.Split(key, "/") - groupType := parts[0] - var ip string - if len(parts) > 1 { - ip = parts[0] - groupType = parts[1] - } - group := strconv.Itoa(int(start)) - if start != last { - group = fmt.Sprintf("%s-%d", group, last) - } - if ip != "" { - group = fmt.Sprintf("%s:%s->%s", ip, group, group) - } - return fmt.Sprintf("%s/%s", group, groupType) -} diff --git a/cmd/podmanV2/containers/restart.go b/cmd/podmanV2/containers/restart.go deleted file mode 100644 index 5f1d3fe51..000000000 --- a/cmd/podmanV2/containers/restart.go +++ /dev/null @@ -1,80 +0,0 @@ -package containers - -import ( - "context" - "fmt" - - "github.com/containers/libpod/cmd/podmanV2/parse" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/cmd/podmanV2/utils" - "github.com/containers/libpod/libpod/define" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - restartDescription = fmt.Sprintf(`Restarts one or more running containers. The container ID or name can be used. - - A timeout before forcibly stopping can be set, but defaults to %d seconds.`, defaultContainerConfig.Engine.StopTimeout) - - restartCommand = &cobra.Command{ - Use: "restart [flags] CONTAINER [CONTAINER...]", - Short: "Restart one or more containers", - Long: restartDescription, - RunE: restart, - PersistentPreRunE: preRunE, - Args: func(cmd *cobra.Command, args []string) error { - return parse.CheckAllLatestAndCIDFile(cmd, args, false, false) - }, - Example: `podman restart ctrID - podman restart --latest - podman restart ctrID1 ctrID2`, - } -) - -var ( - restartOptions = entities.RestartOptions{} - restartTimeout uint -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: restartCommand, - }) - flags := restartCommand.Flags() - flags.BoolVarP(&restartOptions.All, "all", "a", false, "Restart all non-running containers") - flags.BoolVarP(&restartOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - flags.BoolVar(&restartOptions.Running, "running", false, "Restart only running containers when --all is used") - flags.UintVarP(&restartTimeout, "time", "t", defaultContainerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container") - if registry.IsRemote() { - _ = flags.MarkHidden("latest") - } - flags.SetNormalizeFunc(utils.AliasFlags) -} - -func restart(cmd *cobra.Command, args []string) error { - var ( - errs utils.OutputErrors - ) - if len(args) < 1 && !restartOptions.Latest && !restartOptions.All { - return errors.Wrapf(define.ErrInvalidArg, "you must provide at least one container name or ID") - } - - if cmd.Flag("time").Changed { - restartOptions.Timeout = &restartTimeout - } - responses, err := registry.ContainerEngine().ContainerRestart(context.Background(), args, restartOptions) - if err != nil { - return err - } - for _, r := range responses { - if r.Err == nil { - fmt.Println(r.Id) - } else { - errs = append(errs, r.Err) - } - } - return errs.PrintErrors() -} diff --git a/cmd/podmanV2/containers/restore.go b/cmd/podmanV2/containers/restore.go deleted file mode 100644 index 6cab6ab50..000000000 --- a/cmd/podmanV2/containers/restore.go +++ /dev/null @@ -1,104 +0,0 @@ -package containers - -import ( - "context" - "fmt" - - "github.com/containers/libpod/cmd/podmanV2/parse" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/cmd/podmanV2/utils" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/containers/libpod/pkg/rootless" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - restoreDescription = ` - podman container restore - - Restores a container from a checkpoint. The container name or ID can be used. -` - restoreCommand = &cobra.Command{ - Use: "restore [flags] CONTAINER [CONTAINER...]", - Short: "Restores one or more containers from a checkpoint", - Long: restoreDescription, - RunE: restore, - Args: func(cmd *cobra.Command, args []string) error { - return parse.CheckAllLatestAndCIDFile(cmd, args, true, false) - }, - Example: `podman container restore ctrID - podman container restore --latest - podman container restore --all`, - } -) - -var ( - restoreOptions entities.RestoreOptions -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: restoreCommand, - Parent: containerCmd, - }) - flags := restoreCommand.Flags() - flags.BoolVarP(&restoreOptions.All, "all", "a", false, "Restore all checkpointed containers") - flags.BoolVarP(&restoreOptions.Keep, "keep", "k", false, "Keep all temporary checkpoint files") - flags.BoolVarP(&restoreOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - flags.BoolVar(&restoreOptions.TCPEstablished, "tcp-established", false, "Restore a container with established TCP connections") - flags.StringVarP(&restoreOptions.Import, "import", "i", "", "Restore from exported checkpoint archive (tar.gz)") - flags.StringVarP(&restoreOptions.Name, "name", "n", "", "Specify new name for container restored from exported checkpoint (only works with --import)") - flags.BoolVar(&restoreOptions.IgnoreRootFS, "ignore-rootfs", false, "Do not apply root file-system changes when importing from exported checkpoint") - flags.BoolVar(&restoreOptions.IgnoreStaticIP, "ignore-static-ip", false, "Ignore IP address set via --static-ip") - flags.BoolVar(&restoreOptions.IgnoreStaticMAC, "ignore-static-mac", false, "Ignore MAC address set via --mac-address") - if registry.IsRemote() { - _ = flags.MarkHidden("latest") - } -} - -func restore(cmd *cobra.Command, args []string) error { - var errs utils.OutputErrors - if rootless.IsRootless() { - return errors.New("restoring a container requires root") - } - if restoreOptions.Import == "" && restoreOptions.IgnoreRootFS { - return errors.Errorf("--ignore-rootfs can only be used with --import") - } - if restoreOptions.Import == "" && restoreOptions.Name != "" { - return errors.Errorf("--name can only be used with --import") - } - if restoreOptions.Name != "" && restoreOptions.TCPEstablished { - return errors.Errorf("--tcp-established cannot be used with --name") - } - - argLen := len(args) - if restoreOptions.Import != "" { - if restoreOptions.All || restoreOptions.Latest { - return errors.Errorf("Cannot use --import with --all or --latest") - } - if argLen > 0 { - return errors.Errorf("Cannot use --import with positional arguments") - } - } - if (restoreOptions.All || restoreOptions.Latest) && argLen > 0 { - return errors.Errorf("no arguments are needed with --all or --latest") - } - if argLen < 1 && !restoreOptions.All && !restoreOptions.Latest && restoreOptions.Import == "" { - return errors.Errorf("you must provide at least one name or id") - } - responses, err := registry.ContainerEngine().ContainerRestore(context.Background(), args, restoreOptions) - if err != nil { - return err - } - for _, r := range responses { - if r.Err == nil { - fmt.Println(r.Id) - } else { - errs = append(errs, r.Err) - } - } - return errs.PrintErrors() - -} diff --git a/cmd/podmanV2/containers/rm.go b/cmd/podmanV2/containers/rm.go deleted file mode 100644 index 75655e4cd..000000000 --- a/cmd/podmanV2/containers/rm.go +++ /dev/null @@ -1,94 +0,0 @@ -package containers - -import ( - "context" - "fmt" - - "github.com/containers/libpod/cmd/podmanV2/parse" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/cmd/podmanV2/utils" - "github.com/containers/libpod/libpod/define" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" - "github.com/spf13/cobra" -) - -var ( - rmDescription = `Removes one or more containers from the host. The container name or ID can be used. - - Command does not remove images. Running or unusable containers will not be removed without the -f option.` - rmCommand = &cobra.Command{ - Use: "rm [flags] CONTAINER [CONTAINER...]", - Short: "Remove one or more containers", - Long: rmDescription, - RunE: rm, - PersistentPreRunE: preRunE, - Args: func(cmd *cobra.Command, args []string) error { - return parse.CheckAllLatestAndCIDFile(cmd, args, false, true) - }, - Example: `podman rm imageID - podman rm mywebserver myflaskserver 860a4b23 - podman rm --force --all - podman rm -f c684f0d469f2`, - } -) - -var ( - rmOptions = entities.RmOptions{} -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: rmCommand, - }) - flags := rmCommand.Flags() - flags.BoolVarP(&rmOptions.All, "all", "a", false, "Remove all containers") - flags.BoolVarP(&rmOptions.Ignore, "ignore", "i", false, "Ignore errors when a specified container is missing") - flags.BoolVarP(&rmOptions.Force, "force", "f", false, "Force removal of a running or unusable container. The default is false") - flags.BoolVarP(&rmOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - flags.BoolVar(&rmOptions.Storage, "storage", false, "Remove container from storage library") - flags.BoolVarP(&rmOptions.Volumes, "volumes", "v", false, "Remove anonymous volumes associated with the container") - flags.StringArrayVarP(&rmOptions.CIDFiles, "cidfile", "", nil, "Read the container ID from the file") - if registry.IsRemote() { - _ = flags.MarkHidden("latest") - _ = flags.MarkHidden("ignore") - _ = flags.MarkHidden("cidfile") - _ = flags.MarkHidden("storage") - } - -} - -func rm(cmd *cobra.Command, args []string) error { - var ( - errs utils.OutputErrors - ) - // Storage conflicts with --all/--latest/--volumes/--cidfile/--ignore - if rmOptions.Storage { - if rmOptions.All || rmOptions.Ignore || rmOptions.Latest || rmOptions.Volumes || rmOptions.CIDFiles != nil { - return errors.Errorf("--storage conflicts with --volumes, --all, --latest, --ignore and --cidfile") - } - } - responses, err := registry.ContainerEngine().ContainerRm(context.Background(), args, rmOptions) - if err != nil { - // TODO exitcode is a global main variable to track exit codes. - // we need this enabled - //if len(c.InputArgs) < 2 { - // exitCode = setExitCode(err) - //} - return err - } - for _, r := range responses { - if r.Err != nil { - // TODO this will not work with the remote client - if errors.Cause(err) == define.ErrWillDeadlock { - logrus.Errorf("Potential deadlock detected - please run 'podman system renumber' to resolve") - } - errs = append(errs, r.Err) - } else { - fmt.Println(r.Id) - } - } - return errs.PrintErrors() -} diff --git a/cmd/podmanV2/containers/run.go b/cmd/podmanV2/containers/run.go deleted file mode 100644 index bd90aee2f..000000000 --- a/cmd/podmanV2/containers/run.go +++ /dev/null @@ -1,125 +0,0 @@ -package containers - -import ( - "fmt" - "os" - "strings" - - "github.com/sirupsen/logrus" - - "github.com/containers/libpod/pkg/domain/entities" - - "github.com/containers/libpod/cmd/podmanV2/common" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/libpod/define" - "github.com/containers/libpod/pkg/specgen" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - runDescription = "Runs a command in a new container from the given image" - runCommand = &cobra.Command{ - Use: "run [flags] IMAGE [COMMAND [ARG...]]", - Short: "Run a command in a new container", - Long: runDescription, - PreRunE: preRunE, - RunE: run, - Example: `podman run imageID ls -alF /etc - podman run --network=host imageID dnf -y install java - podman run --volume /var/hostdir:/var/ctrdir -i -t fedora /bin/bash`, - } -) - -var ( - runOpts = entities.ContainerRunOptions{ - OutputStream: os.Stdout, - InputStream: os.Stdin, - ErrorStream: os.Stderr, - } - runRmi bool -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode}, - Command: runCommand, - }) - flags := runCommand.Flags() - flags.AddFlagSet(common.GetCreateFlags(&cliVals)) - flags.AddFlagSet(common.GetNetFlags()) - flags.SetNormalizeFunc(common.AliasFlags) - flags.BoolVar(&runOpts.SigProxy, "sig-proxy", true, "Proxy received signals to the process") - flags.BoolVar(&runRmi, "rmi", false, "Remove container image unless used by other containers") - if registry.IsRemote() { - _ = flags.MarkHidden("authfile") - } -} - -func run(cmd *cobra.Command, args []string) error { - var ( - err error - ) - cliVals.Net, err = common.NetFlagsToNetOptions(cmd) - if err != nil { - return err - } - if af := cliVals.Authfile; len(af) > 0 { - if _, err := os.Stat(af); err != nil { - return errors.Wrapf(err, "error checking authfile path %s", af) - } - } - runOpts.Rm = cliVals.Rm - if err := createInit(cmd); err != nil { - return err - } - - // If -i is not set, clear stdin - if !cliVals.Interactive { - runOpts.InputStream = nil - } - - // If attach is set, clear stdin/stdout/stderr and only attach requested - if cmd.Flag("attach").Changed { - runOpts.OutputStream = nil - runOpts.ErrorStream = nil - if !cliVals.Interactive { - runOpts.InputStream = nil - } - - for _, stream := range cliVals.Attach { - switch strings.ToLower(stream) { - case "stdout": - runOpts.OutputStream = os.Stdout - case "stderr": - runOpts.ErrorStream = os.Stderr - case "stdin": - runOpts.InputStream = os.Stdin - default: - return errors.Wrapf(define.ErrInvalidArg, "invalid stream %q for --attach - must be one of stdin, stdout, or stderr", stream) - } - } - } - runOpts.Detach = cliVals.Detach - runOpts.DetachKeys = cliVals.DetachKeys - s := specgen.NewSpecGenerator(args[0]) - if err := common.FillOutSpecGen(s, &cliVals, args); err != nil { - return err - } - runOpts.Spec = s - report, err := registry.ContainerEngine().ContainerRun(registry.GetContext(), runOpts) - if err != nil { - return err - } - if cliVals.Detach { - fmt.Println(report.Id) - } - registry.SetExitCode(report.ExitCode) - if runRmi { - _, err := registry.ImageEngine().Delete(registry.GetContext(), []string{report.Id}, entities.ImageDeleteOptions{}) - if err != nil { - logrus.Errorf("%s", errors.Wrapf(err, "failed removing image")) - } - } - return nil -} diff --git a/cmd/podmanV2/containers/start.go b/cmd/podmanV2/containers/start.go deleted file mode 100644 index 0ae2f6d50..000000000 --- a/cmd/podmanV2/containers/start.go +++ /dev/null @@ -1,87 +0,0 @@ -package containers - -import ( - "fmt" - "os" - - "github.com/containers/libpod/cmd/podmanV2/common" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/cmd/podmanV2/utils" - "github.com/containers/libpod/libpod/define" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - startDescription = `Starts one or more containers. The container name or ID can be used.` - startCommand = &cobra.Command{ - Use: "start [flags] CONTAINER [CONTAINER...]", - Short: "Start one or more containers", - Long: startDescription, - RunE: start, - PreRunE: preRunE, - Args: cobra.MinimumNArgs(1), - Example: `podman start --latest - podman start 860a4b231279 5421ab43b45 - podman start --interactive --attach imageID`, - } -) - -var ( - startOptions entities.ContainerStartOptions -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode}, - Command: startCommand, - }) - flags := startCommand.Flags() - flags.BoolVarP(&startOptions.Attach, "attach", "a", false, "Attach container's STDOUT and STDERR") - flags.StringVar(&startOptions.DetachKeys, "detach-keys", common.GetDefaultDetachKeys(), "Select the key sequence for detaching a container. Format is a single character `[a-Z]` or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-z`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`") - flags.BoolVarP(&startOptions.Interactive, "interactive", "i", false, "Keep STDIN open even if not attached") - flags.BoolVarP(&startOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - flags.BoolVar(&startOptions.SigProxy, "sig-proxy", false, "Proxy received signals to the process (default true if attaching, false otherwise)") - if registry.IsRemote() { - _ = flags.MarkHidden("latest") - _ = flags.MarkHidden("sig-proxy") - } - -} - -func start(cmd *cobra.Command, args []string) error { - var errs utils.OutputErrors - if len(args) > 1 && startOptions.Attach { - return errors.Errorf("you cannot start and attach multiple containers at once") - } - - sigProxy := startOptions.SigProxy || startOptions.Attach - if cmd.Flag("sig-proxy").Changed { - sigProxy = startOptions.SigProxy - } - - if sigProxy && !startOptions.Attach { - return errors.Wrapf(define.ErrInvalidArg, "you cannot use sig-proxy without --attach") - } - if startOptions.Attach { - startOptions.Stdin = os.Stdin - startOptions.Stderr = os.Stderr - startOptions.Stdout = os.Stdout - } - - responses, err := registry.ContainerEngine().ContainerStart(registry.GetContext(), args, startOptions) - if err != nil { - return err - } - - for _, r := range responses { - if r.Err == nil { - fmt.Println(r.Id) - } else { - errs = append(errs, r.Err) - } - } - // TODO need to understand an implement exitcodes - return errs.PrintErrors() -} diff --git a/cmd/podmanV2/containers/stop.go b/cmd/podmanV2/containers/stop.go deleted file mode 100644 index d6f31352f..000000000 --- a/cmd/podmanV2/containers/stop.go +++ /dev/null @@ -1,83 +0,0 @@ -package containers - -import ( - "context" - "fmt" - - "github.com/containers/libpod/cmd/podmanV2/parse" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/cmd/podmanV2/utils" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - stopDescription = fmt.Sprintf(`Stops one or more running containers. The container name or ID can be used. - - A timeout to forcibly stop the container can also be set but defaults to %d seconds otherwise.`, defaultContainerConfig.Engine.StopTimeout) - stopCommand = &cobra.Command{ - Use: "stop [flags] CONTAINER [CONTAINER...]", - Short: "Stop one or more containers", - Long: stopDescription, - RunE: stop, - PersistentPreRunE: preRunE, - Args: func(cmd *cobra.Command, args []string) error { - return parse.CheckAllLatestAndCIDFile(cmd, args, false, true) - }, - Example: `podman stop ctrID - podman stop --latest - podman stop --time 2 mywebserver 6e534f14da9d`, - } -) - -var ( - stopOptions = entities.StopOptions{} - stopTimeout uint -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: stopCommand, - }) - flags := stopCommand.Flags() - flags.BoolVarP(&stopOptions.All, "all", "a", false, "Stop all running containers") - flags.BoolVarP(&stopOptions.Ignore, "ignore", "i", false, "Ignore errors when a specified container is missing") - flags.StringArrayVarP(&stopOptions.CIDFiles, "cidfile", "", nil, "Read the container ID from the file") - flags.BoolVarP(&stopOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - flags.UintVarP(&stopTimeout, "time", "t", defaultContainerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container") - if registry.EngineOptions.EngineMode == entities.ABIMode { - _ = flags.MarkHidden("latest") - _ = flags.MarkHidden("cidfile") - _ = flags.MarkHidden("ignore") - } - flags.SetNormalizeFunc(utils.AliasFlags) -} - -func stop(cmd *cobra.Command, args []string) error { - var ( - errs utils.OutputErrors - ) - stopOptions.Timeout = defaultContainerConfig.Engine.StopTimeout - if cmd.Flag("time").Changed { - stopOptions.Timeout = stopTimeout - } - - // TODO How do we access global attributes? - //if c.Bool("trace") { - // span, _ := opentracing.StartSpanFromContext(Ctx, "stopCmd") - // defer span.Finish() - //} - responses, err := registry.ContainerEngine().ContainerStop(context.Background(), args, stopOptions) - if err != nil { - return err - } - for _, r := range responses { - if r.Err == nil { - fmt.Println(r.Id) - } else { - errs = append(errs, r.Err) - } - } - return errs.PrintErrors() -} diff --git a/cmd/podmanV2/containers/top.go b/cmd/podmanV2/containers/top.go deleted file mode 100644 index a86c12e2a..000000000 --- a/cmd/podmanV2/containers/top.go +++ /dev/null @@ -1,91 +0,0 @@ -package containers - -import ( - "context" - "fmt" - "os" - "strings" - "text/tabwriter" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/containers/psgo" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - topDescription = fmt.Sprintf(`Similar to system "top" command. - - Specify format descriptors to alter the output. - - Running "podman top -l pid pcpu seccomp" will print the process ID, the CPU percentage and the seccomp mode of each process of the latest container. - Format Descriptors: - %s`, strings.Join(psgo.ListDescriptors(), ",")) - - topOptions = entities.TopOptions{} - - topCommand = &cobra.Command{ - Use: "top [flags] CONTAINER [FORMAT-DESCRIPTORS|ARGS]", - Short: "Display the running processes of a container", - Long: topDescription, - PersistentPreRunE: preRunE, - RunE: top, - Args: cobra.ArbitraryArgs, - Example: `podman top ctrID -podman top --latest -podman top ctrID pid seccomp args %C -podman top ctrID -eo user,pid,comm`, - } -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: topCommand, - }) - - topCommand.SetHelpTemplate(registry.HelpTemplate()) - topCommand.SetUsageTemplate(registry.UsageTemplate()) - - flags := topCommand.Flags() - flags.SetInterspersed(false) - flags.BoolVar(&topOptions.ListDescriptors, "list-descriptors", false, "") - flags.BoolVarP(&topOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - - _ = flags.MarkHidden("list-descriptors") // meant only for bash completion - if registry.IsRemote() { - _ = flags.MarkHidden("latest") - } -} - -func top(cmd *cobra.Command, args []string) error { - if topOptions.ListDescriptors { - fmt.Println(strings.Join(psgo.ListDescriptors(), "\n")) - return nil - } - - if len(args) < 1 && !topOptions.Latest { - return errors.Errorf("you must provide the name or id of a running container") - } - - if topOptions.Latest { - topOptions.Descriptors = args - } else { - topOptions.NameOrID = args[0] - topOptions.Descriptors = args[1:] - } - - topResponse, err := registry.ContainerEngine().ContainerTop(context.Background(), topOptions) - if err != nil { - return err - } - - w := tabwriter.NewWriter(os.Stdout, 5, 1, 3, ' ', 0) - for _, proc := range topResponse.Value { - if _, err := fmt.Fprintln(w, proc); err != nil { - return err - } - } - return w.Flush() -} diff --git a/cmd/podmanV2/containers/unpause.go b/cmd/podmanV2/containers/unpause.go deleted file mode 100644 index 6a3179f10..000000000 --- a/cmd/podmanV2/containers/unpause.go +++ /dev/null @@ -1,61 +0,0 @@ -package containers - -import ( - "context" - "fmt" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/cmd/podmanV2/utils" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/containers/libpod/pkg/rootless" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - unpauseDescription = `Unpauses one or more previously paused containers. The container name or ID can be used.` - unpauseCommand = &cobra.Command{ - Use: "unpause [flags] CONTAINER [CONTAINER...]", - Short: "Unpause the processes in one or more containers", - Long: unpauseDescription, - RunE: unpause, - PersistentPreRunE: preRunE, - Example: `podman unpause ctrID - podman unpause --all`, - } - unPauseOptions = entities.PauseUnPauseOptions{} -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: unpauseCommand, - Parent: containerCmd, - }) - flags := unpauseCommand.Flags() - flags.BoolVarP(&unPauseOptions.All, "all", "a", false, "Pause all running containers") -} - -func unpause(cmd *cobra.Command, args []string) error { - var ( - errs utils.OutputErrors - ) - if rootless.IsRootless() && !registry.IsRemote() { - return errors.New("unpause is not supported for rootless containers") - } - if len(args) < 1 && !unPauseOptions.All { - return errors.Errorf("you must provide at least one container name or id") - } - responses, err := registry.ContainerEngine().ContainerUnpause(context.Background(), args, unPauseOptions) - if err != nil { - return err - } - for _, r := range responses { - if r.Err == nil { - fmt.Println(r.Id) - } else { - errs = append(errs, r.Err) - } - } - return errs.PrintErrors() -} diff --git a/cmd/podmanV2/containers/utils.go b/cmd/podmanV2/containers/utils.go deleted file mode 100644 index 0c09d3e40..000000000 --- a/cmd/podmanV2/containers/utils.go +++ /dev/null @@ -1 +0,0 @@ -package containers diff --git a/cmd/podmanV2/containers/wait.go b/cmd/podmanV2/containers/wait.go deleted file mode 100644 index bf3c86200..000000000 --- a/cmd/podmanV2/containers/wait.go +++ /dev/null @@ -1,82 +0,0 @@ -package containers - -import ( - "context" - "fmt" - "time" - - "github.com/containers/libpod/cmd/podmanV2/parse" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/cmd/podmanV2/utils" - "github.com/containers/libpod/libpod/define" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - waitDescription = `Block until one or more containers stop and then print their exit codes. -` - waitCommand = &cobra.Command{ - Use: "wait [flags] CONTAINER [CONTAINER...]", - Short: "Block on one or more containers", - Long: waitDescription, - RunE: wait, - PersistentPreRunE: preRunE, - Args: func(cmd *cobra.Command, args []string) error { - return parse.CheckAllLatestAndCIDFile(cmd, args, false, false) - }, - Example: `podman wait --latest - podman wait --interval 5000 ctrID - podman wait ctrID1 ctrID2`, - } -) - -var ( - waitOptions = entities.WaitOptions{} - waitCondition string -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: waitCommand, - }) - - flags := waitCommand.Flags() - flags.DurationVarP(&waitOptions.Interval, "interval", "i", time.Duration(250), "Milliseconds to wait before polling for completion") - flags.BoolVarP(&waitOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - flags.StringVar(&waitCondition, "condition", "stopped", "Condition to wait on") - if registry.EngineOptions.EngineMode == entities.ABIMode { - // TODO: This is the same as V1. We could skip creating the flag altogether in V2... - _ = flags.MarkHidden("latest") - } -} - -func wait(cmd *cobra.Command, args []string) error { - var ( - err error - errs utils.OutputErrors - ) - if waitOptions.Interval == 0 { - return errors.New("interval must be greater then 0") - } - - waitOptions.Condition, err = define.StringToContainerStatus(waitCondition) - if err != nil { - return err - } - - responses, err := registry.ContainerEngine().ContainerWait(context.Background(), args, waitOptions) - if err != nil { - return err - } - for _, r := range responses { - if r.Error == nil { - fmt.Println(r.Id) - } else { - errs = append(errs, r.Error) - } - } - return errs.PrintErrors() -} diff --git a/cmd/podmanV2/healthcheck/healthcheck.go b/cmd/podmanV2/healthcheck/healthcheck.go deleted file mode 100644 index 2af398ff0..000000000 --- a/cmd/podmanV2/healthcheck/healthcheck.go +++ /dev/null @@ -1,33 +0,0 @@ -package healthcheck - -import ( - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - // Command: healthcheck - healthCmd = &cobra.Command{ - Use: "healthcheck", - Short: "Manage Healthcheck", - Long: "Manage Healthcheck", - TraverseChildren: true, - PersistentPreRunE: preRunE, - RunE: registry.SubCommandExists, - } -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: healthCmd, - }) - healthCmd.SetHelpTemplate(registry.HelpTemplate()) - healthCmd.SetUsageTemplate(registry.UsageTemplate()) -} - -func preRunE(cmd *cobra.Command, args []string) error { - _, err := registry.NewContainerEngine(cmd, args) - return err -} diff --git a/cmd/podmanV2/healthcheck/run.go b/cmd/podmanV2/healthcheck/run.go deleted file mode 100644 index bb2962eaf..000000000 --- a/cmd/podmanV2/healthcheck/run.go +++ /dev/null @@ -1,42 +0,0 @@ -package healthcheck - -import ( - "context" - "fmt" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - healthcheckRunDescription = "run the health check of a container" - healthcheckrunCommand = &cobra.Command{ - Use: "run [flags] CONTAINER", - Short: "run the health check of a container", - Long: healthcheckRunDescription, - Example: `podman healthcheck run mywebapp`, - RunE: run, - Args: cobra.ExactArgs(1), - } -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: healthcheckrunCommand, - Parent: healthCmd, - }) -} - -func run(cmd *cobra.Command, args []string) error { - response, err := registry.ContainerEngine().HealthCheckRun(context.Background(), args[0], entities.HealthCheckOptions{}) - if err != nil { - return err - } - if response.Status == "unhealthy" { - registry.SetExitCode(1) - } - fmt.Println(response.Status) - return err -} diff --git a/cmd/podmanV2/images/exists.go b/cmd/podmanV2/images/exists.go deleted file mode 100644 index d35d6825e..000000000 --- a/cmd/podmanV2/images/exists.go +++ /dev/null @@ -1,40 +0,0 @@ -package images - -import ( - "os" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - existsCmd = &cobra.Command{ - Use: "exists IMAGE", - Short: "Check if an image exists in local storage", - Long: `If the named image exists in local storage, podman image exists exits with 0, otherwise the exit code will be 1.`, - Args: cobra.ExactArgs(1), - RunE: exists, - Example: `podman image exists ID - podman image exists IMAGE && podman pull IMAGE`, - } -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: existsCmd, - Parent: imageCmd, - }) -} - -func exists(cmd *cobra.Command, args []string) error { - found, err := registry.ImageEngine().Exists(registry.GetContext(), args[0]) - if err != nil { - return err - } - if !found.Value { - os.Exit(1) - } - return nil -} diff --git a/cmd/podmanV2/images/history.go b/cmd/podmanV2/images/history.go deleted file mode 100644 index f6f15e2f2..000000000 --- a/cmd/podmanV2/images/history.go +++ /dev/null @@ -1,123 +0,0 @@ -package images - -import ( - "context" - "fmt" - "os" - "strings" - "text/tabwriter" - "text/template" - "time" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/cmd/podmanV2/report" - "github.com/containers/libpod/pkg/domain/entities" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - long = `Displays the history of an image. - - The information can be printed out in an easy to read, or user specified format, and can be truncated.` - - // podman _history_ - historyCmd = &cobra.Command{ - Use: "history [flags] IMAGE", - Short: "Show history of a specified image", - Long: long, - Example: "podman history quay.io/fedora/fedora", - Args: cobra.ExactArgs(1), - PersistentPreRunE: preRunE, - RunE: history, - } - - opts = struct { - human bool - noTrunc bool - quiet bool - format string - }{} -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: historyCmd, - }) - - historyCmd.SetHelpTemplate(registry.HelpTemplate()) - historyCmd.SetUsageTemplate(registry.UsageTemplate()) - - flags := historyCmd.Flags() - flags.StringVar(&opts.format, "format", "", "Change the output to JSON or a Go template") - flags.BoolVarP(&opts.human, "human", "H", false, "Display sizes and dates in human readable format") - flags.BoolVar(&opts.noTrunc, "no-trunc", false, "Do not truncate the output") - flags.BoolVar(&opts.noTrunc, "notruncate", false, "Do not truncate the output") - flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Display the numeric IDs only") -} - -func history(cmd *cobra.Command, args []string) error { - results, err := registry.ImageEngine().History(context.Background(), args[0], entities.ImageHistoryOptions{}) - if err != nil { - return err - } - - if opts.format == "json" { - var err error - if len(results.Layers) == 0 { - _, err = fmt.Fprintf(os.Stdout, "[]\n") - } else { - // ah-hoc change to "Created": type and format - type layer struct { - entities.ImageHistoryLayer - Created string `json:"Created"` - } - - layers := make([]layer, len(results.Layers)) - for i, l := range results.Layers { - layers[i].ImageHistoryLayer = l - layers[i].Created = time.Unix(l.Created, 0).Format(time.RFC3339) - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - enc := json.NewEncoder(os.Stdout) - err = enc.Encode(layers) - } - return err - } - - // Defaults - hdr := "ID\tCREATED\tCREATED BY\tSIZE\tCOMMENT\n" - row := "{{slice .ID 0 12}}\t{{humanDuration .Created}}\t{{ellipsis .CreatedBy 45}}\t{{.Size}}\t{{.Comment}}\n" - - if len(opts.format) > 0 { - hdr = "" - row = opts.format - if !strings.HasSuffix(opts.format, "\n") { - row += "\n" - } - } else { - switch { - case opts.human: - row = "{{slice .ID 0 12}}\t{{humanDuration .Created}}\t{{ellipsis .CreatedBy 45}}\t{{humanSize .Size}}\t{{.Comment}}\n" - case opts.noTrunc: - row = "{{.ID}}\t{{humanDuration .Created}}\t{{.CreatedBy}}\t{{humanSize .Size}}\t{{.Comment}}\n" - case opts.quiet: - hdr = "" - row = "{{.ID}}\n" - } - } - format := hdr + "{{range . }}" + row + "{{end}}" - - tmpl := template.Must(template.New("report").Funcs(report.PodmanTemplateFuncs()).Parse(format)) - w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0) - - _, _ = w.Write(report.ReportHeader("id", "created", "created by", "size", "comment")) - err = tmpl.Execute(w, results.Layers) - if err != nil { - fmt.Fprintln(os.Stderr, errors.Wrapf(err, "Failed to print report")) - } - w.Flush() - return nil -} diff --git a/cmd/podmanV2/images/image.go b/cmd/podmanV2/images/image.go deleted file mode 100644 index 9fc7b21d1..000000000 --- a/cmd/podmanV2/images/image.go +++ /dev/null @@ -1,35 +0,0 @@ -package images - -import ( - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - // Command: podman _image_ - imageCmd = &cobra.Command{ - Use: "image", - Short: "Manage images", - Long: "Manage images", - TraverseChildren: true, - PersistentPreRunE: preRunE, - RunE: registry.SubCommandExists, - } -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: imageCmd, - }) - imageCmd.SetHelpTemplate(registry.HelpTemplate()) - imageCmd.SetUsageTemplate(registry.UsageTemplate()) -} - -func preRunE(cmd *cobra.Command, args []string) error { - if _, err := registry.NewImageEngine(cmd, args); err != nil { - return err - } - return nil -} diff --git a/cmd/podmanV2/images/images.go b/cmd/podmanV2/images/images.go deleted file mode 100644 index d00f0996e..000000000 --- a/cmd/podmanV2/images/images.go +++ /dev/null @@ -1,33 +0,0 @@ -package images - -import ( - "strings" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - // podman _images_ Alias for podman image _list_ - imagesCmd = &cobra.Command{ - Use: strings.Replace(listCmd.Use, "list", "images", 1), - Args: listCmd.Args, - Short: listCmd.Short, - Long: listCmd.Long, - PreRunE: preRunE, - RunE: listCmd.RunE, - Example: strings.Replace(listCmd.Example, "podman image list", "podman images", -1), - } -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: imagesCmd, - }) - imagesCmd.SetHelpTemplate(registry.HelpTemplate()) - imagesCmd.SetUsageTemplate(registry.UsageTemplate()) - - imageListFlagSet(imagesCmd.Flags()) -} diff --git a/cmd/podmanV2/images/import.go b/cmd/podmanV2/images/import.go deleted file mode 100644 index 09a15585f..000000000 --- a/cmd/podmanV2/images/import.go +++ /dev/null @@ -1,87 +0,0 @@ -package images - -import ( - "context" - "fmt" - - "github.com/containers/libpod/cmd/podmanV2/parse" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/hashicorp/go-multierror" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - importDescription = `Create a container image from the contents of the specified tarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz). - - Note remote tar balls can be specified, via web address. - Optionally tag the image. You can specify the instructions using the --change option.` - importCommand = &cobra.Command{ - Use: "import [flags] PATH [REFERENCE]", - Short: "Import a tarball to create a filesystem image", - Long: importDescription, - RunE: importCon, - PersistentPreRunE: preRunE, - Example: `podman import http://example.com/ctr.tar url-image - cat ctr.tar | podman -q import --message "importing the ctr.tar tarball" - image-imported - cat ctr.tar | podman import -`, - } -) - -var ( - importOpts entities.ImageImportOptions -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: importCommand, - }) - - importCommand.SetHelpTemplate(registry.HelpTemplate()) - importCommand.SetUsageTemplate(registry.UsageTemplate()) - flags := importCommand.Flags() - flags.StringArrayVarP(&importOpts.Changes, "change", "c", []string{}, "Apply the following possible instructions to the created image (default []): CMD | ENTRYPOINT | ENV | EXPOSE | LABEL | STOPSIGNAL | USER | VOLUME | WORKDIR") - flags.StringVarP(&importOpts.Message, "message", "m", "", "Set commit message for imported image") - flags.BoolVarP(&importOpts.Quiet, "quiet", "q", false, "Suppress output") -} - -func importCon(cmd *cobra.Command, args []string) error { - var ( - source string - reference string - ) - switch len(args) { - case 0: - return errors.Errorf("need to give the path to the tarball, or must specify a tarball of '-' for stdin") - case 1: - source = args[0] - case 2: - source = args[0] - // TODO when save is merged, we need to process reference - // like it is done in there or we end up with docker.io prepends - // instead of the localhost ones - reference = args[1] - default: - return errors.Errorf("too many arguments. Usage TARBALL [REFERENCE]") - } - errFileName := parse.ValidateFileName(source) - errURL := parse.ValidURL(source) - if errURL == nil { - importOpts.SourceIsURL = true - } - if errFileName != nil && errURL != nil { - return multierror.Append(errFileName, errURL) - } - - importOpts.Source = source - importOpts.Reference = reference - - response, err := registry.ImageEngine().Import(context.Background(), importOpts) - if err != nil { - return err - } - fmt.Println(response.Id) - return nil -} diff --git a/cmd/podmanV2/images/inspect.go b/cmd/podmanV2/images/inspect.go deleted file mode 100644 index d7f6b0ee1..000000000 --- a/cmd/podmanV2/images/inspect.go +++ /dev/null @@ -1,109 +0,0 @@ -package images - -import ( - "context" - "encoding/json" - "fmt" - "os" - "strings" - "text/tabwriter" - "text/template" - - "github.com/containers/buildah/pkg/formats" - "github.com/containers/libpod/cmd/podmanV2/common" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - // Command: podman image _inspect_ - inspectCmd = &cobra.Command{ - Use: "inspect [flags] IMAGE", - Short: "Display the configuration of an image", - Long: `Displays the low-level information on an image identified by name or ID.`, - RunE: inspect, - Example: `podman image inspect alpine`, - } - inspectOpts *entities.InspectOptions -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: inspectCmd, - Parent: imageCmd, - }) - inspectOpts = common.AddInspectFlagSet(inspectCmd) -} - -func inspect(cmd *cobra.Command, args []string) error { - latestContainer := inspectOpts.Latest - - if len(args) == 0 && !latestContainer { - return errors.Errorf("container or image name must be specified: podman inspect [options [...]] name") - } - - if len(args) > 0 && latestContainer { - return errors.Errorf("you cannot provide additional arguments with --latest") - } - - results, err := registry.ImageEngine().Inspect(context.Background(), args, *inspectOpts) - if err != nil { - return err - } - - if len(results.Images) > 0 { - if inspectOpts.Format == "" { - buf, err := json.MarshalIndent(results.Images, "", " ") - if err != nil { - return err - } - fmt.Println(string(buf)) - - for id, e := range results.Errors { - fmt.Fprintf(os.Stderr, "%s: %s\n", id, e.Error()) - } - return nil - } - - row := inspectFormat(inspectOpts.Format) - format := "{{range . }}" + row + "{{end}}" - tmpl, err := template.New("inspect").Parse(format) - if err != nil { - return err - } - - w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0) - defer func() { _ = w.Flush() }() - err = tmpl.Execute(w, results) - if err != nil { - return err - } - } - - for id, e := range results.Errors { - fmt.Fprintf(os.Stderr, "%s: %s\n", id, e.Error()) - } - return nil -} - -func inspectFormat(row string) string { - r := strings.NewReplacer("{{.Id}}", formats.IDString, - ".Src", ".Source", - ".Dst", ".Destination", - ".ImageID", ".Image", - ) - row = r.Replace(row) - - if !strings.HasSuffix(row, "\n") { - row += "\n" - } - return row -} - -func Inspect(cmd *cobra.Command, args []string, options *entities.InspectOptions) error { - inspectOpts = options - return inspect(cmd, args) -} diff --git a/cmd/podmanV2/images/list.go b/cmd/podmanV2/images/list.go deleted file mode 100644 index 2d6cb3596..000000000 --- a/cmd/podmanV2/images/list.go +++ /dev/null @@ -1,243 +0,0 @@ -package images - -import ( - "errors" - "fmt" - "os" - "sort" - "strings" - "text/tabwriter" - "text/template" - "time" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/cmd/podmanV2/report" - "github.com/containers/libpod/pkg/domain/entities" - jsoniter "github.com/json-iterator/go" - "github.com/spf13/cobra" - "github.com/spf13/pflag" -) - -type listFlagType struct { - format string - history bool - noHeading bool - noTrunc bool - quiet bool - sort string - readOnly bool - digests bool -} - -var ( - // Command: podman image _list_ - listCmd = &cobra.Command{ - Use: "list [flag] [IMAGE]", - Aliases: []string{"ls"}, - Args: cobra.MaximumNArgs(1), - Short: "List images in local storage", - Long: "Lists images previously pulled to the system or created on the system.", - RunE: images, - Example: `podman image list --format json - podman image list --sort repository --format "table {{.ID}} {{.Repository}} {{.Tag}}" - podman image list --filter dangling=true`, - } - - // Options to pull data - listOptions = entities.ImageListOptions{} - - // Options for presenting data - listFlag = listFlagType{} - - sortFields = entities.NewStringSet( - "created", - "id", - "repository", - "size", - "tag") -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: listCmd, - Parent: imageCmd, - }) - imageListFlagSet(listCmd.Flags()) -} - -func imageListFlagSet(flags *pflag.FlagSet) { - flags.BoolVarP(&listOptions.All, "all", "a", false, "Show all images (default hides intermediate images)") - flags.StringSliceVarP(&listOptions.Filter, "filter", "f", []string{}, "Filter output based on conditions provided (default [])") - flags.StringVar(&listFlag.format, "format", "", "Change the output format to JSON or a Go template") - flags.BoolVar(&listFlag.digests, "digests", false, "Show digests") - flags.BoolVarP(&listFlag.noHeading, "noheading", "n", false, "Do not print column headings") - flags.BoolVar(&listFlag.noTrunc, "no-trunc", false, "Do not truncate output") - flags.BoolVar(&listFlag.noTrunc, "notruncate", false, "Do not truncate output") - flags.BoolVarP(&listFlag.quiet, "quiet", "q", false, "Display only image IDs") - flags.StringVar(&listFlag.sort, "sort", "created", "Sort by "+sortFields.String()) - flags.BoolVarP(&listFlag.history, "history", "", false, "Display the image name history") -} - -func images(cmd *cobra.Command, args []string) error { - if len(listOptions.Filter) > 0 && len(args) > 0 { - return errors.New("cannot specify an image and a filter(s)") - } - - if len(listOptions.Filter) < 1 && len(args) > 0 { - listOptions.Filter = append(listOptions.Filter, "reference="+args[0]) - } - - if cmd.Flag("sort").Changed && !sortFields.Contains(listFlag.sort) { - return fmt.Errorf("\"%s\" is not a valid field for sorting. Choose from: %s", - listFlag.sort, sortFields.String()) - } - - summaries, err := registry.ImageEngine().List(registry.GetContext(), listOptions) - if err != nil { - return err - } - - imageS := summaries - sort.Slice(imageS, sortFunc(listFlag.sort, imageS)) - - if cmd.Flag("format").Changed && listFlag.format == "json" { - return writeJSON(imageS) - } else { - return writeTemplate(imageS, err) - } -} - -func writeJSON(imageS []*entities.ImageSummary) error { - type image struct { - entities.ImageSummary - Created string - } - - imgs := make([]image, 0, len(imageS)) - for _, e := range imageS { - var h image - h.ImageSummary = *e - h.Created = time.Unix(e.Created, 0).Format(time.RFC3339) - h.RepoTags = nil - - imgs = append(imgs, h) - } - - json := jsoniter.ConfigCompatibleWithStandardLibrary - enc := json.NewEncoder(os.Stdout) - return enc.Encode(imgs) -} - -func writeTemplate(imageS []*entities.ImageSummary, err error) error { - type image struct { - entities.ImageSummary - Repository string `json:"repository,omitempty"` - Tag string `json:"tag,omitempty"` - } - - imgs := make([]image, 0, len(imageS)) - for _, e := range imageS { - for _, tag := range e.RepoTags { - var h image - h.ImageSummary = *e - h.Repository, h.Tag = tokenRepoTag(tag) - imgs = append(imgs, h) - } - if e.IsReadOnly() { - listFlag.readOnly = true - } - } - - hdr, row := imageListFormat(listFlag) - format := hdr + "{{range . }}" + row + "{{end}}" - - tmpl := template.Must(template.New("list").Funcs(report.PodmanTemplateFuncs()).Parse(format)) - w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0) - defer w.Flush() - return tmpl.Execute(w, imgs) -} - -func tokenRepoTag(tag string) (string, string) { - tokens := strings.SplitN(tag, ":", 2) - switch len(tokens) { - case 0: - return tag, "" - case 1: - return tokens[0], "" - case 2: - return tokens[0], tokens[1] - default: - return "<N/A>", "" - } -} - -func sortFunc(key string, data []*entities.ImageSummary) func(i, j int) bool { - switch key { - case "id": - return func(i, j int) bool { - return data[i].ID < data[j].ID - } - case "repository": - return func(i, j int) bool { - return data[i].RepoTags[0] < data[j].RepoTags[0] - } - case "size": - return func(i, j int) bool { - return data[i].Size < data[j].Size - } - case "tag": - return func(i, j int) bool { - return data[i].RepoTags[0] < data[j].RepoTags[0] - } - default: - // case "created": - return func(i, j int) bool { - return data[i].Created >= data[j].Created - } - } -} - -func imageListFormat(flags listFlagType) (string, string) { - if flags.quiet { - return "", "{{slice .ID 0 12}}\n" - } - - // Defaults - hdr := "REPOSITORY\tTAG" - row := "{{.Repository}}\t{{if .Tag}}{{.Tag}}{{else}}<none>{{end}}" - - if flags.digests { - hdr += "\tDIGEST" - row += "\t{{.Digest}}" - } - - hdr += "\tIMAGE ID" - if flags.noTrunc { - row += "\tsha256:{{.ID}}" - } else { - row += "\t{{slice .ID 0 12}}" - } - - hdr += "\tCREATED\tSIZE" - row += "\t{{humanDuration .Created}}\t{{humanSize .Size}}" - - if flags.history { - hdr += "\tHISTORY" - row += "\t{{if .History}}{{join .History \", \"}}{{else}}<none>{{end}}" - } - - if flags.readOnly { - hdr += "\tReadOnly" - row += "\t{{.ReadOnly}}" - } - - if flags.noHeading { - hdr = "" - } else { - hdr += "\n" - } - - row += "\n" - return hdr, row -} diff --git a/cmd/podmanV2/images/load.go b/cmd/podmanV2/images/load.go deleted file mode 100644 index f60dc4908..000000000 --- a/cmd/podmanV2/images/load.go +++ /dev/null @@ -1,61 +0,0 @@ -package images - -import ( - "context" - "fmt" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/libpod/image" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - loadDescription = "Loads an image from a locally stored archive (tar file) into container storage." - loadCommand = &cobra.Command{ - Use: "load [flags] [NAME[:TAG]]", - Short: "Load an image from container archive", - Long: loadDescription, - RunE: load, - Args: cobra.MaximumNArgs(1), - PersistentPreRunE: preRunE, - } -) - -var ( - loadOpts entities.ImageLoadOptions -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: loadCommand, - }) - - loadCommand.SetHelpTemplate(registry.HelpTemplate()) - loadCommand.SetUsageTemplate(registry.UsageTemplate()) - flags := loadCommand.Flags() - flags.StringVarP(&loadOpts.Input, "input", "i", "", "Read from specified archive file (default: stdin)") - flags.BoolVarP(&loadOpts.Quiet, "quiet", "q", false, "Suppress the output") - flags.StringVar(&loadOpts.SignaturePolicy, "signature-policy", "", "Pathname of signature policy file") - if registry.IsRemote() { - _ = flags.MarkHidden("signature-policy") - } - -} - -func load(cmd *cobra.Command, args []string) error { - if len(args) > 0 { - repo, err := image.NormalizedTag(args[0]) - if err != nil { - return err - } - loadOpts.Name = repo.Name() - } - response, err := registry.ImageEngine().Load(context.Background(), loadOpts) - if err != nil { - return err - } - fmt.Println("Loaded image: " + response.Name) - return nil -} diff --git a/cmd/podmanV2/images/prune.go b/cmd/podmanV2/images/prune.go deleted file mode 100644 index 6577c458e..000000000 --- a/cmd/podmanV2/images/prune.go +++ /dev/null @@ -1,86 +0,0 @@ -package images - -import ( - "bufio" - "fmt" - "os" - "strings" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - pruneDescription = `Removes all unnamed images from local storage. - - If an image is not being used by a container, it will be removed from the system.` - pruneCmd = &cobra.Command{ - Use: "prune", - Args: cobra.NoArgs, - Short: "Remove unused images", - Long: pruneDescription, - RunE: prune, - Example: `podman image prune`, - } - - pruneOpts = entities.ImagePruneOptions{} - force bool - filter = []string{} -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: pruneCmd, - Parent: imageCmd, - }) - - flags := pruneCmd.Flags() - flags.BoolVarP(&pruneOpts.All, "all", "a", false, "Remove all unused images, not just dangling ones") - flags.BoolVarP(&force, "force", "f", false, "Do not prompt for confirmation") - flags.StringArrayVar(&filter, "filter", []string{}, "Provide filter values (e.g. 'label=<key>=<value>')") - -} - -func prune(cmd *cobra.Command, args []string) error { - if !force { - reader := bufio.NewReader(os.Stdin) - fmt.Printf(` -WARNING! This will remove all dangling images. -Are you sure you want to continue? [y/N] `) - answer, err := reader.ReadString('\n') - if err != nil { - return errors.Wrapf(err, "error reading input") - } - if strings.ToLower(answer)[0] != 'y' { - return nil - } - } - - // TODO Remove once filter refactor is finished and url.Values rules :) - for _, f := range filter { - t := strings.SplitN(f, "=", 2) - pruneOpts.Filters.Add(t[0], t[1]) - } - - results, err := registry.ImageEngine().Prune(registry.GetContext(), pruneOpts) - if err != nil { - return err - } - - for _, i := range results.Report.Id { - fmt.Println(i) - } - - for _, e := range results.Report.Err { - fmt.Fprint(os.Stderr, e.Error()+"\n") - } - - if results.Size > 0 { - fmt.Fprintf(os.Stdout, "Size: %d\n", results.Size) - } - - return nil -} diff --git a/cmd/podmanV2/images/pull.go b/cmd/podmanV2/images/pull.go deleted file mode 100644 index c7e325409..000000000 --- a/cmd/podmanV2/images/pull.go +++ /dev/null @@ -1,140 +0,0 @@ -package images - -import ( - "fmt" - - buildahcli "github.com/containers/buildah/pkg/cli" - "github.com/containers/image/v5/types" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/opentracing/opentracing-go" - "github.com/pkg/errors" - "github.com/spf13/cobra" - "github.com/spf13/pflag" -) - -// pullOptionsWrapper wraps entities.ImagePullOptions and prevents leaking -// CLI-only fields into the API types. -type pullOptionsWrapper struct { - entities.ImagePullOptions - TLSVerifyCLI bool // CLI only -} - -var ( - pullOptions = pullOptionsWrapper{} - pullDescription = `Pulls an image from a registry and stores it locally. - - An image can be pulled by tag or digest. If a tag is not specified, the image with the 'latest' tag is pulled.` - - // Command: podman pull - pullCmd = &cobra.Command{ - Use: "pull [flags] IMAGE", - Short: "Pull an image from a registry", - Long: pullDescription, - PreRunE: preRunE, - RunE: imagePull, - Example: `podman pull imageName - podman pull fedora:latest`, - } - - // Command: podman image pull - // It's basically a clone of `pullCmd` with the exception of being a - // child of the images command. - imagesPullCmd = &cobra.Command{ - Use: pullCmd.Use, - Short: pullCmd.Short, - Long: pullCmd.Long, - PreRunE: pullCmd.PreRunE, - RunE: pullCmd.RunE, - Example: `podman image pull imageName - podman image pull fedora:latest`, - } -) - -func init() { - // pull - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: pullCmd, - }) - - pullCmd.SetHelpTemplate(registry.HelpTemplate()) - pullCmd.SetUsageTemplate(registry.UsageTemplate()) - - flags := pullCmd.Flags() - pullFlags(flags) - - // images pull - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: imagesPullCmd, - Parent: imageCmd, - }) - - imagesPullCmd.SetHelpTemplate(registry.HelpTemplate()) - imagesPullCmd.SetUsageTemplate(registry.UsageTemplate()) - imagesPullFlags := imagesPullCmd.Flags() - pullFlags(imagesPullFlags) -} - -// pullFlags set the flags for the pull command. -func pullFlags(flags *pflag.FlagSet) { - flags.BoolVar(&pullOptions.AllTags, "all-tags", false, "All tagged images in the repository will be pulled") - flags.StringVar(&pullOptions.Authfile, "authfile", buildahcli.GetDefaultAuthFile(), "Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override") - flags.StringVar(&pullOptions.CertDir, "cert-dir", "", "`Pathname` of a directory containing TLS certificates and keys") - flags.StringVar(&pullOptions.Credentials, "creds", "", "`Credentials` (USERNAME:PASSWORD) to use for authenticating to a registry") - flags.StringVar(&pullOptions.OverrideArch, "override-arch", "", "Use `ARCH` instead of the architecture of the machine for choosing images") - flags.StringVar(&pullOptions.OverrideOS, "override-os", "", "Use `OS` instead of the running OS for choosing images") - flags.BoolVarP(&pullOptions.Quiet, "quiet", "q", false, "Suppress output information when pulling images") - flags.StringVar(&pullOptions.SignaturePolicy, "signature-policy", "", "`Pathname` of signature policy file (not usually used)") - flags.BoolVar(&pullOptions.TLSVerifyCLI, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries") - - if registry.IsRemote() { - _ = flags.MarkHidden("authfile") - _ = flags.MarkHidden("cert-dir") - _ = flags.MarkHidden("signature-policy") - _ = flags.MarkHidden("tls-verify") - } -} - -// imagePull is implement the command for pulling images. -func imagePull(cmd *cobra.Command, args []string) error { - // Sanity check input. - if len(args) == 0 { - return errors.Errorf("an image name must be specified") - } - if len(args) > 1 { - return errors.Errorf("too many arguments. Requires exactly 1") - } - - // Start tracing if requested. - if cmd.Flags().Changed("trace") { - span, _ := opentracing.StartSpanFromContext(registry.GetContext(), "pullCmd") - defer span.Finish() - } - - pullOptsAPI := pullOptions.ImagePullOptions - // TLS verification in c/image is controlled via a `types.OptionalBool` - // which allows for distinguishing among set-true, set-false, unspecified - // which is important to implement a sane way of dealing with defaults of - // boolean CLI flags. - if cmd.Flags().Changed("tls-verify") { - pullOptsAPI.TLSVerify = types.NewOptionalBool(pullOptions.TLSVerifyCLI) - } - - // Let's do all the remaining Yoga in the API to prevent us from - // scattering logic across (too) many parts of the code. - pullReport, err := registry.ImageEngine().Pull(registry.GetContext(), args[0], pullOptsAPI) - if err != nil { - return err - } - - if len(pullReport.Images) > 1 { - fmt.Println("Pulled Images:") - } - for _, img := range pullReport.Images { - fmt.Println(img) - } - - return nil -} diff --git a/cmd/podmanV2/images/push.go b/cmd/podmanV2/images/push.go deleted file mode 100644 index 82cc0c486..000000000 --- a/cmd/podmanV2/images/push.go +++ /dev/null @@ -1,127 +0,0 @@ -package images - -import ( - buildahcli "github.com/containers/buildah/pkg/cli" - "github.com/containers/image/v5/types" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/pkg/errors" - "github.com/spf13/cobra" - "github.com/spf13/pflag" -) - -// pushOptionsWrapper wraps entities.ImagepushOptions and prevents leaking -// CLI-only fields into the API types. -type pushOptionsWrapper struct { - entities.ImagePushOptions - TLSVerifyCLI bool // CLI only -} - -var ( - pushOptions = pushOptionsWrapper{} - pushDescription = `Pushes a source image to a specified destination. - - The Image "DESTINATION" uses a "transport":"details" format. See podman-push(1) section "DESTINATION" for the expected format.` - - // Command: podman push - pushCmd = &cobra.Command{ - Use: "push [flags] SOURCE DESTINATION", - Short: "Push an image to a specified destination", - Long: pushDescription, - PreRunE: preRunE, - RunE: imagePush, - Example: `podman push imageID docker://registry.example.com/repository:tag - podman push imageID oci-archive:/path/to/layout:image:tag`, - } - - // Command: podman image push - // It's basically a clone of `pushCmd` with the exception of being a - // child of the images command. - imagePushCmd = &cobra.Command{ - Use: pushCmd.Use, - Short: pushCmd.Short, - Long: pushCmd.Long, - PreRunE: pushCmd.PreRunE, - RunE: pushCmd.RunE, - Example: `podman image push imageID docker://registry.example.com/repository:tag - podman image push imageID oci-archive:/path/to/layout:image:tag`, - } -) - -func init() { - // push - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: pushCmd, - }) - - pushCmd.SetHelpTemplate(registry.HelpTemplate()) - pushCmd.SetUsageTemplate(registry.UsageTemplate()) - - flags := pushCmd.Flags() - pushFlags(flags) - - // images push - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: imagePushCmd, - Parent: imageCmd, - }) - - imagePushCmd.SetHelpTemplate(registry.HelpTemplate()) - imagePushCmd.SetUsageTemplate(registry.UsageTemplate()) - pushFlags(imagePushCmd.Flags()) -} - -// pushFlags set the flags for the push command. -func pushFlags(flags *pflag.FlagSet) { - flags.StringVar(&pushOptions.Authfile, "authfile", buildahcli.GetDefaultAuthFile(), "Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override") - flags.StringVar(&pushOptions.CertDir, "cert-dir", "", "Path to a directory containing TLS certificates and keys") - flags.BoolVar(&pushOptions.Compress, "compress", false, "Compress tarball image layers when pushing to a directory using the 'dir' transport. (default is same compression type as source)") - flags.StringVar(&pushOptions.Credentials, "creds", "", "`Credentials` (USERNAME:PASSWORD) to use for authenticating to a registry") - flags.StringVar(&pushOptions.DigestFile, "digestfile", "", "Write the digest of the pushed image to the specified file") - flags.StringVarP(&pushOptions.Format, "format", "f", "", "Manifest type (oci, v2s1, or v2s2) to use when pushing an image using the 'dir' transport (default is manifest type of source)") - flags.BoolVarP(&pushOptions.Quiet, "quiet", "q", false, "Suppress output information when pushing images") - flags.BoolVar(&pushOptions.RemoveSignatures, "remove-signatures", false, "Discard any pre-existing signatures in the image") - flags.StringVar(&pushOptions.SignaturePolicy, "signature-policy", "", "Path to a signature-policy file") - flags.StringVar(&pushOptions.SignBy, "sign-by", "", "Add a signature at the destination using the specified key") - flags.BoolVar(&pushOptions.TLSVerifyCLI, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries") - - if registry.IsRemote() { - _ = flags.MarkHidden("authfile") - _ = flags.MarkHidden("cert-dir") - _ = flags.MarkHidden("compress") - _ = flags.MarkHidden("quiet") - _ = flags.MarkHidden("signature-policy") - _ = flags.MarkHidden("tls-verify") - } -} - -// imagePush is implement the command for pushing images. -func imagePush(cmd *cobra.Command, args []string) error { - var source, destination string - switch len(args) { - case 1: - source = args[0] - case 2: - source = args[0] - destination = args[1] - case 0: - fallthrough - default: - return errors.New("push requires at least one image name, or optionally a second to specify a different destination") - } - - pushOptsAPI := pushOptions.ImagePushOptions - // TLS verification in c/image is controlled via a `types.OptionalBool` - // which allows for distinguishing among set-true, set-false, unspecified - // which is important to implement a sane way of dealing with defaults of - // boolean CLI flags. - if cmd.Flags().Changed("tls-verify") { - pushOptsAPI.TLSVerify = types.NewOptionalBool(pushOptions.TLSVerifyCLI) - } - - // Let's do all the remaining Yoga in the API to prevent us from scattering - // logic across (too) many parts of the code. - return registry.ImageEngine().Push(registry.GetContext(), source, destination, pushOptsAPI) -} diff --git a/cmd/podmanV2/images/rm.go b/cmd/podmanV2/images/rm.go deleted file mode 100644 index bb5880de3..000000000 --- a/cmd/podmanV2/images/rm.go +++ /dev/null @@ -1,70 +0,0 @@ -package images - -import ( - "fmt" - "os" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - rmDescription = "Removes one or more previously pulled or locally created images." - rmCmd = &cobra.Command{ - Use: "rm [flags] IMAGE [IMAGE...]", - Short: "Removes one or more images from local storage", - Long: rmDescription, - PreRunE: preRunE, - RunE: rm, - Example: `podman image rm imageID - podman image rm --force alpine - podman image rm c4dfb1609ee2 93fd78260bd1 c0ed59d05ff7`, - } - - imageOpts = entities.ImageDeleteOptions{} -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: rmCmd, - Parent: imageCmd, - }) - - flags := rmCmd.Flags() - flags.BoolVarP(&imageOpts.All, "all", "a", false, "Remove all images") - flags.BoolVarP(&imageOpts.Force, "force", "f", false, "Force Removal of the image") -} - -func rm(cmd *cobra.Command, args []string) error { - - if len(args) < 1 && !imageOpts.All { - return errors.Errorf("image name or ID must be specified") - } - if len(args) > 0 && imageOpts.All { - return errors.Errorf("when using the --all switch, you may not pass any images names or IDs") - } - - report, err := registry.ImageEngine().Delete(registry.GetContext(), args, imageOpts) - if err != nil { - switch { - case report != nil && report.ImageNotFound != nil: - fmt.Fprintln(os.Stderr, err.Error()) - registry.SetExitCode(2) - case report != nil && report.ImageInUse != nil: - fmt.Fprintln(os.Stderr, err.Error()) - default: - return err - } - } - - for _, u := range report.Untagged { - fmt.Println("Untagged: " + u) - } - for _, d := range report.Deleted { - fmt.Println("Deleted: " + d) - } - return nil -} diff --git a/cmd/podmanV2/images/rmi.go b/cmd/podmanV2/images/rmi.go deleted file mode 100644 index 7f9297bc9..000000000 --- a/cmd/podmanV2/images/rmi.go +++ /dev/null @@ -1,30 +0,0 @@ -package images - -import ( - "strings" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - rmiCmd = &cobra.Command{ - Use: strings.Replace(rmCmd.Use, "rm ", "rmi ", 1), - Args: rmCmd.Args, - Short: rmCmd.Short, - Long: rmCmd.Long, - PreRunE: rmCmd.PreRunE, - RunE: rmCmd.RunE, - Example: strings.Replace(rmCmd.Example, "podman image rm", "podman rmi", -1), - } -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: rmiCmd, - }) - rmiCmd.SetHelpTemplate(registry.HelpTemplate()) - rmiCmd.SetUsageTemplate(registry.UsageTemplate()) -} diff --git a/cmd/podmanV2/images/save.go b/cmd/podmanV2/images/save.go deleted file mode 100644 index ae39b7bce..000000000 --- a/cmd/podmanV2/images/save.go +++ /dev/null @@ -1,87 +0,0 @@ -package images - -import ( - "context" - "os" - "strings" - - "github.com/containers/libpod/libpod/define" - - "github.com/containers/libpod/cmd/podmanV2/parse" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/containers/libpod/pkg/util" - "github.com/pkg/errors" - "github.com/spf13/cobra" - "golang.org/x/crypto/ssh/terminal" -) - -var validFormats = []string{define.OCIManifestDir, define.OCIArchive, define.V2s2ManifestDir, define.V2s2Archive} - -var ( - saveDescription = `Save an image to docker-archive or oci-archive on the local machine. Default is docker-archive.` - - saveCommand = &cobra.Command{ - Use: "save [flags] IMAGE", - Short: "Save image to an archive", - Long: saveDescription, - PersistentPreRunE: preRunE, - RunE: save, - Args: func(cmd *cobra.Command, args []string) error { - if len(args) == 0 { - return errors.Errorf("need at least 1 argument") - } - format, err := cmd.Flags().GetString("format") - if err != nil { - return err - } - if !util.StringInSlice(format, validFormats) { - return errors.Errorf("format value must be one of %s", strings.Join(validFormats, " ")) - } - return nil - }, - Example: `podman save --quiet -o myimage.tar imageID - podman save --format docker-dir -o ubuntu-dir ubuntu - podman save > alpine-all.tar alpine:latest`, - } -) - -var ( - saveOpts entities.ImageSaveOptions -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: saveCommand, - }) - flags := saveCommand.Flags() - flags.BoolVar(&saveOpts.Compress, "compress", false, "Compress tarball image layers when saving to a directory using the 'dir' transport. (default is same compression type as source)") - flags.StringVar(&saveOpts.Format, "format", define.V2s2Archive, "Save image to oci-archive, oci-dir (directory with oci manifest type), docker-archive, docker-dir (directory with v2s2 manifest type)") - flags.StringVarP(&saveOpts.Output, "output", "o", "", "Write to a specified file (default: stdout, which must be redirected)") - flags.BoolVarP(&saveOpts.Quiet, "quiet", "q", false, "Suppress the output") - -} - -func save(cmd *cobra.Command, args []string) error { - var ( - tags []string - ) - if cmd.Flag("compress").Changed && (saveOpts.Format != define.OCIManifestDir && saveOpts.Format != define.V2s2ManifestDir && saveOpts.Format == "") { - return errors.Errorf("--compress can only be set when --format is either 'oci-dir' or 'docker-dir'") - } - if len(saveOpts.Output) == 0 { - fi := os.Stdout - if terminal.IsTerminal(int(fi.Fd())) { - return errors.Errorf("refusing to save to terminal. Use -o flag or redirect") - } - saveOpts.Output = "/dev/stdout" - } - if err := parse.ValidateFileName(saveOpts.Output); err != nil { - return err - } - if len(args) > 1 { - tags = args[1:] - } - return registry.ImageEngine().Save(context.Background(), args[0], tags, saveOpts) -} diff --git a/cmd/podmanV2/images/tag.go b/cmd/podmanV2/images/tag.go deleted file mode 100644 index f66fe7857..000000000 --- a/cmd/podmanV2/images/tag.go +++ /dev/null @@ -1,34 +0,0 @@ -package images - -import ( - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - tagDescription = "Adds one or more additional names to locally-stored image." - tagCommand = &cobra.Command{ - Use: "tag [flags] IMAGE TARGET_NAME [TARGET_NAME...]", - Short: "Add an additional name to a local image", - Long: tagDescription, - RunE: tag, - Args: cobra.MinimumNArgs(2), - Example: `podman tag 0e3bbc2 fedora:latest - podman tag imageID:latest myNewImage:newTag - podman tag httpd myregistryhost:5000/fedora/httpd:v2`, - } -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: tagCommand, - }) - tagCommand.SetHelpTemplate(registry.HelpTemplate()) - tagCommand.SetUsageTemplate(registry.UsageTemplate()) -} - -func tag(cmd *cobra.Command, args []string) error { - return registry.ImageEngine().Tag(registry.GetContext(), args[0], args[1:], entities.ImageTagOptions{}) -} diff --git a/cmd/podmanV2/images/untag.go b/cmd/podmanV2/images/untag.go deleted file mode 100644 index c84827bb3..000000000 --- a/cmd/podmanV2/images/untag.go +++ /dev/null @@ -1,33 +0,0 @@ -package images - -import ( - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - untagCommand = &cobra.Command{ - Use: "untag [flags] IMAGE [NAME...]", - Short: "Remove a name from a local image", - Long: "Removes one or more names from a locally-stored image.", - RunE: untag, - Args: cobra.MinimumNArgs(1), - Example: `podman untag 0e3bbc2 - podman untag imageID:latest otherImageName:latest - podman untag httpd myregistryhost:5000/fedora/httpd:v2`, - } -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: untagCommand, - }) - untagCommand.SetHelpTemplate(registry.HelpTemplate()) - untagCommand.SetUsageTemplate(registry.UsageTemplate()) -} - -func untag(cmd *cobra.Command, args []string) error { - return registry.ImageEngine().Untag(registry.GetContext(), args[0], args[1:], entities.ImageUntagOptions{}) -} diff --git a/cmd/podmanV2/inspect.go b/cmd/podmanV2/inspect.go deleted file mode 100644 index 4975cf632..000000000 --- a/cmd/podmanV2/inspect.go +++ /dev/null @@ -1,62 +0,0 @@ -package main - -import ( - "context" - "fmt" - - "github.com/containers/libpod/cmd/podmanV2/common" - "github.com/containers/libpod/cmd/podmanV2/containers" - "github.com/containers/libpod/cmd/podmanV2/images" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -// Inspect is one of the out layer commands in that it operates on images/containers/... - -var ( - inspectOpts *entities.InspectOptions - - // Command: podman _inspect_ Object_ID - inspectCmd = &cobra.Command{ - Use: "inspect [flags] {CONTAINER_ID | IMAGE_ID}", - Args: cobra.ExactArgs(1), - Short: "Display the configuration of object denoted by ID", - Long: "Displays the low-level information on an object identified by name or ID", - TraverseChildren: true, - RunE: inspect, - } -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: inspectCmd, - }) - inspectOpts = common.AddInspectFlagSet(inspectCmd) -} - -func inspect(cmd *cobra.Command, args []string) error { - ie, err := registry.NewImageEngine(cmd, args) - if err != nil { - return err - } - - if found, err := ie.Exists(context.Background(), args[0]); err != nil { - return err - } else if found.Value { - return images.Inspect(cmd, args, inspectOpts) - } - - ce, err := registry.NewContainerEngine(cmd, args) - if err != nil { - return err - } - - if found, err := ce.ContainerExists(context.Background(), args[0]); err != nil { - return err - } else if found.Value { - return containers.Inspect(cmd, args, inspectOpts) - } - return fmt.Errorf("%s not found on system", args[0]) -} diff --git a/cmd/podmanV2/main.go b/cmd/podmanV2/main.go deleted file mode 100644 index fe3cd9f16..000000000 --- a/cmd/podmanV2/main.go +++ /dev/null @@ -1,87 +0,0 @@ -package main - -import ( - "os" - "reflect" - "runtime" - "strings" - - _ "github.com/containers/libpod/cmd/podmanV2/containers" - _ "github.com/containers/libpod/cmd/podmanV2/healthcheck" - _ "github.com/containers/libpod/cmd/podmanV2/images" - _ "github.com/containers/libpod/cmd/podmanV2/networks" - _ "github.com/containers/libpod/cmd/podmanV2/pods" - "github.com/containers/libpod/cmd/podmanV2/registry" - _ "github.com/containers/libpod/cmd/podmanV2/system" - _ "github.com/containers/libpod/cmd/podmanV2/volumes" - "github.com/containers/libpod/libpod" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/containers/storage/pkg/reexec" - "github.com/sirupsen/logrus" -) - -func init() { - if err := libpod.SetXdgDirs(); err != nil { - logrus.Errorf(err.Error()) - os.Exit(1) - } - - switch runtime.GOOS { - case "darwin": - fallthrough - case "windows": - registry.EngineOptions.EngineMode = entities.TunnelMode - case "linux": - registry.EngineOptions.EngineMode = entities.ABIMode - default: - logrus.Errorf("%s is not a supported OS", runtime.GOOS) - os.Exit(1) - } - - // TODO: Is there a Cobra way to "peek" at os.Args? - for _, v := range os.Args { - if strings.HasPrefix(v, "--remote") { - registry.EngineOptions.EngineMode = entities.TunnelMode - } - } -} - -func main() { - if reexec.Init() { - // We were invoked with a different argv[0] indicating that we - // had a specific job to do as a subprocess, and it's done. - return - } - for _, c := range registry.Commands { - if Contains(registry.EngineOptions.EngineMode, c.Mode) { - parent := rootCmd - if c.Parent != nil { - parent = c.Parent - } - parent.AddCommand(c.Command) - } - } - - Execute() - os.Exit(0) -} - -func Contains(item interface{}, slice interface{}) bool { - s := reflect.ValueOf(slice) - - switch s.Kind() { - case reflect.Array: - fallthrough - case reflect.Slice: - break - default: - return false - } - - for i := 0; i < s.Len(); i++ { - if s.Index(i).Interface() == item { - return true - } - } - return false -} diff --git a/cmd/podmanV2/networks/network.go b/cmd/podmanV2/networks/network.go deleted file mode 100644 index fc92d2321..000000000 --- a/cmd/podmanV2/networks/network.go +++ /dev/null @@ -1,33 +0,0 @@ -package images - -import ( - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - // Command: podman _network_ - cmd = &cobra.Command{ - Use: "network", - Short: "Manage networks", - Long: "Manage networks", - TraverseChildren: true, - PersistentPreRunE: preRunE, - RunE: registry.SubCommandExists, - } -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode}, - Command: cmd, - }) - cmd.SetHelpTemplate(registry.HelpTemplate()) - cmd.SetUsageTemplate(registry.UsageTemplate()) -} - -func preRunE(cmd *cobra.Command, args []string) error { - _, err := registry.NewContainerEngine(cmd, args) - return err -} diff --git a/cmd/podmanV2/parse/common.go b/cmd/podmanV2/parse/common.go deleted file mode 100644 index a5e9b4fc2..000000000 --- a/cmd/podmanV2/parse/common.go +++ /dev/null @@ -1,50 +0,0 @@ -package parse - -import ( - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -// CheckAllLatestAndCIDFile checks that --all and --latest are used correctly. -// If cidfile is set, also check for the --cidfile flag. -func CheckAllLatestAndCIDFile(c *cobra.Command, args []string, ignoreArgLen bool, cidfile bool) error { - argLen := len(args) - if c.Flags().Lookup("all") == nil || c.Flags().Lookup("latest") == nil { - if !cidfile { - return errors.New("unable to lookup values for 'latest' or 'all'") - } else if c.Flags().Lookup("cidfile") == nil { - return errors.New("unable to lookup values for 'latest', 'all' or 'cidfile'") - } - } - - specifiedAll, _ := c.Flags().GetBool("all") - specifiedLatest, _ := c.Flags().GetBool("latest") - specifiedCIDFile := false - if cid, _ := c.Flags().GetStringArray("cidfile"); len(cid) > 0 { - specifiedCIDFile = true - } - - if specifiedCIDFile && (specifiedAll || specifiedLatest) { - return errors.Errorf("--all, --latest and --cidfile cannot be used together") - } else if specifiedAll && specifiedLatest { - return errors.Errorf("--all and --latest cannot be used together") - } - - if ignoreArgLen { - return nil - } - if (argLen > 0) && (specifiedAll || specifiedLatest) { - return errors.Errorf("no arguments are needed with --all or --latest") - } else if cidfile && (argLen > 0) && (specifiedAll || specifiedLatest || specifiedCIDFile) { - return errors.Errorf("no arguments are needed with --all, --latest or --cidfile") - } - - if specifiedCIDFile { - return nil - } - - if argLen < 1 && !specifiedAll && !specifiedLatest && !specifiedCIDFile { - return errors.Errorf("you must provide at least one name or id") - } - return nil -} diff --git a/cmd/podmanV2/parse/net.go b/cmd/podmanV2/parse/net.go deleted file mode 100644 index 03cda268c..000000000 --- a/cmd/podmanV2/parse/net.go +++ /dev/null @@ -1,188 +0,0 @@ -//nolint -// most of these validate and parse functions have been taken from projectatomic/docker -// and modified for cri-o -package parse - -import ( - "bufio" - "fmt" - "net" - "net/url" - "os" - "regexp" - "strings" - - "github.com/pkg/errors" -) - -const ( - Protocol_TCP Protocol = 0 - Protocol_UDP Protocol = 1 -) - -type Protocol int32 - -// PortMapping specifies the port mapping configurations of a sandbox. -type PortMapping struct { - // Protocol of the port mapping. - Protocol Protocol `protobuf:"varint,1,opt,name=protocol,proto3,enum=runtime.Protocol" json:"protocol,omitempty"` - // Port number within the container. Default: 0 (not specified). - ContainerPort int32 `protobuf:"varint,2,opt,name=container_port,json=containerPort,proto3" json:"container_port,omitempty"` - // Port number on the host. Default: 0 (not specified). - HostPort int32 `protobuf:"varint,3,opt,name=host_port,json=hostPort,proto3" json:"host_port,omitempty"` - // Host IP. - HostIp string `protobuf:"bytes,4,opt,name=host_ip,json=hostIp,proto3" json:"host_ip,omitempty"` -} - -// Note: for flags that are in the form <number><unit>, use the RAMInBytes function -// from the units package in docker/go-units/size.go - -var ( - whiteSpaces = " \t" - alphaRegexp = regexp.MustCompile(`[a-zA-Z]`) - domainRegexp = regexp.MustCompile(`^(:?(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9]))(:?\.(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])))*)\.?\s*$`) -) - -// validateExtraHost validates that the specified string is a valid extrahost and returns it. -// ExtraHost is in the form of name:ip where the ip has to be a valid ip (ipv4 or ipv6). -// for add-host flag -func ValidateExtraHost(val string) (string, error) { //nolint - // allow for IPv6 addresses in extra hosts by only splitting on first ":" - arr := strings.SplitN(val, ":", 2) - if len(arr) != 2 || len(arr[0]) == 0 { - return "", fmt.Errorf("bad format for add-host: %q", val) - } - if _, err := validateIPAddress(arr[1]); err != nil { - return "", fmt.Errorf("invalid IP address in add-host: %q", arr[1]) - } - return val, nil -} - -// validateIPAddress validates an Ip address. -// for dns, ip, and ip6 flags also -func validateIPAddress(val string) (string, error) { - var ip = net.ParseIP(strings.TrimSpace(val)) - if ip != nil { - return ip.String(), nil - } - return "", fmt.Errorf("%s is not an ip address", val) -} - -func ValidateDomain(val string) (string, error) { - if alphaRegexp.FindString(val) == "" { - return "", fmt.Errorf("%s is not a valid domain", val) - } - ns := domainRegexp.FindSubmatch([]byte(val)) - if len(ns) > 0 && len(ns[1]) < 255 { - return string(ns[1]), nil - } - return "", fmt.Errorf("%s is not a valid domain", val) -} - -// GetAllLabels retrieves all labels given a potential label file and a number -// of labels provided from the command line. -func GetAllLabels(labelFile, inputLabels []string) (map[string]string, error) { - labels := make(map[string]string) - for _, file := range labelFile { - // Use of parseEnvFile still seems safe, as it's missing the - // extra parsing logic of parseEnv. - // There's an argument that we SHOULD be doing that parsing for - // all environment variables, even those sourced from files, but - // that would require a substantial rework. - if err := parseEnvFile(labels, file); err != nil { - // FIXME: parseEnvFile is using parseEnv, so we need to add extra - // logic for labels. - return nil, err - } - } - for _, label := range inputLabels { - split := strings.SplitN(label, "=", 2) - if split[0] == "" { - return nil, errors.Errorf("invalid label format: %q", label) - } - value := "" - if len(split) > 1 { - value = split[1] - } - labels[split[0]] = value - } - return labels, nil -} - -func parseEnv(env map[string]string, line string) error { - data := strings.SplitN(line, "=", 2) - - // catch invalid variables such as "=" or "=A" - if data[0] == "" { - return errors.Errorf("invalid environment variable: %q", line) - } - - // trim the front of a variable, but nothing else - name := strings.TrimLeft(data[0], whiteSpaces) - if strings.ContainsAny(name, whiteSpaces) { - return errors.Errorf("name %q has white spaces, poorly formatted name", name) - } - - if len(data) > 1 { - env[name] = data[1] - } else { - if strings.HasSuffix(name, "*") { - name = strings.TrimSuffix(name, "*") - for _, e := range os.Environ() { - part := strings.SplitN(e, "=", 2) - if len(part) < 2 { - continue - } - if strings.HasPrefix(part[0], name) { - env[part[0]] = part[1] - } - } - } else { - // if only a pass-through variable is given, clean it up. - if val, ok := os.LookupEnv(name); ok { - env[name] = val - } - } - } - return nil -} - -// parseEnvFile reads a file with environment variables enumerated by lines -func parseEnvFile(env map[string]string, filename string) error { - fh, err := os.Open(filename) - if err != nil { - return err - } - defer fh.Close() - - scanner := bufio.NewScanner(fh) - for scanner.Scan() { - // trim the line from all leading whitespace first - line := strings.TrimLeft(scanner.Text(), whiteSpaces) - // line is not empty, and not starting with '#' - if len(line) > 0 && !strings.HasPrefix(line, "#") { - if err := parseEnv(env, line); err != nil { - return err - } - } - } - return scanner.Err() -} - -// ValidateFileName returns an error if filename contains ":" -// as it is currently not supported -func ValidateFileName(filename string) error { - if strings.Contains(filename, ":") { - return errors.Errorf("invalid filename (should not contain ':') %q", filename) - } - return nil -} - -// ValidURL checks a string urlStr is a url or not -func ValidURL(urlStr string) error { - _, err := url.ParseRequestURI(urlStr) - if err != nil { - return errors.Wrapf(err, "invalid url path: %q", urlStr) - } - return nil -} diff --git a/cmd/podmanV2/parse/net_test.go b/cmd/podmanV2/parse/net_test.go deleted file mode 100644 index a6ddc2be9..000000000 --- a/cmd/podmanV2/parse/net_test.go +++ /dev/null @@ -1,152 +0,0 @@ -//nolint -// most of these validate and parse functions have been taken from projectatomic/docker -// and modified for cri-o -package parse - -import ( - "io/ioutil" - "os" - "testing" - - "github.com/stretchr/testify/assert" -) - -var ( - Var1 = []string{"ONE=1", "TWO=2"} -) - -func createTmpFile(content []byte) (string, error) { - tmpfile, err := ioutil.TempFile(os.TempDir(), "unittest") - if err != nil { - return "", err - } - - if _, err := tmpfile.Write(content); err != nil { - return "", err - - } - if err := tmpfile.Close(); err != nil { - return "", err - } - return tmpfile.Name(), nil -} - -func TestValidateExtraHost(t *testing.T) { - type args struct { - val string - } - tests := []struct { - name string - args args - want string - wantErr bool - }{ - //2001:0db8:85a3:0000:0000:8a2e:0370:7334 - {name: "good-ipv4", args: args{val: "foobar:192.168.1.1"}, want: "foobar:192.168.1.1", wantErr: false}, - {name: "bad-ipv4", args: args{val: "foobar:999.999.999.99"}, want: "", wantErr: true}, - {name: "bad-ipv4", args: args{val: "foobar:999.999.999"}, want: "", wantErr: true}, - {name: "noname-ipv4", args: args{val: "192.168.1.1"}, want: "", wantErr: true}, - {name: "noname-ipv4", args: args{val: ":192.168.1.1"}, want: "", wantErr: true}, - {name: "noip", args: args{val: "foobar:"}, want: "", wantErr: true}, - {name: "noip", args: args{val: "foobar"}, want: "", wantErr: true}, - {name: "good-ipv6", args: args{val: "foobar:2001:0db8:85a3:0000:0000:8a2e:0370:7334"}, want: "foobar:2001:0db8:85a3:0000:0000:8a2e:0370:7334", wantErr: false}, - {name: "bad-ipv6", args: args{val: "foobar:0db8:85a3:0000:0000:8a2e:0370:7334"}, want: "", wantErr: true}, - {name: "bad-ipv6", args: args{val: "foobar:0db8:85a3:0000:0000:8a2e:0370:7334.0000.0000.000"}, want: "", wantErr: true}, - {name: "noname-ipv6", args: args{val: "2001:0db8:85a3:0000:0000:8a2e:0370:7334"}, want: "", wantErr: true}, - {name: "noname-ipv6", args: args{val: ":2001:0db8:85a3:0000:0000:8a2e:0370:7334"}, want: "", wantErr: true}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := ValidateExtraHost(tt.args.val) - if (err != nil) != tt.wantErr { - t.Errorf("ValidateExtraHost() error = %v, wantErr %v", err, tt.wantErr) - return - } - if got != tt.want { - t.Errorf("ValidateExtraHost() = %v, want %v", got, tt.want) - } - }) - } -} - -func Test_validateIPAddress(t *testing.T) { - type args struct { - val string - } - tests := []struct { - name string - args args - want string - wantErr bool - }{ - {name: "ipv4-good", args: args{val: "192.168.1.1"}, want: "192.168.1.1", wantErr: false}, - {name: "ipv4-bad", args: args{val: "192.168.1.1.1"}, want: "", wantErr: true}, - {name: "ipv4-bad", args: args{val: "192."}, want: "", wantErr: true}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := validateIPAddress(tt.args.val) - if (err != nil) != tt.wantErr { - t.Errorf("validateIPAddress() error = %v, wantErr %v", err, tt.wantErr) - return - } - if got != tt.want { - t.Errorf("validateIPAddress() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestValidateFileName(t *testing.T) { - type args struct { - filename string - } - tests := []struct { - name string - args args - wantErr bool - }{ - {name: "good", args: args{filename: "/some/rand/path"}, wantErr: false}, - {name: "good", args: args{filename: "some/rand/path"}, wantErr: false}, - {name: "good", args: args{filename: "/"}, wantErr: false}, - {name: "bad", args: args{filename: "/:"}, wantErr: true}, - {name: "bad", args: args{filename: ":/"}, wantErr: true}, - {name: "bad", args: args{filename: "/some/rand:/path"}, wantErr: true}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if err := ValidateFileName(tt.args.filename); (err != nil) != tt.wantErr { - t.Errorf("ValidateFileName() error = %v, wantErr %v", err, tt.wantErr) - } - }) - } -} - -func TestGetAllLabels(t *testing.T) { - fileLabels := []string{} - labels, _ := GetAllLabels(fileLabels, Var1) - assert.Equal(t, len(labels), 2) -} - -func TestGetAllLabelsBadKeyValue(t *testing.T) { - inLabels := []string{"=badValue", "="} - fileLabels := []string{} - _, err := GetAllLabels(fileLabels, inLabels) - assert.Error(t, err, assert.AnError) -} - -func TestGetAllLabelsBadLabelFile(t *testing.T) { - fileLabels := []string{"/foobar5001/be"} - _, err := GetAllLabels(fileLabels, Var1) - assert.Error(t, err, assert.AnError) -} - -func TestGetAllLabelsFile(t *testing.T) { - content := []byte("THREE=3") - tFile, err := createTmpFile(content) - defer os.Remove(tFile) - assert.NoError(t, err) - fileLabels := []string{tFile} - result, _ := GetAllLabels(fileLabels, Var1) - assert.Equal(t, len(result), 3) -} diff --git a/cmd/podmanV2/pods/create.go b/cmd/podmanV2/pods/create.go deleted file mode 100644 index ab8957ee3..000000000 --- a/cmd/podmanV2/pods/create.go +++ /dev/null @@ -1,132 +0,0 @@ -package pods - -import ( - "context" - "fmt" - "os" - "strings" - - "github.com/containers/libpod/cmd/podmanV2/common" - "github.com/containers/libpod/cmd/podmanV2/parse" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/libpod/define" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/containers/libpod/pkg/errorhandling" - "github.com/containers/libpod/pkg/specgen" - "github.com/containers/libpod/pkg/util" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - podCreateDescription = `After creating the pod, the pod ID is printed to stdout. - - You can then start it at any time with the podman pod start <pod_id> command. The pod will be created with the initial state 'created'.` - - createCommand = &cobra.Command{ - Use: "create", - Args: cobra.NoArgs, - Short: "Create a new empty pod", - Long: podCreateDescription, - RunE: create, - } -) - -var ( - createOptions entities.PodCreateOptions - labels, labelFile []string - podIDFile string - share string -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: createCommand, - Parent: podCmd, - }) - flags := createCommand.Flags() - flags.SetInterspersed(false) - flags.AddFlagSet(common.GetNetFlags()) - flags.StringVar(&createOptions.CGroupParent, "cgroup-parent", "", "Set parent cgroup for the pod") - flags.BoolVar(&createOptions.Infra, "infra", true, "Create an infra container associated with the pod to share namespaces with") - flags.StringVar(&createOptions.InfraImage, "infra-image", define.DefaultInfraImage, "The image of the infra container to associate with the pod") - flags.StringVar(&createOptions.InfraCommand, "infra-command", define.DefaultInfraCommand, "The command to run on the infra container when the pod is started") - flags.StringSliceVar(&labelFile, "label-file", []string{}, "Read in a line delimited file of labels") - flags.StringSliceVarP(&labels, "label", "l", []string{}, "Set metadata on pod (default [])") - flags.StringVarP(&createOptions.Name, "name", "n", "", "Assign a name to the pod") - flags.StringVarP(&createOptions.Hostname, "hostname", "", "", "Set a hostname to the pod") - flags.StringVar(&podIDFile, "pod-id-file", "", "Write the pod ID to the file") - flags.StringVar(&share, "share", common.DefaultKernelNamespaces, "A comma delimited list of kernel namespaces the pod will share") -} - -func create(cmd *cobra.Command, args []string) error { - var ( - err error - podIdFile *os.File - ) - createOptions.Labels, err = parse.GetAllLabels(labelFile, labels) - if err != nil { - return errors.Wrapf(err, "unable to process labels") - } - - if !createOptions.Infra && cmd.Flag("share").Changed && share != "none" && share != "" { - return errors.Errorf("You cannot share kernel namespaces on the pod level without an infra container") - } - createOptions.Share = strings.Split(share, ",") - if cmd.Flag("pod-id-file").Changed { - podIdFile, err = util.OpenExclusiveFile(podIDFile) - if err != nil && os.IsExist(err) { - return errors.Errorf("pod id file exists. Ensure another pod is not using it or delete %s", podIDFile) - } - if err != nil { - return errors.Errorf("error opening pod-id-file %s", podIDFile) - } - defer errorhandling.CloseQuiet(podIdFile) - defer errorhandling.SyncQuiet(podIdFile) - } - - createOptions.Net, err = common.NetFlagsToNetOptions(cmd) - if err != nil { - return err - } - netInput, err := cmd.Flags().GetString("network") - if err != nil { - return err - } - n := specgen.Namespace{} - switch netInput { - case "bridge": - n.NSMode = specgen.Bridge - case "host": - n.NSMode = specgen.Host - case "slip4netns": - n.NSMode = specgen.Slirp - default: - if strings.HasPrefix(netInput, "container:") { //nolint - split := strings.Split(netInput, ":") - if len(split) != 2 { - return errors.Errorf("invalid network paramater: %q", netInput) - } - n.NSMode = specgen.FromContainer - n.Value = split[1] - } else if strings.HasPrefix(netInput, "ns:") { - return errors.New("the ns: network option is not supported for pods") - } else { - n.NSMode = specgen.Bridge - createOptions.Net.CNINetworks = strings.Split(netInput, ",") - } - } - if len(createOptions.Net.PublishPorts) > 0 { - if !createOptions.Infra { - return errors.Errorf("you must have an infra container to publish port bindings to the host") - } - } - - response, err := registry.ContainerEngine().PodCreate(context.Background(), createOptions) - if err != nil { - return err - } - fmt.Println(response.Id) - return nil -} diff --git a/cmd/podmanV2/pods/exists.go b/cmd/podmanV2/pods/exists.go deleted file mode 100644 index e37f2ebd7..000000000 --- a/cmd/podmanV2/pods/exists.go +++ /dev/null @@ -1,43 +0,0 @@ -package pods - -import ( - "context" - "os" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - podExistsDescription = `If the named pod exists in local storage, podman pod exists exits with 0, otherwise the exit code will be 1.` - - existsCommand = &cobra.Command{ - Use: "exists POD", - Short: "Check if a pod exists in local storage", - Long: podExistsDescription, - RunE: exists, - Args: cobra.ExactArgs(1), - Example: `podman pod exists podID - podman pod exists mypod || podman pod create --name mypod`, - } -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: existsCommand, - Parent: podCmd, - }) -} - -func exists(cmd *cobra.Command, args []string) error { - response, err := registry.ContainerEngine().PodExists(context.Background(), args[0]) - if err != nil { - return err - } - if !response.Value { - os.Exit(1) - } - return nil -} diff --git a/cmd/podmanV2/pods/inspect.go b/cmd/podmanV2/pods/inspect.go deleted file mode 100644 index 9aab610f2..000000000 --- a/cmd/podmanV2/pods/inspect.go +++ /dev/null @@ -1,64 +0,0 @@ -package pods - -import ( - "context" - "fmt" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - inspectOptions = entities.PodInspectOptions{} -) - -var ( - inspectDescription = fmt.Sprintf(`Display the configuration for a pod by name or id - - By default, this will render all results in a JSON array.`) - - inspectCmd = &cobra.Command{ - Use: "inspect [flags] POD [POD...]", - Short: "Displays a pod configuration", - Long: inspectDescription, - RunE: inspect, - Example: `podman pod inspect podID`, - } -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: inspectCmd, - Parent: podCmd, - }) - flags := inspectCmd.Flags() - flags.BoolVarP(&inspectOptions.Latest, "latest", "l", false, "Act on the latest pod podman is aware of") - if registry.IsRemote() { - _ = flags.MarkHidden("latest") - } -} - -func inspect(cmd *cobra.Command, args []string) error { - - if len(args) < 1 && !inspectOptions.Latest { - return errors.Errorf("you must provide the name or id of a running pod") - } - - if !inspectOptions.Latest { - inspectOptions.NameOrID = args[0] - } - responses, err := registry.ContainerEngine().PodInspect(context.Background(), inspectOptions) - if err != nil { - return err - } - b, err := jsoniter.MarshalIndent(responses, "", " ") - if err != nil { - return err - } - fmt.Println(string(b)) - return nil -} diff --git a/cmd/podmanV2/pods/kill.go b/cmd/podmanV2/pods/kill.go deleted file mode 100644 index 06cca916c..000000000 --- a/cmd/podmanV2/pods/kill.go +++ /dev/null @@ -1,68 +0,0 @@ -package pods - -import ( - "context" - "fmt" - - "github.com/containers/libpod/cmd/podmanV2/parse" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/cmd/podmanV2/utils" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - podKillDescription = `Signals are sent to the main process of each container inside the specified pod. - - The default signal is SIGKILL, or any signal specified with option --signal.` - killCommand = &cobra.Command{ - Use: "kill [flags] POD [POD...]", - Short: "Send the specified signal or SIGKILL to containers in pod", - Long: podKillDescription, - RunE: kill, - Args: func(cmd *cobra.Command, args []string) error { - return parse.CheckAllLatestAndCIDFile(cmd, args, false, false) - }, - Example: `podman pod kill podID - podman pod kill --signal TERM mywebserver - podman pod kill --latest`, - } -) - -var ( - killOpts entities.PodKillOptions -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: killCommand, - Parent: podCmd, - }) - flags := killCommand.Flags() - flags.BoolVarP(&killOpts.All, "all", "a", false, "Kill all containers in all pods") - flags.BoolVarP(&killOpts.Latest, "latest", "l", false, "Act on the latest pod podman is aware of") - flags.StringVarP(&killOpts.Signal, "signal", "s", "KILL", "Signal to send to the containers in the pod") - if registry.IsRemote() { - _ = flags.MarkHidden("latest") - } - -} -func kill(cmd *cobra.Command, args []string) error { - var ( - errs utils.OutputErrors - ) - responses, err := registry.ContainerEngine().PodKill(context.Background(), args, killOpts) - if err != nil { - return err - } - // in the cli, first we print out all the successful attempts - for _, r := range responses { - if len(r.Errs) == 0 { - fmt.Println(r.Id) - } else { - errs = append(errs, r.Errs...) - } - } - return errs.PrintErrors() -} diff --git a/cmd/podmanV2/pods/pause.go b/cmd/podmanV2/pods/pause.go deleted file mode 100644 index dc86e534d..000000000 --- a/cmd/podmanV2/pods/pause.go +++ /dev/null @@ -1,66 +0,0 @@ -package pods - -import ( - "context" - "fmt" - - "github.com/containers/libpod/cmd/podmanV2/parse" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/cmd/podmanV2/utils" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - podPauseDescription = `The pod name or ID can be used. - - All running containers within each specified pod will then be paused.` - pauseCommand = &cobra.Command{ - Use: "pause [flags] POD [POD...]", - Short: "Pause one or more pods", - Long: podPauseDescription, - RunE: pause, - Args: func(cmd *cobra.Command, args []string) error { - return parse.CheckAllLatestAndCIDFile(cmd, args, false, false) - }, - Example: `podman pod pause podID1 podID2 - podman pod pause --latest - podman pod pause --all`, - } -) - -var ( - pauseOptions entities.PodPauseOptions -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: pauseCommand, - Parent: podCmd, - }) - flags := pauseCommand.Flags() - flags.BoolVarP(&pauseOptions.All, "all", "a", false, "Pause all running pods") - flags.BoolVarP(&pauseOptions.Latest, "latest", "l", false, "Act on the latest pod podman is aware of") - if registry.IsRemote() { - _ = flags.MarkHidden("latest") - } -} -func pause(cmd *cobra.Command, args []string) error { - var ( - errs utils.OutputErrors - ) - responses, err := registry.ContainerEngine().PodPause(context.Background(), args, pauseOptions) - if err != nil { - return err - } - // in the cli, first we print out all the successful attempts - for _, r := range responses { - if len(r.Errs) == 0 { - fmt.Println(r.Id) - } else { - errs = append(errs, r.Errs...) - } - } - return errs.PrintErrors() -} diff --git a/cmd/podmanV2/pods/pod.go b/cmd/podmanV2/pods/pod.go deleted file mode 100644 index 3766893bb..000000000 --- a/cmd/podmanV2/pods/pod.go +++ /dev/null @@ -1,63 +0,0 @@ -package pods - -import ( - "strings" - "text/template" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - // Command: podman _pod_ - podCmd = &cobra.Command{ - Use: "pod", - Short: "Manage pods", - Long: "Manage pods", - TraverseChildren: true, - PersistentPreRunE: preRunE, - RunE: registry.SubCommandExists, - } -) - -var podFuncMap = template.FuncMap{ - "numCons": func(cons []*entities.ListPodContainer) int { - return len(cons) - }, - "podcids": func(cons []*entities.ListPodContainer) string { - var ctrids []string - for _, c := range cons { - ctrids = append(ctrids, c.Id[:12]) - } - return strings.Join(ctrids, ",") - }, - "podconnames": func(cons []*entities.ListPodContainer) string { - var ctrNames []string - for _, c := range cons { - ctrNames = append(ctrNames, c.Names[:12]) - } - return strings.Join(ctrNames, ",") - }, - "podconstatuses": func(cons []*entities.ListPodContainer) string { - var statuses []string - for _, c := range cons { - statuses = append(statuses, c.Status) - } - return strings.Join(statuses, ",") - }, -} - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: podCmd, - }) - podCmd.SetHelpTemplate(registry.HelpTemplate()) - podCmd.SetUsageTemplate(registry.UsageTemplate()) -} - -func preRunE(cmd *cobra.Command, args []string) error { - _, err := registry.NewContainerEngine(cmd, args) - return err -} diff --git a/cmd/podmanV2/pods/ps.go b/cmd/podmanV2/pods/ps.go deleted file mode 100644 index 9875263ac..000000000 --- a/cmd/podmanV2/pods/ps.go +++ /dev/null @@ -1,166 +0,0 @@ -package pods - -import ( - "context" - "encoding/json" - "fmt" - "io" - "os" - "strings" - "text/tabwriter" - "text/template" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/cmd/podmanV2/report" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - psDescription = "List all pods on system including their names, ids and current state." - - // Command: podman pod _ps_ - psCmd = &cobra.Command{ - Use: "ps", - Aliases: []string{"ls", "list"}, - Short: "list pods", - Long: psDescription, - RunE: pods, - } -) - -var ( - defaultHeaders string = "POD ID\tNAME\tSTATUS\tCREATED" - inputFilters string - noTrunc bool - psInput entities.PodPSOptions -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: psCmd, - Parent: podCmd, - }) - flags := psCmd.Flags() - flags.BoolVar(&psInput.CtrNames, "ctr-names", false, "Display the container names") - flags.BoolVar(&psInput.CtrIds, "ctr-ids", false, "Display the container UUIDs. If no-trunc is not set they will be truncated") - flags.BoolVar(&psInput.CtrStatus, "ctr-status", false, "Display the container status") - // TODO should we make this a [] ? - flags.StringVarP(&inputFilters, "filter", "f", "", "Filter output based on conditions given") - flags.StringVar(&psInput.Format, "format", "", "Pretty-print pods to JSON or using a Go template") - flags.BoolVarP(&psInput.Latest, "latest", "l", false, "Act on the latest pod podman is aware of") - flags.BoolVar(&psInput.Namespace, "namespace", false, "Display namespace information of the pod") - flags.BoolVar(&psInput.Namespace, "ns", false, "Display namespace information of the pod") - flags.BoolVar(&noTrunc, "no-trunc", false, "Do not truncate pod and container IDs") - flags.BoolVarP(&psInput.Quiet, "quiet", "q", false, "Print the numeric IDs of the pods only") - flags.StringVar(&psInput.Sort, "sort", "created", "Sort output by created, id, name, or number") - if registry.IsRemote() { - _ = flags.MarkHidden("latest") - } -} - -func pods(cmd *cobra.Command, args []string) error { - var ( - w io.Writer = os.Stdout - row string - ) - if cmd.Flag("filter").Changed { - for _, f := range strings.Split(inputFilters, ",") { - split := strings.Split(f, "=") - if len(split) < 2 { - return errors.Errorf("filter input must be in the form of filter=value: %s is invalid", f) - } - psInput.Filters[split[0]] = append(psInput.Filters[split[0]], split[1]) - } - } - responses, err := registry.ContainerEngine().PodPs(context.Background(), psInput) - if err != nil { - return err - } - - if psInput.Format == "json" { - b, err := json.MarshalIndent(responses, "", " ") - if err != nil { - return err - } - fmt.Println(string(b)) - return nil - } - headers, row := createPodPsOut() - if psInput.Quiet { - if noTrunc { - row = "{{.Id}}\n" - } else { - row = "{{slice .Id 0 12}}\n" - } - } - if cmd.Flag("format").Changed { - row = psInput.Format - if !strings.HasPrefix(row, "\n") { - row += "\n" - } - } - format := "{{range . }}" + row + "{{end}}" - if !psInput.Quiet && !cmd.Flag("format").Changed { - format = headers + format - } - funcs := report.AppendFuncMap(podFuncMap) - tmpl, err := template.New("listPods").Funcs(funcs).Parse(format) - if err != nil { - return err - } - if !psInput.Quiet { - w = tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0) - } - if err := tmpl.Execute(w, responses); err != nil { - return err - } - if flusher, ok := w.(interface{ Flush() error }); ok { - return flusher.Flush() - } - return nil -} - -func createPodPsOut() (string, string) { - var row string - headers := defaultHeaders - if noTrunc { - row += "{{.Id}}" - } else { - row += "{{slice .Id 0 12}}" - } - - row += "\t{{.Name}}\t{{.Status}}\t{{humanDurationFromTime .Created}}" - - //rowFormat string = "{{slice .Id 0 12}}\t{{.Name}}\t{{.Status}}\t{{humanDurationFromTime .Created}}" - if psInput.CtrIds { - headers += "\tIDS" - row += "\t{{podcids .Containers}}" - } - if psInput.CtrNames { - headers += "\tNAMES" - row += "\t{{podconnames .Containers}}" - } - if psInput.CtrStatus { - headers += "\tSTATUS" - row += "\t{{podconstatuses .Containers}}" - } - if psInput.Namespace { - headers += "\tCGROUP\tNAMESPACES" - row += "\t{{.Cgroup}}\t{{.Namespace}}" - } - if !psInput.CtrStatus && !psInput.CtrNames && !psInput.CtrIds { - headers += "\t# OF CONTAINERS" - row += "\t{{numCons .Containers}}" - - } - headers += "\tINFRA ID\n" - if noTrunc { - row += "\t{{.InfraId}}\n" - } else { - row += "\t{{slice .InfraId 0 12}}\n" - } - return headers, row -} diff --git a/cmd/podmanV2/pods/restart.go b/cmd/podmanV2/pods/restart.go deleted file mode 100644 index 1c8709704..000000000 --- a/cmd/podmanV2/pods/restart.go +++ /dev/null @@ -1,68 +0,0 @@ -package pods - -import ( - "context" - "fmt" - - "github.com/containers/libpod/cmd/podmanV2/parse" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/cmd/podmanV2/utils" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - podRestartDescription = `The pod ID or name can be used. - - All of the containers within each of the specified pods will be restarted. If a container in a pod is not currently running it will be started.` - restartCommand = &cobra.Command{ - Use: "restart [flags] POD [POD...]", - Short: "Restart one or more pods", - Long: podRestartDescription, - RunE: restart, - Args: func(cmd *cobra.Command, args []string) error { - return parse.CheckAllLatestAndCIDFile(cmd, args, false, false) - }, - Example: `podman pod restart podID1 podID2 - podman pod restart --latest - podman pod restart --all`, - } -) - -var ( - restartOptions = entities.PodRestartOptions{} -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: restartCommand, - Parent: podCmd, - }) - - flags := restartCommand.Flags() - flags.BoolVarP(&restartOptions.All, "all", "a", false, "Restart all running pods") - flags.BoolVarP(&restartOptions.Latest, "latest", "l", false, "Restart the latest pod podman is aware of") - if registry.IsRemote() { - _ = flags.MarkHidden("latest") - } -} - -func restart(cmd *cobra.Command, args []string) error { - var ( - errs utils.OutputErrors - ) - responses, err := registry.ContainerEngine().PodRestart(context.Background(), args, restartOptions) - if err != nil { - return err - } - // in the cli, first we print out all the successful attempts - for _, r := range responses { - if len(r.Errs) == 0 { - fmt.Println(r.Id) - } else { - errs = append(errs, r.Errs...) - } - } - return errs.PrintErrors() -} diff --git a/cmd/podmanV2/pods/rm.go b/cmd/podmanV2/pods/rm.go deleted file mode 100644 index b43dd2d6c..000000000 --- a/cmd/podmanV2/pods/rm.go +++ /dev/null @@ -1,71 +0,0 @@ -package pods - -import ( - "context" - "fmt" - - "github.com/containers/libpod/cmd/podmanV2/parse" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/cmd/podmanV2/utils" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - podRmDescription = fmt.Sprintf(`podman rm will remove one or more stopped pods and their containers from the host. - - The pod name or ID can be used. A pod with containers will not be removed without --force. If --force is specified, all containers will be stopped, then removed.`) - rmCommand = &cobra.Command{ - Use: "rm [flags] POD [POD...]", - Short: "Remove one or more pods", - Long: podRmDescription, - RunE: rm, - Args: func(cmd *cobra.Command, args []string) error { - return parse.CheckAllLatestAndCIDFile(cmd, args, false, false) - }, - Example: `podman pod rm mywebserverpod - podman pod rm -f 860a4b23 - podman pod rm -f -a`, - } -) - -var ( - rmOptions = entities.PodRmOptions{} -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: rmCommand, - Parent: podCmd, - }) - - flags := rmCommand.Flags() - flags.BoolVarP(&rmOptions.All, "all", "a", false, "Restart all running pods") - flags.BoolVarP(&rmOptions.Force, "force", "f", false, "Force removal of a running pod by first stopping all containers, then removing all containers in the pod. The default is false") - flags.BoolVarP(&rmOptions.Ignore, "ignore", "i", false, "Ignore errors when a specified pod is missing") - flags.BoolVarP(&rmOptions.Latest, "latest", "l", false, "Restart the latest pod podman is aware of") - if registry.IsRemote() { - _ = flags.MarkHidden("latest") - _ = flags.MarkHidden("ignore") - } -} - -func rm(cmd *cobra.Command, args []string) error { - var ( - errs utils.OutputErrors - ) - responses, err := registry.ContainerEngine().PodRm(context.Background(), args, rmOptions) - if err != nil { - return err - } - // in the cli, first we print out all the successful attempts - for _, r := range responses { - if r.Err == nil { - fmt.Println(r.Id) - } else { - errs = append(errs, r.Err) - } - } - return errs.PrintErrors() -} diff --git a/cmd/podmanV2/pods/start.go b/cmd/podmanV2/pods/start.go deleted file mode 100644 index 11ac312f9..000000000 --- a/cmd/podmanV2/pods/start.go +++ /dev/null @@ -1,68 +0,0 @@ -package pods - -import ( - "context" - "fmt" - - "github.com/containers/libpod/cmd/podmanV2/parse" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/cmd/podmanV2/utils" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - podStartDescription = `The pod name or ID can be used. - - All containers defined in the pod will be started.` - startCommand = &cobra.Command{ - Use: "start [flags] POD [POD...]", - Short: "Start one or more pods", - Long: podStartDescription, - RunE: start, - Args: func(cmd *cobra.Command, args []string) error { - return parse.CheckAllLatestAndCIDFile(cmd, args, false, false) - }, - Example: `podman pod start podID - podman pod start --latest - podman pod start --all`, - } -) - -var ( - startOptions = entities.PodStartOptions{} -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: startCommand, - Parent: podCmd, - }) - - flags := startCommand.Flags() - flags.BoolVarP(&startOptions.All, "all", "a", false, "Restart all running pods") - flags.BoolVarP(&startOptions.Latest, "latest", "l", false, "Restart the latest pod podman is aware of") - if registry.IsRemote() { - _ = flags.MarkHidden("latest") - } -} - -func start(cmd *cobra.Command, args []string) error { - var ( - errs utils.OutputErrors - ) - responses, err := registry.ContainerEngine().PodStart(context.Background(), args, startOptions) - if err != nil { - return err - } - // in the cli, first we print out all the successful attempts - for _, r := range responses { - if len(r.Errs) == 0 { - fmt.Println(r.Id) - } else { - errs = append(errs, r.Errs...) - } - } - return errs.PrintErrors() -} diff --git a/cmd/podmanV2/pods/stop.go b/cmd/podmanV2/pods/stop.go deleted file mode 100644 index 403c7d95d..000000000 --- a/cmd/podmanV2/pods/stop.go +++ /dev/null @@ -1,79 +0,0 @@ -package pods - -import ( - "context" - "fmt" - - "github.com/containers/libpod/cmd/podmanV2/parse" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/cmd/podmanV2/utils" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - podStopDescription = `The pod name or ID can be used. - - This command will stop all running containers in each of the specified pods.` - - stopCommand = &cobra.Command{ - Use: "stop [flags] POD [POD...]", - Short: "Stop one or more pods", - Long: podStopDescription, - RunE: stop, - Args: func(cmd *cobra.Command, args []string) error { - return parse.CheckAllLatestAndCIDFile(cmd, args, false, false) - }, - Example: `podman pod stop mywebserverpod - podman pod stop --latest - podman pod stop --time 0 490eb 3557fb`, - } -) - -var ( - stopOptions = entities.PodStopOptions{ - Timeout: -1, - } - timeout uint -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: stopCommand, - Parent: podCmd, - }) - flags := stopCommand.Flags() - flags.BoolVarP(&stopOptions.All, "all", "a", false, "Stop all running pods") - flags.BoolVarP(&stopOptions.Ignore, "ignore", "i", false, "Ignore errors when a specified pod is missing") - flags.BoolVarP(&stopOptions.Latest, "latest", "l", false, "Stop the latest pod podman is aware of") - flags.UintVarP(&timeout, "time", "t", 0, "Seconds to wait for pod stop before killing the container") - if registry.IsRemote() { - _ = flags.MarkHidden("latest") - _ = flags.MarkHidden("ignore") - - } - flags.SetNormalizeFunc(utils.AliasFlags) -} - -func stop(cmd *cobra.Command, args []string) error { - var ( - errs utils.OutputErrors - ) - if cmd.Flag("time").Changed { - stopOptions.Timeout = int(timeout) - } - responses, err := registry.ContainerEngine().PodStop(context.Background(), args, stopOptions) - if err != nil { - return err - } - // in the cli, first we print out all the successful attempts - for _, r := range responses { - if len(r.Errs) == 0 { - fmt.Println(r.Id) - } else { - errs = append(errs, r.Errs...) - } - } - return errs.PrintErrors() -} diff --git a/cmd/podmanV2/pods/top.go b/cmd/podmanV2/pods/top.go deleted file mode 100644 index 5ef282238..000000000 --- a/cmd/podmanV2/pods/top.go +++ /dev/null @@ -1,90 +0,0 @@ -package pods - -import ( - "context" - "fmt" - "os" - "strings" - "text/tabwriter" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/containers/psgo" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - topDescription = fmt.Sprintf(`Specify format descriptors to alter the output. - - You may run "podman pod top -l pid pcpu seccomp" to print the process ID, the CPU percentage and the seccomp mode of each process of the latest pod. - Format Descriptors: - %s`, strings.Join(psgo.ListDescriptors(), ",")) - - topOptions = entities.PodTopOptions{} - - topCommand = &cobra.Command{ - Use: "top [flags] POD [FORMAT-DESCRIPTORS|ARGS]", - Short: "Display the running processes in a pod", - Long: topDescription, - PersistentPreRunE: preRunE, - RunE: top, - Args: cobra.ArbitraryArgs, - Example: `podman pod top podID -podman pod top --latest -podman pod top podID pid seccomp args %C -podman pod top podID -eo user,pid,comm`, - } -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: topCommand, - Parent: podCmd, - }) - - topCommand.SetHelpTemplate(registry.HelpTemplate()) - topCommand.SetUsageTemplate(registry.UsageTemplate()) - - flags := topCommand.Flags() - flags.SetInterspersed(false) - flags.BoolVar(&topOptions.ListDescriptors, "list-descriptors", false, "") - flags.BoolVarP(&topOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - - _ = flags.MarkHidden("list-descriptors") // meant only for bash completion - if registry.IsRemote() { - _ = flags.MarkHidden("latest") - } -} - -func top(cmd *cobra.Command, args []string) error { - if topOptions.ListDescriptors { - fmt.Println(strings.Join(psgo.ListDescriptors(), "\n")) - return nil - } - - if len(args) < 1 && !topOptions.Latest { - return errors.Errorf("you must provide the name or id of a running pod") - } - - if topOptions.Latest { - topOptions.Descriptors = args - } else { - topOptions.NameOrID = args[0] - topOptions.Descriptors = args[1:] - } - - topResponse, err := registry.ContainerEngine().PodTop(context.Background(), topOptions) - if err != nil { - return err - } - - w := tabwriter.NewWriter(os.Stdout, 5, 1, 3, ' ', 0) - for _, proc := range topResponse.Value { - if _, err := fmt.Fprintln(w, proc); err != nil { - return err - } - } - return w.Flush() -} diff --git a/cmd/podmanV2/pods/unpause.go b/cmd/podmanV2/pods/unpause.go deleted file mode 100644 index 2de7b964f..000000000 --- a/cmd/podmanV2/pods/unpause.go +++ /dev/null @@ -1,66 +0,0 @@ -package pods - -import ( - "context" - "fmt" - - "github.com/containers/libpod/cmd/podmanV2/parse" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/cmd/podmanV2/utils" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - podUnpauseDescription = `The podman unpause command will unpause all "paused" containers assigned to the pod. - - The pod name or ID can be used.` - unpauseCommand = &cobra.Command{ - Use: "unpause [flags] POD [POD...]", - Short: "Unpause one or more pods", - Long: podUnpauseDescription, - RunE: unpause, - Args: func(cmd *cobra.Command, args []string) error { - return parse.CheckAllLatestAndCIDFile(cmd, args, false, false) - }, - Example: `podman pod unpause podID1 podID2 - podman pod unpause --all - podman pod unpause --latest`, - } -) - -var ( - unpauseOptions entities.PodunpauseOptions -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: unpauseCommand, - Parent: podCmd, - }) - flags := unpauseCommand.Flags() - flags.BoolVarP(&unpauseOptions.All, "all", "a", false, "Pause all running pods") - flags.BoolVarP(&unpauseOptions.Latest, "latest", "l", false, "Act on the latest pod podman is aware of") - if registry.IsRemote() { - _ = flags.MarkHidden("latest") - } -} -func unpause(cmd *cobra.Command, args []string) error { - var ( - errs utils.OutputErrors - ) - responses, err := registry.ContainerEngine().PodUnpause(context.Background(), args, unpauseOptions) - if err != nil { - return err - } - // in the cli, first we print out all the successful attempts - for _, r := range responses { - if len(r.Errs) == 0 { - fmt.Println(r.Id) - } else { - errs = append(errs, r.Errs...) - } - } - return errs.PrintErrors() -} diff --git a/cmd/podmanV2/registry/registry.go b/cmd/podmanV2/registry/registry.go deleted file mode 100644 index 401f82718..000000000 --- a/cmd/podmanV2/registry/registry.go +++ /dev/null @@ -1,136 +0,0 @@ -package registry - -import ( - "context" - - "github.com/containers/libpod/pkg/domain/entities" - "github.com/containers/libpod/pkg/domain/infra" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -type CobraFuncs func(cmd *cobra.Command, args []string) error - -type CliCommand struct { - Mode []entities.EngineMode - Command *cobra.Command - Parent *cobra.Command -} - -const ExecErrorCodeGeneric = 125 - -var ( - cliCtx context.Context - containerEngine entities.ContainerEngine - exitCode = ExecErrorCodeGeneric - imageEngine entities.ImageEngine - - Commands []CliCommand - EngineOptions entities.EngineOptions -) - -func SetExitCode(code int) { - exitCode = code -} - -func GetExitCode() int { - return exitCode -} - -// 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 displaying of the global options. The main podman -// command should not use this. -func UsageTemplate() string { - return `Usage(v2):{{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}} -` -} - -func ImageEngine() entities.ImageEngine { - return imageEngine -} - -// NewImageEngine is a wrapper for building an ImageEngine to be used for PreRunE functions -func NewImageEngine(cmd *cobra.Command, args []string) (entities.ImageEngine, error) { - if imageEngine == nil { - EngineOptions.FlagSet = cmd.Flags() - engine, err := infra.NewImageEngine(EngineOptions) - if err != nil { - return nil, err - } - imageEngine = engine - } - return imageEngine, nil -} - -func ContainerEngine() entities.ContainerEngine { - return containerEngine -} - -// NewContainerEngine is a wrapper for building an ContainerEngine to be used for PreRunE functions -func NewContainerEngine(cmd *cobra.Command, args []string) (entities.ContainerEngine, error) { - if containerEngine == nil { - EngineOptions.FlagSet = cmd.Flags() - engine, err := infra.NewContainerEngine(EngineOptions) - if err != nil { - return nil, err - } - containerEngine = engine - } - return containerEngine, nil -} - -func SubCommandExists(cmd *cobra.Command, args []string) error { - if len(args) > 0 { - return errors.Errorf("unrecognized command `%[1]s %[2]s`\nTry '%[1]s --help' for more information.", cmd.CommandPath(), args[0]) - } - return errors.Errorf("missing command '%[1]s COMMAND'\nTry '%[1]s --help' for more information.", cmd.CommandPath()) -} - -type podmanContextKey string - -var podmanFactsKey = podmanContextKey("engineOptions") - -func NewOptions(ctx context.Context, facts *entities.EngineOptions) context.Context { - return context.WithValue(ctx, podmanFactsKey, facts) -} - -func Options(cmd *cobra.Command) (*entities.EngineOptions, error) { - if f, ok := cmd.Context().Value(podmanFactsKey).(*entities.EngineOptions); ok { - return f, errors.New("Command Context ") - } - return nil, nil -} - -func GetContext() context.Context { - if cliCtx == nil { - cliCtx = context.TODO() - } - return cliCtx -} diff --git a/cmd/podmanV2/registry/remote.go b/cmd/podmanV2/registry/remote.go deleted file mode 100644 index 32a231ac4..000000000 --- a/cmd/podmanV2/registry/remote.go +++ /dev/null @@ -1,9 +0,0 @@ -package registry - -import ( - "github.com/containers/libpod/pkg/domain/entities" -) - -func IsRemote() bool { - return EngineOptions.EngineMode == entities.TunnelMode -} diff --git a/cmd/podmanV2/report/templates.go b/cmd/podmanV2/report/templates.go deleted file mode 100644 index e46048e97..000000000 --- a/cmd/podmanV2/report/templates.go +++ /dev/null @@ -1,73 +0,0 @@ -package report - -import ( - "strings" - "text/template" - "time" - "unicode" - - "github.com/docker/go-units" -) - -var defaultFuncMap = template.FuncMap{ - "ellipsis": func(s string, length int) string { - if len(s) > length { - return s[:length-3] + "..." - } - return s - }, - "humanDuration": func(t int64) string { - return units.HumanDuration(time.Since(time.Unix(t, 0))) + " ago" - }, - "humanDurationFromTime": func(t time.Time) string { - return units.HumanDuration(time.Since(t)) + " ago" - }, - "humanSize": func(sz int64) string { - s := units.HumanSizeWithPrecision(float64(sz), 3) - i := strings.LastIndexFunc(s, unicode.IsNumber) - return s[:i+1] + " " + s[i+1:] - }, - "join": strings.Join, - "lower": strings.ToLower, - "rfc3339": func(t int64) string { - return time.Unix(t, 0).Format(time.RFC3339) - }, - "replace": strings.Replace, - "split": strings.Split, - "title": strings.Title, - "upper": strings.ToUpper, - // TODO: Remove after Go 1.14 port - "slice": func(s string, i, j int) string { - if i > j || len(s) < i { - return s - } - if len(s) < j { - return s[i:] - } - return s[i:j] - }, -} - -func ReportHeader(columns ...string) []byte { - hdr := make([]string, len(columns)) - for i, h := range columns { - hdr[i] = strings.ToUpper(h) - } - return []byte(strings.Join(hdr, "\t") + "\n") -} - -func AppendFuncMap(funcMap template.FuncMap) template.FuncMap { - merged := PodmanTemplateFuncs() - for k, v := range funcMap { - merged[k] = v - } - return merged -} - -func PodmanTemplateFuncs() template.FuncMap { - merged := make(template.FuncMap) - for k, v := range defaultFuncMap { - merged[k] = v - } - return merged -} diff --git a/cmd/podmanV2/root.go b/cmd/podmanV2/root.go deleted file mode 100644 index 6fc12f57e..000000000 --- a/cmd/podmanV2/root.go +++ /dev/null @@ -1,99 +0,0 @@ -package main - -import ( - "fmt" - "log/syslog" - "os" - "path" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/containers/libpod/version" - "github.com/sirupsen/logrus" - logrusSyslog "github.com/sirupsen/logrus/hooks/syslog" - "github.com/spf13/cobra" -) - -var ( - rootCmd = &cobra.Command{ - Use: path.Base(os.Args[0]), - Long: "Manage pods, containers and images", - SilenceUsage: true, - SilenceErrors: true, - TraverseChildren: true, - PersistentPreRunE: preRunE, - RunE: registry.SubCommandExists, - Version: version.Version, - } - - logLevels = entities.NewStringSet("debug", "info", "warn", "error", "fatal", "panic") - logLevel = "error" - useSyslog bool -) - -func init() { - // Override default --help information of `--version` global flag} - var dummyVersion bool - // TODO had to disable shorthand -v for version due to -v rm with volume - rootCmd.PersistentFlags().BoolVar(&dummyVersion, "version", false, "Version of Podman") - rootCmd.PersistentFlags().StringVarP(®istry.EngineOptions.Uri, "remote", "r", "", "URL to access Podman service") - rootCmd.PersistentFlags().StringSliceVar(®istry.EngineOptions.Identities, "identity", []string{}, "path to SSH identity file") - rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "error", fmt.Sprintf("Log messages above specified level (%s)", logLevels.String())) - rootCmd.PersistentFlags().BoolVar(&useSyslog, "syslog", false, "Output logging information to syslog as well as the console (default false)") - - cobra.OnInitialize( - logging, - syslogHook, - ) -} - -func preRunE(cmd *cobra.Command, args []string) error { - cmd.SetHelpTemplate(registry.HelpTemplate()) - cmd.SetUsageTemplate(registry.UsageTemplate()) - return nil -} - -func logging() { - if !logLevels.Contains(logLevel) { - fmt.Fprintf(os.Stderr, "Log Level \"%s\" is not supported, choose from: %s\n", logLevel, logLevels.String()) - os.Exit(1) - } - - level, err := logrus.ParseLevel(logLevel) - if err != nil { - fmt.Fprintf(os.Stderr, err.Error()) - os.Exit(1) - } - logrus.SetLevel(level) - - if logrus.IsLevelEnabled(logrus.InfoLevel) { - logrus.Infof("%s filtering at log level %s", os.Args[0], logrus.GetLevel()) - } -} - -func syslogHook() { - if useSyslog { - hook, err := logrusSyslog.NewSyslogHook("", "", syslog.LOG_INFO, "") - if err != nil { - logrus.WithError(err).Error("Failed to initialize syslog hook") - } - if err == nil { - logrus.AddHook(hook) - } - } -} - -func Execute() { - o := registry.NewOptions(rootCmd.Context(), ®istry.EngineOptions) - if err := rootCmd.ExecuteContext(o); err != nil { - fmt.Fprintln(os.Stderr, "Error:", err.Error()) - } else if registry.GetExitCode() == registry.ExecErrorCodeGeneric { - // The exitCode modified from registry.ExecErrorCodeGeneric, - // indicates an application - // running inside of a container failed, as opposed to the - // podman command failed. Must exit with that exit code - // otherwise command exited correctly. - registry.SetExitCode(0) - } - os.Exit(registry.GetExitCode()) -} diff --git a/cmd/podmanV2/system/system.go b/cmd/podmanV2/system/system.go deleted file mode 100644 index 4e805c7bd..000000000 --- a/cmd/podmanV2/system/system.go +++ /dev/null @@ -1,33 +0,0 @@ -package system - -import ( - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - // Command: podman _system_ - cmd = &cobra.Command{ - Use: "system", - Short: "Manage podman", - Long: "Manage podman", - TraverseChildren: true, - PersistentPreRunE: preRunE, - RunE: registry.SubCommandExists, - } -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: cmd, - }) - cmd.SetHelpTemplate(registry.HelpTemplate()) - cmd.SetUsageTemplate(registry.UsageTemplate()) -} - -func preRunE(cmd *cobra.Command, args []string) error { - _, err := registry.NewContainerEngine(cmd, args) - return err -} diff --git a/cmd/podmanV2/system/version.go b/cmd/podmanV2/system/version.go deleted file mode 100644 index e8002056b..000000000 --- a/cmd/podmanV2/system/version.go +++ /dev/null @@ -1,119 +0,0 @@ -package system - -import ( - "fmt" - "io" - "os" - "strings" - "text/tabwriter" - "time" - - "github.com/containers/buildah/pkg/formats" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/libpod/define" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - versionCommand = &cobra.Command{ - Use: "version", - Args: cobra.NoArgs, - Short: "Display the Podman Version Information", - RunE: version, - PersistentPreRunE: preRunE, - } - format string -) - -type versionStruct struct { - Client define.Version - Server define.Version -} - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: versionCommand, - }) - flags := versionCommand.Flags() - flags.StringVarP(&format, "format", "f", "", "Change the output format to JSON or a Go template") -} - -func version(cmd *cobra.Command, args []string) error { - var ( - v versionStruct - err error - ) - v.Client, err = define.GetVersion() - if err != nil { - return errors.Wrapf(err, "unable to determine version") - } - // TODO we need to discuss how to implement - // this more. current endpoints dont have a - // version endpoint. maybe we use info? - //if remote { - // v.Server, err = getRemoteVersion(c) - // if err != nil { - // return err - // } - //} else { - v.Server = v.Client - //} - - versionOutputFormat := format - if versionOutputFormat != "" { - if strings.Join(strings.Fields(versionOutputFormat), "") == "{{json.}}" { - versionOutputFormat = formats.JSONString - } - var out formats.Writer - switch versionOutputFormat { - case formats.JSONString: - out = formats.JSONStruct{Output: v} - return out.Out() - default: - out = formats.StdoutTemplate{Output: v, Template: versionOutputFormat} - err := out.Out() - if err != nil { - // On Failure, assume user is using older version of podman version --format and check client - out = formats.StdoutTemplate{Output: v.Client, Template: versionOutputFormat} - if err1 := out.Out(); err1 != nil { - return err - } - } - } - return nil - } - w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) - defer w.Flush() - - if registry.IsRemote() { - if _, err := fmt.Fprintf(w, "Client:\n"); err != nil { - return err - } - formatVersion(w, v.Client) - if _, err := fmt.Fprintf(w, "\nServer:\n"); err != nil { - return err - } - formatVersion(w, v.Server) - } else { - formatVersion(w, v.Client) - } - return nil -} - -func formatVersion(writer io.Writer, version define.Version) { - fmt.Fprintf(writer, "Version:\t%s\n", version.Version) - fmt.Fprintf(writer, "RemoteAPI Version:\t%d\n", version.RemoteAPIVersion) - fmt.Fprintf(writer, "Go Version:\t%s\n", version.GoVersion) - if version.GitCommit != "" { - fmt.Fprintf(writer, "Git Commit:\t%s\n", version.GitCommit) - } - // Prints out the build time in readable format - if version.Built != 0 { - fmt.Fprintf(writer, "Built:\t%s\n", time.Unix(version.Built, 0).Format(time.ANSIC)) - } - - fmt.Fprintf(writer, "OS/Arch:\t%s\n", version.OsArch) -} diff --git a/cmd/podmanV2/utils/alias.go b/cmd/podmanV2/utils/alias.go deleted file mode 100644 index 54b3c5e89..000000000 --- a/cmd/podmanV2/utils/alias.go +++ /dev/null @@ -1,24 +0,0 @@ -package utils - -import "github.com/spf13/pflag" - -// AliasFlags is a function to handle backwards compatability with old flags -func AliasFlags(f *pflag.FlagSet, name string) pflag.NormalizedName { - switch name { - case "healthcheck-command": - name = "health-cmd" - case "healthcheck-interval": - name = "health-interval" - case "healthcheck-retries": - name = "health-retries" - case "healthcheck-start-period": - name = "health-start-period" - case "healthcheck-timeout": - name = "health-timeout" - case "net": - name = "network" - case "timeout": - name = "time" - } - return pflag.NormalizedName(name) -} diff --git a/cmd/podmanV2/utils/error.go b/cmd/podmanV2/utils/error.go deleted file mode 100644 index 3464f0779..000000000 --- a/cmd/podmanV2/utils/error.go +++ /dev/null @@ -1,16 +0,0 @@ -package utils - -import "fmt" - -type OutputErrors []error - -func (o OutputErrors) PrintErrors() (lastError error) { - if len(o) == 0 { - return - } - lastError = o[len(o)-1] - for e := 0; e < len(o)-1; e++ { - fmt.Println(o[e]) - } - return -} diff --git a/cmd/podmanV2/volumes/create.go b/cmd/podmanV2/volumes/create.go deleted file mode 100644 index 91181dd03..000000000 --- a/cmd/podmanV2/volumes/create.go +++ /dev/null @@ -1,72 +0,0 @@ -package volumes - -import ( - "context" - "fmt" - - "github.com/containers/libpod/cmd/podmanV2/parse" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - createDescription = `If using the default driver, "local", the volume will be created on the host in the volumes directory under container storage.` - - createCommand = &cobra.Command{ - Use: "create [flags] [NAME]", - Short: "Create a new volume", - Long: createDescription, - RunE: create, - Example: `podman volume create myvol - podman volume create - podman volume create --label foo=bar myvol`, - } -) - -var ( - createOpts = entities.VolumeCreateOptions{} - opts = struct { - Label []string - Opts []string - }{} -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: createCommand, - Parent: volumeCmd, - }) - flags := createCommand.Flags() - flags.StringVar(&createOpts.Driver, "driver", "", "Specify volume driver name (default local)") - flags.StringSliceVarP(&opts.Label, "label", "l", []string{}, "Set metadata for a volume (default [])") - flags.StringArrayVarP(&opts.Opts, "opt", "o", []string{}, "Set driver specific options (default [])") -} - -func create(cmd *cobra.Command, args []string) error { - var ( - err error - ) - if len(args) > 1 { - return errors.Errorf("too many arguments, create takes at most 1 argument") - } - if len(args) > 0 { - createOpts.Name = args[0] - } - createOpts.Label, err = parse.GetAllLabels([]string{}, opts.Label) - if err != nil { - return errors.Wrapf(err, "unable to process labels") - } - createOpts.Options, err = parse.GetAllLabels([]string{}, opts.Opts) - if err != nil { - return errors.Wrapf(err, "unable to process options") - } - response, err := registry.ContainerEngine().VolumeCreate(context.Background(), createOpts) - if err != nil { - return err - } - fmt.Println(response.IdOrName) - return nil -} diff --git a/cmd/podmanV2/volumes/inspect.go b/cmd/podmanV2/volumes/inspect.go deleted file mode 100644 index 4d9720432..000000000 --- a/cmd/podmanV2/volumes/inspect.go +++ /dev/null @@ -1,74 +0,0 @@ -package volumes - -import ( - "encoding/json" - "fmt" - "html/template" - "os" - - "github.com/containers/buildah/pkg/formats" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/pkg/errors" - "github.com/spf13/cobra" - "golang.org/x/net/context" -) - -var ( - volumeInspectDescription = `Display detailed information on one or more volumes. - - Use a Go template to change the format from JSON.` - inspectCommand = &cobra.Command{ - Use: "inspect [flags] VOLUME [VOLUME...]", - Short: "Display detailed information on one or more volumes", - Long: volumeInspectDescription, - RunE: inspect, - Example: `podman volume inspect myvol - podman volume inspect --all - podman volume inspect --format "{{.Driver}} {{.Scope}}" myvol`, - } -) - -var ( - inspectOpts = entities.VolumeInspectOptions{} - inspectFormat string -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: inspectCommand, - Parent: volumeCmd, - }) - flags := inspectCommand.Flags() - flags.BoolVarP(&inspectOpts.All, "all", "a", false, "Inspect all volumes") - flags.StringVarP(&inspectFormat, "format", "f", "json", "Format volume output using Go template") -} - -func inspect(cmd *cobra.Command, args []string) error { - if (inspectOpts.All && len(args) > 0) || (!inspectOpts.All && len(args) < 1) { - return errors.New("provide one or more volume names or use --all") - } - responses, err := registry.ContainerEngine().VolumeInspect(context.Background(), args, inspectOpts) - if err != nil { - return err - } - switch inspectFormat { - case "", formats.JSONString: - jsonOut, err := json.MarshalIndent(responses, "", " ") - if err != nil { - return errors.Wrapf(err, "error marshalling inspect JSON") - } - fmt.Println(string(jsonOut)) - default: - tmpl, err := template.New("volumeInspect").Parse(inspectFormat) - if err != nil { - return err - } - if err := tmpl.Execute(os.Stdout, responses); err != nil { - return err - } - } - return nil - -} diff --git a/cmd/podmanV2/volumes/list.go b/cmd/podmanV2/volumes/list.go deleted file mode 100644 index c38f78c73..000000000 --- a/cmd/podmanV2/volumes/list.go +++ /dev/null @@ -1,98 +0,0 @@ -package volumes - -import ( - "context" - "html/template" - "io" - "os" - "strings" - "text/tabwriter" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - volumeLsDescription = ` -podman volume ls - -List all available volumes. The output of the volumes can be filtered -and the output format can be changed to JSON or a user specified Go template.` - lsCommand = &cobra.Command{ - Use: "ls", - Aliases: []string{"list"}, - Args: cobra.NoArgs, - Short: "List volumes", - Long: volumeLsDescription, - RunE: list, - } -) - -var ( - // Temporary struct to hold cli values. - cliOpts = struct { - Filter []string - Format string - Quiet bool - }{} - lsOpts = entities.VolumeListOptions{} -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: lsCommand, - Parent: volumeCmd, - }) - flags := lsCommand.Flags() - flags.StringSliceVarP(&cliOpts.Filter, "filter", "f", []string{}, "Filter volume output") - flags.StringVar(&cliOpts.Format, "format", "{{.Driver}}\t{{.Name}}\n", "Format volume output using Go template") - flags.BoolVarP(&cliOpts.Quiet, "quiet", "q", false, "Print volume output in quiet mode") -} - -func list(cmd *cobra.Command, args []string) error { - var w io.Writer = os.Stdout - if cliOpts.Quiet && cmd.Flag("format").Changed { - return errors.New("quiet and format flags cannot be used together") - } - for _, f := range cliOpts.Filter { - filterSplit := strings.Split(f, "=") - if len(filterSplit) < 2 { - return errors.Errorf("filter input must be in the form of filter=value: %s is invalid", f) - } - lsOpts.Filter[filterSplit[0]] = append(lsOpts.Filter[filterSplit[0]], filterSplit[1:]...) - } - responses, err := registry.ContainerEngine().VolumeList(context.Background(), lsOpts) - if err != nil { - return err - } - // "\t" from the command line is not being recognized as a tab - // replacing the string "\t" to a tab character if the user passes in "\t" - cliOpts.Format = strings.Replace(cliOpts.Format, `\t`, "\t", -1) - if cliOpts.Quiet { - cliOpts.Format = "{{.Name}}\n" - } - headers := "DRIVER\tVOLUME NAME\n" - row := cliOpts.Format - if !strings.HasSuffix(cliOpts.Format, "\n") { - row += "\n" - } - format := "{{range . }}" + row + "{{end}}" - if !cliOpts.Quiet && !cmd.Flag("format").Changed { - w = tabwriter.NewWriter(os.Stdout, 12, 2, 2, ' ', 0) - format = headers + format - } - tmpl, err := template.New("listVolume").Parse(format) - if err != nil { - return err - } - if err := tmpl.Execute(w, responses); err != nil { - return err - } - if flusher, ok := w.(interface{ Flush() error }); ok { - return flusher.Flush() - } - return nil -} diff --git a/cmd/podmanV2/volumes/prune.go b/cmd/podmanV2/volumes/prune.go deleted file mode 100644 index 148065f56..000000000 --- a/cmd/podmanV2/volumes/prune.go +++ /dev/null @@ -1,74 +0,0 @@ -package volumes - -import ( - "bufio" - "context" - "fmt" - "os" - "strings" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/cmd/podmanV2/utils" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - volumePruneDescription = `Volumes that are not currently owned by a container will be removed. - - The command prompts for confirmation which can be overridden with the --force flag. - Note all data will be destroyed.` - pruneCommand = &cobra.Command{ - Use: "prune", - Args: cobra.NoArgs, - Short: "Remove all unused volumes", - Long: volumePruneDescription, - RunE: prune, - } -) - -var ( - pruneOptions entities.VolumePruneOptions -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: pruneCommand, - Parent: volumeCmd, - }) - flags := pruneCommand.Flags() - flags.BoolVarP(&pruneOptions.Force, "force", "f", false, "Do not prompt for confirmation") -} - -func prune(cmd *cobra.Command, args []string) error { - var ( - errs utils.OutputErrors - ) - // Prompt for confirmation if --force is not set - if !pruneOptions.Force { - reader := bufio.NewReader(os.Stdin) - fmt.Println("WARNING! This will remove all volumes not used by at least one container.") - fmt.Print("Are you sure you want to continue? [y/N] ") - answer, err := reader.ReadString('\n') - if err != nil { - return errors.Wrapf(err, "error reading input") - } - if strings.ToLower(answer)[0] != 'y' { - return nil - } - } - responses, err := registry.ContainerEngine().VolumePrune(context.Background(), pruneOptions) - if err != nil { - return err - } - for _, r := range responses { - if r.Err == nil { - fmt.Println(r.Id) - } else { - errs = append(errs, r.Err) - } - } - return errs.PrintErrors() -} diff --git a/cmd/podmanV2/volumes/rm.go b/cmd/podmanV2/volumes/rm.go deleted file mode 100644 index b019285d8..000000000 --- a/cmd/podmanV2/volumes/rm.go +++ /dev/null @@ -1,64 +0,0 @@ -package volumes - -import ( - "context" - "fmt" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/cmd/podmanV2/utils" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - volumeRmDescription = `Remove one or more existing volumes. - - By default only volumes that are not being used by any containers will be removed. To remove the volumes anyways, use the --force flag.` - rmCommand = &cobra.Command{ - Use: "rm [flags] VOLUME [VOLUME...]", - Aliases: []string{"remove"}, - Short: "Remove one or more volumes", - Long: volumeRmDescription, - RunE: rm, - Example: `podman volume rm myvol1 myvol2 - podman volume rm --all - podman volume rm --force myvol`, - } -) - -var ( - rmOptions = entities.VolumeRmOptions{} -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: rmCommand, - Parent: volumeCmd, - }) - flags := rmCommand.Flags() - flags.BoolVarP(&rmOptions.All, "all", "a", false, "Remove all volumes") - flags.BoolVarP(&rmOptions.Force, "force", "f", false, "Remove a volume by force, even if it is being used by a container") -} - -func rm(cmd *cobra.Command, args []string) error { - var ( - errs utils.OutputErrors - ) - if (len(args) > 0 && rmOptions.All) || (len(args) < 1 && !rmOptions.All) { - return errors.New("choose either one or more volumes or all") - } - responses, err := registry.ContainerEngine().VolumeRm(context.Background(), args, rmOptions) - if err != nil { - return err - } - for _, r := range responses { - if r.Err == nil { - fmt.Println(r.Id) - } else { - errs = append(errs, r.Err) - } - } - return errs.PrintErrors() -} diff --git a/cmd/podmanV2/volumes/volume.go b/cmd/podmanV2/volumes/volume.go deleted file mode 100644 index 84abe3d24..000000000 --- a/cmd/podmanV2/volumes/volume.go +++ /dev/null @@ -1,33 +0,0 @@ -package volumes - -import ( - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - // Command: podman _volume_ - volumeCmd = &cobra.Command{ - Use: "volume", - Short: "Manage volumes", - Long: "Volumes are created in and can be shared between containers", - TraverseChildren: true, - PersistentPreRunE: preRunE, - RunE: registry.SubCommandExists, - } -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: volumeCmd, - }) - volumeCmd.SetHelpTemplate(registry.HelpTemplate()) - volumeCmd.SetUsageTemplate(registry.UsageTemplate()) -} - -func preRunE(cmd *cobra.Command, args []string) error { - _, err := registry.NewContainerEngine(cmd, args) - return err -} |