summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--cmd/podman/build.go4
-rw-r--r--cmd/podman/ps.go4
-rw-r--r--docs/source/markdown/podman-ps.1.md1
-rw-r--r--libpod/container.go2
-rw-r--r--pkg/bindings/errors.go3
-rw-r--r--pkg/bindings/test/images_test.go35
-rw-r--r--pkg/specgen/specgen.go399
-rw-r--r--test/e2e/ps_test.go16
9 files changed, 458 insertions, 8 deletions
diff --git a/Makefile b/Makefile
index 6713b8bae..1e5aa4d77 100644
--- a/Makefile
+++ b/Makefile
@@ -596,7 +596,7 @@ validate.completions: completions/bash/podman
if [ -x /bin/zsh ]; then /bin/zsh completions/zsh/_podman; fi
.PHONY: validate
-validate: lint gofmt .gitvalidation validate.completions man-page-check
+validate: gofmt lint .gitvalidation validate.completions man-page-check
.PHONY: build-all-new-commits
build-all-new-commits:
diff --git a/cmd/podman/build.go b/cmd/podman/build.go
index 885f2ac51..1fcb98a0e 100644
--- a/cmd/podman/build.go
+++ b/cmd/podman/build.go
@@ -234,10 +234,6 @@ func buildCmd(c *cliconfig.BuildValues) error {
return errors.Wrapf(err, "error determining path to file %q", containerfiles[i])
}
contextDir = filepath.Dir(absFile)
- containerfiles[i], err = filepath.Rel(contextDir, absFile)
- if err != nil {
- return errors.Wrapf(err, "error determining path to file %q", containerfiles[i])
- }
break
}
}
diff --git a/cmd/podman/ps.go b/cmd/podman/ps.go
index d2c5e19e2..d93ccc24c 100644
--- a/cmd/podman/ps.go
+++ b/cmd/podman/ps.go
@@ -205,6 +205,10 @@ func checkFlagsPassed(c *cliconfig.PsValues) error {
if c.Last >= 0 && c.Latest {
return errors.Errorf("last and latest are mutually exclusive")
}
+ // Filter forces all
+ if len(c.Filter) > 0 {
+ c.All = true
+ }
// Quiet conflicts with size and namespace and is overridden by a Go
// template.
if c.Quiet {
diff --git a/docs/source/markdown/podman-ps.1.md b/docs/source/markdown/podman-ps.1.md
index 024b85ea5..23bf9f45d 100644
--- a/docs/source/markdown/podman-ps.1.md
+++ b/docs/source/markdown/podman-ps.1.md
@@ -96,6 +96,7 @@ Display namespace information
Filter what containers are shown in the output.
Multiple filters can be given with multiple uses of the --filter flag.
If multiple filters are given, only containers which match all of the given filters will be shown.
+Results will be drawn from all containers, regardless of whether --all was given.
Valid filters are listed below:
diff --git a/libpod/container.go b/libpod/container.go
index f29cebf20..5e5c8ab26 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -244,7 +244,7 @@ type ContainerConfig struct {
// UID/GID mappings used by the storage
IDMappings storage.IDMappingOptions `json:"idMappingsOptions,omitempty"`
- // Information on the image used for the root filesystem/
+ // Information on the image used for the root filesystem
RootfsImageID string `json:"rootfsImageID,omitempty"`
RootfsImageName string `json:"rootfsImageName,omitempty"`
// Rootfs to use for the container, this conflicts with RootfsImageID
diff --git a/pkg/bindings/errors.go b/pkg/bindings/errors.go
index 8bd40f804..1bcaac3f0 100644
--- a/pkg/bindings/errors.go
+++ b/pkg/bindings/errors.go
@@ -3,7 +3,6 @@ package bindings
import (
"encoding/json"
"io/ioutil"
- "net/http"
"github.com/containers/libpod/pkg/api/handlers/utils"
"github.com/pkg/errors"
@@ -26,7 +25,7 @@ func (a APIResponse) Process(unmarshalInto interface{}) error {
if err != nil {
return errors.Wrap(err, "unable to process API response")
}
- if a.Response.StatusCode == http.StatusOK {
+ if a.IsSuccess() {
if unmarshalInto != nil {
return json.Unmarshal(data, unmarshalInto)
}
diff --git a/pkg/bindings/test/images_test.go b/pkg/bindings/test/images_test.go
index 227f28d16..f2dc856b2 100644
--- a/pkg/bindings/test/images_test.go
+++ b/pkg/bindings/test/images_test.go
@@ -89,4 +89,39 @@ var _ = Describe("Podman images", func() {
})
+ //Tests to validate the image tag command.
+ It("tag image", func() {
+ // Validates if invalid image name is given a bad response is encountered.
+ err = images.Tag(connText, "dummy", "demo", "alpine")
+ Expect(err).ToNot(BeNil())
+ code, _ := bindings.CheckResponseCode(err)
+ Expect(code).To(BeNumerically("==", 404))
+
+ // Validates if the image is tagged sucessfully.
+ err = images.Tag(connText, "alpine", "demo", "alpine")
+ Expect(err).To(BeNil())
+
+ //Validates if name updates when the image is retagged.
+ _, err := images.GetImage(connText, "alpine:demo", nil)
+ Expect(err).To(BeNil())
+
+ })
+
+ //Test to validate the List images command.
+ It("List image", func() {
+ //Array to hold the list of images returned
+ imageSummary, err := images.List(connText, nil, nil)
+ //There Should be no errors in the response.
+ Expect(err).To(BeNil())
+ //Since in the begin context only one image is created the list context should have only one image
+ Expect(len(imageSummary)).To(Equal(1))
+
+ //To be written create a new image and check list count again
+ //imageSummary, err = images.List(connText, nil, nil)
+
+ //Since in the begin context only one image adding one more image should
+ ///Expect(len(imageSummary)).To(Equal(2)
+
+ })
+
})
diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go
new file mode 100644
index 000000000..e22ee598f
--- /dev/null
+++ b/pkg/specgen/specgen.go
@@ -0,0 +1,399 @@
+package specgen
+
+import (
+ "net"
+
+ "github.com/containers/image/v5/manifest"
+ "github.com/containers/libpod/libpod"
+ "github.com/containers/libpod/libpod/define"
+ "github.com/containers/storage"
+ "github.com/cri-o/ocicni/pkg/ocicni"
+ spec "github.com/opencontainers/runtime-spec/specs-go"
+)
+
+// TODO
+// mheon provided this an off the cuff suggestion. Adding it here to retain
+// for history as we implement it. When this struct is implemented, we need
+// to remove the nolints.
+type Namespace struct {
+ isHost bool //nolint
+ isPath string //nolint
+ isContainer string //nolint
+ isPod bool //nolint
+}
+
+// ContainerBasicConfig contains the basic parts of a container.
+type ContainerBasicConfig struct {
+ // Name is the name the container will be given.
+ // If no name is provided, one will be randomly generated.
+ // Optional.
+ Name string `json:"name,omitempty"`
+ // Pod is the ID of the pod the container will join.
+ // Optional.
+ Pod string `json:"pod,omitempty"`
+ // Entrypoint is the container's entrypoint.
+ // If not given and Image is specified, this will be populated by the
+ // image's configuration.
+ // Optional.
+ Entrypoint []string `json:"entrypoint,omitempty"`
+ // Command is the container's command.
+ // If not given and Image is specified, this will be populated by the
+ // image's configuration.
+ // Optional.
+ Command []string `json:"command,omitempty"`
+ // Env is a set of environment variables that will be set in the
+ // container.
+ // Optional.
+ Env map[string]string `json:"env,omitempty"`
+ // Terminal is whether the container will create a PTY.
+ Terminal bool `json:"terminal,omitempty"`
+ // Stdin is whether the container will keep its STDIN open.
+ Stdin bool `json:"stdin,omitempty"`
+ // Labels are key-valid labels that are used to add metadata to
+ // containers.
+ // Optional.
+ Labels map[string]string `json:"labels,omitempty"`
+ // Annotations are key-value options passed into the container runtime
+ // that can be used to trigger special behavior.
+ // Optional.
+ Annotations map[string]string `json:"annotations,omitempty"`
+ // StopSignal is the signal that will be used to stop the container.
+ // Must be a non-zero integer below SIGRTMAX.
+ // If not provided, the default, SIGTERM, will be used.
+ // Will conflict with Systemd if Systemd is set to "true" or "always".
+ // Optional.
+ StopSignal *uint `json:"stop_signal,omitempty"`
+ // StopTimeout is a timeout between the container's stop signal being
+ // sent and SIGKILL being sent.
+ // If not provided, the default will be used.
+ // If 0 is used, stop signal will not be sent, and SIGKILL will be sent
+ // instead.
+ // Optional.
+ StopTimeout *uint `json:"stop_timeout,omitempty"`
+ // LogDriver is the container's log driver.
+ // Optional.
+ LogDriver string `json:"log_driver,omitempty"`
+ // LogPath is the path the container's logs will be stored at.
+ // Only available if LogDriver is set to "json-file" or "k8s-file".
+ // Optional.
+ LogPath string `json:"log_path,omitempty"`
+ // ConmonPidFile is a path at which a PID file for Conmon will be
+ // placed.
+ // If not given, a default location will be used.
+ // Optional.
+ ConmonPidFile string `json:"conmon_pid_file,omitempty"`
+ // RestartPolicy is the container's restart policy - an action which
+ // will be taken when the container exits.
+ // If not given, the default policy, which does nothing, will be used.
+ // Optional.
+ RestartPolicy string `json:"restart_policy,omitempty"`
+ // RestartRetries is the number of attempts that will be made to restart
+ // the container.
+ // Only available when RestartPolicy is set to "on-failure".
+ // Optional.
+ RestartRetries *uint `json:"restart_tries,omitempty"`
+ // OCIRuntime is the name of the OCI runtime that will be used to create
+ // the container.
+ // If not specified, the default will be used.
+ // Optional.
+ OCIRuntime string `json:"oci_runtime,omitempty"`
+ // Systemd is whether the container will be started in systemd mode.
+ // Valid options are "true", "false", and "always".
+ // "true" enables this mode only if the binary run in the container is
+ // /sbin/init or systemd. "always" unconditionally enables systemd mode.
+ // "false" unconditionally disables systemd mode.
+ // If enabled, mounts and stop signal will be modified.
+ // If set to "always" or set to "true" and conditionally triggered,
+ // conflicts with StopSignal.
+ // If not specified, "false" will be assumed.
+ // Optional.
+ Systemd string `json:"systemd,omitempty"`
+ // Namespace is the libpod namespace the container will be placed in.
+ // Optional.
+ Namespace string `json:"namespace,omitempty"`
+
+ // PidNS is the container's PID namespace.
+ // It defaults to private.
+ // Mandatory.
+ PidNS Namespace `json:"pidns,omitempty"`
+
+ // UtsNS is the container's UTS namespace.
+ // It defaults to private.
+ // Must be set to Private to set Hostname.
+ // Mandatory.
+ UtsNS Namespace `json:"utsns,omitempty"`
+ // Hostname is the container's hostname. If not set, the hostname will
+ // not be modified (if UtsNS is not private) or will be set to the
+ // container ID (if UtsNS is private).
+ // Conflicts with UtsNS if UtsNS is not set to private.
+ // Optional.
+ Hostname string `json:"hostname,omitempty"`
+}
+
+// ContainerStorageConfig contains information on the storage configuration of a
+// container.
+type ContainerStorageConfig struct {
+ // Image is the image the container will be based on. The image will be
+ // used as the container's root filesystem, and its environment vars,
+ // volumes, and other configuration will be applied to the container.
+ // Conflicts with Rootfs.
+ // At least one of Image or Rootfs must be specified.
+ Image string `json:"image"`
+ // Rootfs is the path to a directory that will be used as the
+ // container's root filesystem. No modification will be made to the
+ // directory, it will be directly mounted into the container as root.
+ // Conflicts with Image.
+ // At least one of Image or Rootfs must be specified.
+ Rootfs string `json:"rootfs,omitempty"`
+ // ImageVolumeMode indicates how image volumes will be created.
+ // Supported modes are "ignore" (do not create), "tmpfs" (create as
+ // tmpfs), and "anonymous" (create as anonymous volumes).
+ // The default is anonymous.
+ // Optional.
+ ImageVolumeMode string `json:"image_volume_mode,omitempty"`
+ // VolumesFrom is a list of containers whose volumes will be added to
+ // this container. Supported mount options may be added after the
+ // container name with a : and include "ro" and "rw".
+ // Optional.
+ VolumesFrom []string `json:"volumes_from,omitempty"`
+ // Mounts are mounts that will be added to the container.
+ // These will supersede Image Volumes and VolumesFrom volumes where
+ // there are conflicts.
+ // Optional.
+ Mounts []spec.Mount `json:"mounts,omitempty"`
+ // Volumes are named volumes that will be added to the container.
+ // These will supersede Image Volumes and VolumesFrom volumes where
+ // there are conflicts.
+ // Optional.
+ Volumes []*libpod.ContainerNamedVolume `json:"volumes,omitempty"`
+ // Devices are devices that will be added to the container.
+ // Optional.
+ Devices []spec.LinuxDevice `json:"devices,omitempty"`
+ // IpcNS is the container's IPC namespace.
+ // Default is private.
+ // Conflicts with ShmSize if not set to private.
+ // Mandatory.
+ IpcNS Namespace `json:"ipcns,omitempty"`
+ // ShmSize is the size of the tmpfs to mount in at /dev/shm, in bytes.
+ // Conflicts with ShmSize if ShmSize is not private.
+ // Optional.
+ ShmSize *int64 `json:"shm_size,omitempty"`
+ // WorkDir is the container's working directory.
+ // If unset, the default, /, will be used.
+ // Optional.
+ WorkDir string `json:"work_dir,omitempty"`
+ // RootfsPropagation is the rootfs propagation mode for the container.
+ // If not set, the default of rslave will be used.
+ // Optional.
+ RootfsPropagation string `json:"rootfs_propagation,omitempty"`
+}
+
+// ContainerSecurityConfig is a container's security features, including
+// SELinux, Apparmor, and Seccomp.
+type ContainerSecurityConfig struct {
+ // Privileged is whether the container is privileged.
+ // Privileged does the following:
+ // - Adds all devices on the system to the container.
+ // - Adds all capabilities to the container.
+ // - Disables Seccomp, SELinux, and Apparmor confinement.
+ // TODO: this conflicts with things.
+ // TODO: this does more.
+ Privileged bool `json:"privileged,omitempty"`
+ // User is the user the container will be run as.
+ // Can be given as a UID or a username; if a username, it will be
+ // resolved within the container, using the container's /etc/passwd.
+ // If unset, the container will be run as root.
+ // Optional.
+ User string `json:"user,omitempty"`
+ // Groups are a list of supplemental groups the container's user will
+ // be granted access to.
+ // Optional.
+ Groups []string `json:"groups,omitempty"`
+ // CapAdd are capabilities which will be added to the container.
+ // Conflicts with Privileged.
+ // Optional.
+ CapAdd []string `json:"cap_add,omitempty"`
+ // CapDrop are capabilities which will be removed from the container.
+ // Conflicts with Privileged.
+ // Optional.
+ CapDrop []string `json:"cap_drop,omitempty"`
+ // SelinuxProcessLabel is the process label the container will use.
+ // If SELinux is enabled and this is not specified, a label will be
+ // automatically generated if not specified.
+ // Optional.
+ SelinuxProcessLabel string `json:"selinux_process_label,omitempty"`
+ // SelinuxMountLabel is the mount label the container will use.
+ // If SELinux is enabled and this is not specified, a label will be
+ // automatically generated if not specified.
+ // Optional.
+ SelinuxMountLabel string `json:"selinux_mount_label,omitempty"`
+ // SelinuxOpts are options for configuring SELinux.
+ // Optional.
+ SelinuxOpts []string `json:"selinux_opts,omitempty"`
+ // ApparmorProfile is the name of the Apparmor profile the container
+ // will use.
+ // Optional.
+ ApparmorProfile string `json:"apparmor_profile,omitempty"`
+ // SeccompProfilePath is the path to a JSON file containing the
+ // container's Seccomp profile.
+ // If not specified, no Seccomp profile will be used.
+ // Optional.
+ SeccompProfilePath string `json:"seccomp_profile_path,omitempty"`
+ // NoNewPrivileges is whether the container will set the no new
+ // privileges flag on create, which disables gaining additional
+ // privileges (e.g. via setuid) in the container.
+ NoNewPrivileges bool `json:"no_new_privileges,omitempty"`
+ // UserNS is the container's user namespace.
+ // It defaults to host, indicating that no user namespace will be
+ // created.
+ // If set to private, IDMappings must be set.
+ // Mandatory.
+ UserNS Namespace `json:"userns,omitempty"`
+ // IDMappings are UID and GID mappings that will be used by user
+ // namespaces.
+ // Required if UserNS is private.
+ IDMappings storage.IDMappingOptions `json:"idmappings,omitempty"`
+}
+
+// ContainerCgroupConfig contains configuration information about a container's
+// cgroups.
+type ContainerCgroupConfig struct {
+ // CgroupNS is the container's cgroup namespace.
+ // It defaults to private.
+ // Conflicts with NoCgroups if not set to host.
+ // Mandatory.
+ CgroupNS Namespace `json:"cgroupns,omitempty"`
+ // NoCgroups indicates that the container should not create CGroups.
+ // Conflicts with CgroupParent and CgroupNS if CgroupNS is not set to
+ // host.
+ NoCgroups bool `json:"no_cgroups,omitempty"`
+ // CgroupParent is the container's CGroup parent.
+ // If not set, the default for the current cgroup driver will be used.
+ // Conflicts with NoCgroups.
+ // Optional.
+ CgroupParent string `json:"cgroup_parent,omitempty"`
+}
+
+// ContainerNetworkConfig contains information on a container's network
+// configuration.
+type ContainerNetworkConfig struct {
+ // NetNS is the configuration to use for the container's network
+ // namespace.
+ // Mandatory.
+ NetNS Namespace `json:"netns,omitempty"`
+ // ConfigureNetNS is whether Libpod will configure the container's
+ // network namespace to send and receive traffic.
+ // Only available is NetNS is private - conflicts with other NetNS
+ // modes.
+ ConfigureNetNS bool `json:"configure_netns,omitempty"`
+ // StaticIP is the a IPv4 address of the container.
+ // Only available if ConfigureNetNS is true.
+ // Optional.
+ StaticIP *net.IP `json:"static_ip,omitempty"`
+ // StaticIPv6 is a static IPv6 address to set in the container.
+ // Only available if ConfigureNetNS is true.
+ // Optional.
+ StaticIPv6 *net.IP `json:"static_ipv6,omitempty"`
+ // StaticMAC is a static MAC address to set in the container.
+ // Only available if ConfigureNetNS is true.
+ // Optional.
+ StaticMAC *net.HardwareAddr `json:"static_mac,omitempty"`
+ // PortBindings is a set of ports to map into the container.
+ // Only available if ConfigureNetNS is true.
+ // Optional.
+ PortMappings []ocicni.PortMapping `json:"portmappings,omitempty"`
+ // PublishImagePorts will publish ports specified in the image to random
+ // ports outside.
+ // Requires Image to be set.
+ PublishImagePorts bool `json:"publish_image_ports,omitempty"`
+ // CNINetworks is a list of CNI networks to join the container to.
+ // If this list is empty, the default CNI network will be joined
+ // instead. If at least one entry is present, we will not join the
+ // default network (unless it is part of this list).
+ // Only available if ConfigureNetNS is true.
+ // Optional.
+ CNINetworks []string `json:"cni_networks,omitempty"`
+ // UseImageResolvConf indicates that resolv.conf should not be managed
+ // by Podman, but instead sourced from the image.
+ // Conflicts with DNSServer, DNSSearch, DNSOption.
+ UseImageResolvConf bool `json:"use_image_resolve_conf,omitempty"`
+ // DNSServer is a set of DNS servers that will be used in the
+ // container's resolv.conf, replacing the host's DNS Servers which are
+ // used by default.
+ // Conflicts with UseImageResolvConf.
+ // Optional.
+ DNSServer []net.IP `json:"dns_server,omitempty"`
+ // DNSSearch is a set of DNS search domains that will be used in the
+ // container's resolv.conf, replacing the host's DNS search domains
+ // which are used by default.
+ // Conflicts with UseImageResolvConf.
+ // Optional.
+ DNSSearch []string `json:"dns_search,omitempty"`
+ // DNSOption is a set of DNS options that will be used in the
+ // container's resolv.conf, replacing the host's DNS options which are
+ // used by default.
+ // Conflicts with UseImageResolvConf.
+ // Optional.
+ DNSOption []string `json:"dns_option,omitempty"`
+ // UseImageHosts indicates that /etc/hosts should not be managed by
+ // Podman, and instead sourced from the image.
+ // Conflicts with HostAdd.
+ UseImageHosts bool `json:"use_image_hosts,omitempty"`
+ // HostAdd is a set of hosts which will be added to the container's
+ // /etc/hosts file.
+ // Conflicts with UseImageHosts.
+ // Optional.
+ HostAdd []string `json:"hostadd,omitempty"`
+}
+
+// ContainerResourceConfig contains information on container resource limits.
+type ContainerResourceConfig struct {
+ // ResourceLimits are resource limits to apply to the container.
+ // Can only be set as root on cgroups v1 systems, but can be set as
+ // rootless as well for cgroups v2.
+ // Optional.
+ ResourceLimits *spec.LinuxResources `json:"resource_limits,omitempty"`
+ // Rlimits are POSIX rlimits to apply to the container.
+ // Optional.
+ Rlimits []spec.POSIXRlimit `json:"r_limits,omitempty"`
+ // OOMScoreAdj adjusts the score used by the OOM killer to determine
+ // processes to kill for the container's process.
+ // Optional.
+ OOMScoreAdj *int `json:"oom_score_adj,omitempty"`
+}
+
+// ContainerHealthCheckConfig describes a container healthcheck with attributes
+// like command, retries, interval, start period, and timeout.
+type ContainerHealthCheckConfig struct {
+ HealthConfig manifest.Schema2HealthConfig `json:"healthconfig,omitempty"`
+}
+
+// SpecGenerator creates an OCI spec and Libpod configuration options to create
+// a container based on the given configuration.
+type SpecGenerator struct {
+ ContainerBasicConfig
+ ContainerStorageConfig
+ ContainerSecurityConfig
+ ContainerCgroupConfig
+ ContainerNetworkConfig
+ ContainerResourceConfig
+ ContainerHealthCheckConfig
+}
+
+// NewSpecGenerator returns a SpecGenerator struct given one of two mandatory inputs
+func NewSpecGenerator(image, rootfs *string) (*SpecGenerator, error) {
+ _ = image
+ _ = rootfs
+ return &SpecGenerator{}, define.ErrNotImplemented
+}
+
+// Validate verifies that the given SpecGenerator is valid and satisfies required
+// input for creating a container.
+func (s *SpecGenerator) Validate() error {
+ return define.ErrNotImplemented
+}
+
+// MakeContainer creates a container based on the SpecGenerator
+func (s *SpecGenerator) MakeContainer() (*libpod.Container, error) {
+ return nil, define.ErrNotImplemented
+}
diff --git a/test/e2e/ps_test.go b/test/e2e/ps_test.go
index 12bfdfe41..fccc5c93b 100644
--- a/test/e2e/ps_test.go
+++ b/test/e2e/ps_test.go
@@ -227,6 +227,22 @@ var _ = Describe("Podman ps", func() {
Expect(output[0]).To(Equal(fullCid))
})
+ It("podman ps filter by exited does not need all", func() {
+ ctr := podmanTest.Podman([]string{"run", "-t", "-i", ALPINE, "ls", "/"})
+ ctr.WaitWithDefaultTimeout()
+ Expect(ctr.ExitCode()).To(Equal(0))
+
+ psAll := podmanTest.Podman([]string{"ps", "-aq", "--no-trunc"})
+ psAll.WaitWithDefaultTimeout()
+ Expect(psAll.ExitCode()).To(Equal(0))
+
+ psFilter := podmanTest.Podman([]string{"ps", "--no-trunc", "--quiet", "--filter", "status=exited"})
+ psFilter.WaitWithDefaultTimeout()
+ Expect(psFilter.ExitCode()).To(Equal(0))
+
+ Expect(psAll.OutputToString()).To(Equal(psFilter.OutputToString()))
+ })
+
It("podman ps mutually exclusive flags", func() {
session := podmanTest.Podman([]string{"ps", "-aqs"})
session.WaitWithDefaultTimeout()