summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/config/config.go2
-rw-r--r--libpod/container_api.go4
-rw-r--r--libpod/container_inspect.go4
-rw-r--r--libpod/container_internal.go2
-rw-r--r--libpod/container_validate.go99
-rw-r--r--libpod/image/filters.go2
-rw-r--r--libpod/networking_linux.go4
-rw-r--r--libpod/oci.go2
-rw-r--r--libpod/options.go87
-rw-r--r--libpod/runtime_ctr.go38
-rw-r--r--libpod/runtime_img.go10
-rw-r--r--libpod/runtime_pod_infra_linux.go2
-rw-r--r--libpod/storage.go2
13 files changed, 133 insertions, 125 deletions
diff --git a/libpod/config/config.go b/libpod/config/config.go
index c72a0efc7..5d59f1bf2 100644
--- a/libpod/config/config.go
+++ b/libpod/config/config.go
@@ -437,7 +437,7 @@ func probeConmon(conmonBinary string) error {
// with cgroupsv2. Other OCI runtimes are not yet supporting cgroupsv2. This
// might change in the future.
func NewConfig(userConfigPath string) (*Config, error) {
- // Start with the default config and interatively merge fields in the system
+ // Start with the default config and iteratively merge fields in the system
// configs.
config, err := defaultConfigFromMemory()
if err != nil {
diff --git a/libpod/container_api.go b/libpod/container_api.go
index aa932e0b8..039619ea6 100644
--- a/libpod/container_api.go
+++ b/libpod/container_api.go
@@ -9,9 +9,9 @@ import (
"os"
"time"
+ "github.com/containers/common/pkg/capabilities"
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/libpod/events"
- "github.com/containers/libpod/pkg/capabilities"
"github.com/containers/storage/pkg/stringid"
"github.com/opentracing/opentracing-go"
"github.com/pkg/errors"
@@ -395,7 +395,7 @@ func (c *Container) Attach(streams *AttachStreams, keys string, resize <-chan re
// HTTPAttach forwards an attach session over a hijacked HTTP session.
// HTTPAttach will consume and close the included httpCon, which is expected to
// be sourced from a hijacked HTTP connection.
-// The cancel channel is optional, and can be used to asyncronously cancel the
+// The cancel channel is optional, and can be used to asynchronously cancel the
// attach session.
// The streams variable is only supported if the container was not a terminal,
// and allows specifying which of the container's standard streams will be
diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go
index a543a19c0..50ae72499 100644
--- a/libpod/container_inspect.go
+++ b/libpod/container_inspect.go
@@ -670,8 +670,8 @@ type InspectAdditionalNetwork struct {
// DriverOpts is presently unused and maintained exclusively for
// compatibility.
DriverOpts map[string]string `json:"DriverOpts"`
- // IPAMConfig is presently unused and maintained exlusively for
- // compabitility.
+ // IPAMConfig is presently unused and maintained exclusively for
+ // compatibility.
IPAMConfig map[string]string `json:"IPAMConfig"`
// Links is presently unused and maintained exclusively for
// compatibility.
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index ff43bfc8f..a0805c1fa 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -951,7 +951,7 @@ func (c *Container) completeNetworkSetup() error {
return err
}
for _, line := range strings.Split(string(b), "\n") {
- // only keep things that dont start with nameserver from the old
+ // only keep things that don't start with nameserver from the old
// resolv.conf file
if !strings.HasPrefix(line, "nameserver") {
outResolvConf = append([]string{line}, outResolvConf...)
diff --git a/libpod/container_validate.go b/libpod/container_validate.go
new file mode 100644
index 000000000..b7f0aadff
--- /dev/null
+++ b/libpod/container_validate.go
@@ -0,0 +1,99 @@
+package libpod
+
+import (
+ "github.com/containers/libpod/libpod/define"
+ "github.com/containers/libpod/pkg/rootless"
+ spec "github.com/opencontainers/runtime-spec/specs-go"
+ "github.com/pkg/errors"
+)
+
+// Validate that the configuration of a container is valid.
+func (c *Container) validate() error {
+ imageIDSet := c.config.RootfsImageID != ""
+ imageNameSet := c.config.RootfsImageName != ""
+ rootfsSet := c.config.Rootfs != ""
+
+ // If one of RootfsImageIDor RootfsImageName are set, both must be set.
+ if (imageIDSet || imageNameSet) && !(imageIDSet && imageNameSet) {
+ return errors.Wrapf(define.ErrInvalidArg, "both RootfsImageName and RootfsImageID must be set if either is set")
+ }
+
+ // Cannot set RootfsImageID and Rootfs at the same time
+ if imageIDSet && rootfsSet {
+ return errors.Wrapf(define.ErrInvalidArg, "cannot set both an image ID and rootfs for a container")
+ }
+
+ // Must set at least one of RootfsImageID or Rootfs
+ if !(imageIDSet || rootfsSet) {
+ return errors.Wrapf(define.ErrInvalidArg, "must set root filesystem source to either image or rootfs")
+ }
+
+ // Cannot make a network namespace if we are joining another container's
+ // network namespace
+ if c.config.CreateNetNS && c.config.NetNsCtr != "" {
+ return errors.Wrapf(define.ErrInvalidArg, "cannot both create a network namespace and join another container's network namespace")
+ }
+
+ // Not creating cgroups has a number of requirements, mostly related to
+ // the PID namespace.
+ if c.config.NoCgroups || c.config.CgroupsMode == "disabled" {
+ if c.config.PIDNsCtr != "" {
+ return errors.Wrapf(define.ErrInvalidArg, "cannot join another container's PID namespace if not creating cgroups")
+ }
+
+ if c.config.CgroupParent != "" {
+ return errors.Wrapf(define.ErrInvalidArg, "cannot set cgroup parent if not creating cgroups")
+ }
+
+ // Ensure we have a PID namespace
+ if c.config.Spec.Linux == nil {
+ return errors.Wrapf(define.ErrInvalidArg, "must provide Linux namespace configuration in OCI spec when using NoCgroups")
+ }
+ foundPid := false
+ for _, ns := range c.config.Spec.Linux.Namespaces {
+ if ns.Type == spec.PIDNamespace {
+ foundPid = true
+ if ns.Path != "" {
+ return errors.Wrapf(define.ErrInvalidArg, "containers not creating CGroups must create a private PID namespace - cannot use another")
+ }
+ break
+ }
+ }
+ if !foundPid {
+ return errors.Wrapf(define.ErrInvalidArg, "containers not creating CGroups must create a private PID namespace")
+ }
+ }
+
+ // Rootless has some requirements, compared to networks.
+ if rootless.IsRootless() {
+ if len(c.config.Networks) > 0 {
+ return errors.Wrapf(define.ErrInvalidArg, "cannot join CNI networks if running rootless")
+ }
+
+ // TODO: Should we make sure network mode is set to Slirp if set
+ // at all?
+ }
+
+ // Can only set static IP or MAC is creating a network namespace.
+ if !c.config.CreateNetNS && (c.config.StaticIP != nil || c.config.StaticMAC != nil) {
+ return errors.Wrapf(define.ErrInvalidArg, "cannot set static IP or MAC address if not creating a network namespace")
+ }
+
+ // Cannot set static IP or MAC if joining >1 CNI network.
+ if len(c.config.Networks) > 1 && (c.config.StaticIP != nil || c.config.StaticMAC != nil) {
+ return errors.Wrapf(define.ErrInvalidArg, "cannot set static IP or MAC address if joining more than one CNI network")
+ }
+
+ // Using image resolv.conf conflicts with various DNS settings.
+ if c.config.UseImageResolvConf &&
+ (len(c.config.DNSSearch) > 0 || len(c.config.DNSServer) > 0 ||
+ len(c.config.DNSOption) > 0) {
+ return errors.Wrapf(define.ErrInvalidArg, "cannot configure DNS options if using image's resolv.conf")
+ }
+
+ if c.config.UseImageHosts && len(c.config.HostAdd) > 0 {
+ return errors.Wrapf(define.ErrInvalidArg, "cannot add to /etc/hosts if using image's /etc/hosts")
+ }
+
+ return nil
+}
diff --git a/libpod/image/filters.go b/libpod/image/filters.go
index c54ca6333..8ca3526a0 100644
--- a/libpod/image/filters.go
+++ b/libpod/image/filters.go
@@ -3,13 +3,13 @@ package image
import (
"context"
"fmt"
- "github.com/pkg/errors"
"path/filepath"
"strconv"
"strings"
"time"
"github.com/containers/libpod/pkg/inspect"
+ "github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go
index d57b1a8eb..5a27a2abb 100644
--- a/libpod/networking_linux.go
+++ b/libpod/networking_linux.go
@@ -117,10 +117,10 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) ([]*cnitypes.Re
networkStatus := make([]*cnitypes.Result, 0)
for idx, r := range results {
- logrus.Debugf("[%d] CNI result: %v", idx, r.Result.String())
+ logrus.Debugf("[%d] CNI result: %v", idx, r.Result)
resultCurrent, err := cnitypes.GetResult(r.Result)
if err != nil {
- return nil, errors.Wrapf(err, "error parsing CNI plugin result %q: %v", r.Result.String(), err)
+ return nil, errors.Wrapf(err, "error parsing CNI plugin result %q: %v", r.Result, err)
}
networkStatus = append(networkStatus, resultCurrent)
}
diff --git a/libpod/oci.go b/libpod/oci.go
index 2ea61851f..27edebefc 100644
--- a/libpod/oci.go
+++ b/libpod/oci.go
@@ -55,7 +55,7 @@ type OCIRuntime interface {
// to output; otherwise, STDOUT and STDERR will be multiplexed, with
// a header prepended as follows: 1-byte STREAM (0, 1, 2 for STDIN,
// STDOUT, STDERR), 3 null (0x00) bytes, 4-byte big endian length.
- // If a cancel channel is provided, it can be used to asyncronously
+ // If a cancel channel is provided, it can be used to asynchronously
// termninate the attach session. Detach keys, if given, will also cause
// the attach session to be terminated if provided via the STDIN
// channel. If they are not provided, the default detach keys will be
diff --git a/libpod/options.go b/libpod/options.go
index d01e8a85f..98de71af2 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -599,13 +599,6 @@ func WithRootFSFromImage(imageID string, imageName string) CtrCreateOption {
return define.ErrCtrFinalized
}
- if ctr.config.RootfsImageID != "" || ctr.config.RootfsImageName != "" {
- return errors.Wrapf(define.ErrInvalidArg, "container already configured with root filesystem")
- }
- if ctr.config.Rootfs != "" {
- return errors.Wrapf(define.ErrInvalidArg, "cannot set both an image ID and a rootfs for a container")
- }
-
ctr.config.RootfsImageID = imageID
ctr.config.RootfsImageName = imageName
@@ -815,10 +808,6 @@ func WithNetNSFrom(nsCtr *Container) CtrCreateOption {
return err
}
- if ctr.config.CreateNetNS {
- return errors.Wrapf(define.ErrInvalidArg, "cannot join another container's net ns as we are making a new net ns")
- }
-
ctr.config.NetNsCtr = nsCtr.ID()
return nil
@@ -839,10 +828,6 @@ func WithPIDNSFrom(nsCtr *Container) CtrCreateOption {
return err
}
- if ctr.config.NoCgroups {
- return errors.Wrapf(define.ErrInvalidArg, "container has disabled creation of CGroups, which is incompatible with sharing a PID namespace")
- }
-
ctr.config.PIDNsCtr = nsCtr.ID()
return nil
@@ -921,16 +906,8 @@ func WithDependencyCtrs(ctrs []*Container) CtrCreateOption {
deps := make([]string, 0, len(ctrs))
for _, dep := range ctrs {
- if !dep.valid {
- return errors.Wrapf(define.ErrCtrRemoved, "container %s is not valid", dep.ID())
- }
-
- if dep.ID() == ctr.ID() {
- return errors.Wrapf(define.ErrInvalidArg, "must specify another container")
- }
-
- if ctr.config.Pod != "" && dep.config.Pod != ctr.config.Pod {
- return errors.Wrapf(define.ErrInvalidArg, "container has joined pod %s and dependency container %s is not a member of the pod", ctr.config.Pod, dep.ID())
+ if err := checkDependencyContainer(dep, ctr); err != nil {
+ return err
}
deps = append(deps, dep.ID())
@@ -952,20 +929,6 @@ func WithNetNS(portMappings []ocicni.PortMapping, postConfigureNetNS bool, netmo
return define.ErrCtrFinalized
}
- if rootless.IsRootless() {
- if len(networks) > 0 {
- return errors.Wrapf(define.ErrInvalidArg, "cannot use CNI networks with rootless containers")
- }
- }
-
- if len(networks) > 1 && (ctr.config.StaticIP != nil || ctr.config.StaticMAC != nil) {
- return errors.Wrapf(define.ErrInvalidArg, "cannot join more than one CNI network if configuring a static IP or MAC address")
- }
-
- if ctr.config.NetNsCtr != "" {
- return errors.Wrapf(define.ErrInvalidArg, "container is already set to join another container's net ns, cannot create a new net ns")
- }
-
ctr.config.PostConfigureNetNS = postConfigureNetNS
ctr.config.NetMode = namespaces.NetworkMode(netmode)
ctr.config.CreateNetNS = true
@@ -988,14 +951,6 @@ func WithStaticIP(ip net.IP) CtrCreateOption {
return define.ErrCtrFinalized
}
- if !ctr.config.CreateNetNS {
- return errors.Wrapf(define.ErrInvalidArg, "cannot set a static IP if the container is not creating a network namespace")
- }
-
- if len(ctr.config.Networks) > 1 {
- return errors.Wrapf(define.ErrInvalidArg, "cannot set a static IP if joining more than 1 CNI network")
- }
-
ctr.config.StaticIP = ip
return nil
@@ -1013,14 +968,6 @@ func WithStaticMAC(mac net.HardwareAddr) CtrCreateOption {
return define.ErrCtrFinalized
}
- if !ctr.config.CreateNetNS {
- return errors.Wrapf(define.ErrInvalidArg, "cannot set a static MAC if the container is not creating a network namespace")
- }
-
- if len(ctr.config.Networks) > 1 {
- return errors.Wrapf(define.ErrInvalidArg, "cannot set a static MAC if joining more than 1 CNI network")
- }
-
ctr.config.StaticMAC = mac
return nil
@@ -1114,10 +1061,6 @@ func WithCgroupParent(parent string) CtrCreateOption {
return errors.Wrapf(define.ErrInvalidArg, "cgroup parent cannot be empty")
}
- if ctr.config.NoCgroups {
- return errors.Wrapf(define.ErrInvalidArg, "CgroupParent conflicts with NoCgroups")
- }
-
ctr.config.CgroupParent = parent
return nil
@@ -1130,9 +1073,6 @@ func WithDNSSearch(searchDomains []string) CtrCreateOption {
if ctr.valid {
return define.ErrCtrFinalized
}
- if ctr.config.UseImageResolvConf {
- return errors.Wrapf(define.ErrInvalidArg, "cannot add DNS search domains if container will not create /etc/resolv.conf")
- }
ctr.config.DNSSearch = searchDomains
return nil
}
@@ -1144,9 +1084,6 @@ func WithDNS(dnsServers []string) CtrCreateOption {
if ctr.valid {
return define.ErrCtrFinalized
}
- if ctr.config.UseImageResolvConf {
- return errors.Wrapf(define.ErrInvalidArg, "cannot add DNS servers if container will not create /etc/resolv.conf")
- }
var dns []net.IP
for _, i := range dnsServers {
result := net.ParseIP(i)
@@ -1166,9 +1103,6 @@ func WithDNSOption(dnsOptions []string) CtrCreateOption {
if ctr.valid {
return define.ErrCtrFinalized
}
- if ctr.config.UseImageResolvConf {
- return errors.Wrapf(define.ErrInvalidArg, "cannot add DNS options if container will not create /etc/resolv.conf")
- }
ctr.config.DNSOption = dnsOptions
return nil
}
@@ -1181,10 +1115,6 @@ func WithHosts(hosts []string) CtrCreateOption {
return define.ErrCtrFinalized
}
- if ctr.config.UseImageHosts {
- return errors.Wrapf(define.ErrInvalidArg, "cannot add hosts if container will not create /etc/hosts")
- }
-
ctr.config.HostAdd = hosts
return nil
}
@@ -1282,9 +1212,6 @@ func WithRootFS(rootfs string) CtrCreateOption {
if _, err := os.Stat(rootfs); err != nil {
return errors.Wrapf(err, "error checking path %q", rootfs)
}
- if ctr.config.RootfsImageID != "" {
- return errors.Wrapf(define.ErrInvalidArg, "cannot set both an image ID and a rootfs for a container")
- }
ctr.config.Rootfs = rootfs
return nil
}
@@ -1314,12 +1241,6 @@ func WithUseImageResolvConf() CtrCreateOption {
return define.ErrCtrFinalized
}
- if len(ctr.config.DNSServer) != 0 ||
- len(ctr.config.DNSSearch) != 0 ||
- len(ctr.config.DNSOption) != 0 {
- return errors.Wrapf(define.ErrInvalidArg, "not creating resolv.conf conflicts with DNS options")
- }
-
ctr.config.UseImageResolvConf = true
return nil
@@ -1334,10 +1255,6 @@ func WithUseImageHosts() CtrCreateOption {
return define.ErrCtrFinalized
}
- if len(ctr.config.HostAdd) != 0 {
- return errors.Wrapf(define.ErrInvalidArg, "not creating /etc/hosts conflicts with adding to the hosts file")
- }
-
ctr.config.UseImageHosts = true
return nil
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index 39284026c..ba2a6b93e 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -10,6 +10,7 @@ import (
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/libpod/events"
+ "github.com/containers/libpod/pkg/cgroups"
"github.com/containers/libpod/pkg/rootless"
"github.com/containers/storage/pkg/stringid"
spec "github.com/opencontainers/runtime-spec/specs-go"
@@ -133,7 +134,12 @@ func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options ..
return r.setupContainer(ctx, ctr)
}
-func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (c *Container, err error) {
+func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Container, err error) {
+ // Validate the container
+ if err := ctr.validate(); err != nil {
+ return nil, err
+ }
+
// Allocate a lock for the container
lock, err := r.lockManager.AllocateLock()
if err != nil {
@@ -190,27 +196,6 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (c *Contai
ctr.config.Name = name
}
- // If CGroups are disabled, we MUST create a PID namespace.
- // Otherwise, the OCI runtime won't be able to stop our container.
- if ctr.config.NoCgroups {
- if ctr.config.Spec.Linux == nil {
- return nil, errors.Wrapf(define.ErrInvalidArg, "must provide Linux namespace configuration in OCI spec when using NoCgroups")
- }
- foundPid := false
- for _, ns := range ctr.config.Spec.Linux.Namespaces {
- if ns.Type == spec.PIDNamespace {
- foundPid = true
- if ns.Path != "" {
- return nil, errors.Wrapf(define.ErrInvalidArg, "containers not creating CGroups must create a private PID namespace - cannot use another")
- }
- break
- }
- }
- if !foundPid {
- return nil, errors.Wrapf(define.ErrInvalidArg, "containers not creating CGroups must create a private PID namespace")
- }
- }
-
// Check CGroup parent sanity, and set it if it was not set.
// Only if we're actually configuring CGroups.
if !ctr.config.NoCgroups {
@@ -454,9 +439,16 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force bool,
if err := c.ociRuntime.KillContainer(c, 9, false); err != nil {
return err
}
- if err := c.unpause(); err != nil {
+ isV2, err := cgroups.IsCgroup2UnifiedMode()
+ if err != nil {
return err
}
+ // cgroups v1 and v2 handle signals on paused processes differently
+ if !isV2 {
+ if err := c.unpause(); err != nil {
+ return err
+ }
+ }
// Need to update container state to make sure we know it's stopped
if err := c.waitForExitFileAndSync(); err != nil {
return err
diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go
index bae1c1ed8..6ac32878b 100644
--- a/libpod/runtime_img.go
+++ b/libpod/runtime_img.go
@@ -21,7 +21,7 @@ import (
"github.com/containers/image/v5/directory"
dockerarchive "github.com/containers/image/v5/docker/archive"
ociarchive "github.com/containers/image/v5/oci/archive"
- "github.com/opencontainers/image-spec/specs-go/v1"
+ v1 "github.com/opencontainers/image-spec/specs-go/v1"
)
// Runtime API
@@ -209,11 +209,11 @@ func (r *Runtime) Import(ctx context.Context, source string, reference string, c
}
// donwloadFromURL downloads an image in the format "https:/example.com/myimage.tar"
-// and temporarily saves in it /var/tmp/importxyz, which is deleted after the image is imported
+// and temporarily saves in it $TMPDIR/importxyz, which is deleted after the image is imported
func downloadFromURL(source string) (string, error) {
fmt.Printf("Downloading from %q\n", source)
- outFile, err := ioutil.TempFile("/var/tmp", "import")
+ outFile, err := ioutil.TempFile(util.Tmpdir(), "import")
if err != nil {
return "", errors.Wrap(err, "error creating file")
}
@@ -234,9 +234,9 @@ func downloadFromURL(source string) (string, error) {
}
// DownloadFromFile reads all of the content from the reader and temporarily
-// saves in it /var/tmp/importxyz, which is deleted after the image is imported
+// saves in it $TMPDIR/importxyz, which is deleted after the image is imported
func DownloadFromFile(reader *os.File) (string, error) {
- outFile, err := ioutil.TempFile("/var/tmp", "import")
+ outFile, err := ioutil.TempFile(util.Tmpdir(), "import")
if err != nil {
return "", errors.Wrap(err, "error creating file")
}
diff --git a/libpod/runtime_pod_infra_linux.go b/libpod/runtime_pod_infra_linux.go
index da46f03e8..27735a9b2 100644
--- a/libpod/runtime_pod_infra_linux.go
+++ b/libpod/runtime_pod_infra_linux.go
@@ -10,7 +10,7 @@ import (
"github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/rootless"
"github.com/containers/libpod/pkg/util"
- "github.com/opencontainers/image-spec/specs-go/v1"
+ v1 "github.com/opencontainers/image-spec/specs-go/v1"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate"
"github.com/pkg/errors"
diff --git a/libpod/storage.go b/libpod/storage.go
index 6375d031b..d675f4ffe 100644
--- a/libpod/storage.go
+++ b/libpod/storage.go
@@ -8,7 +8,7 @@ import (
"github.com/containers/image/v5/types"
"github.com/containers/libpod/libpod/define"
"github.com/containers/storage"
- "github.com/opencontainers/image-spec/specs-go/v1"
+ v1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/opentracing/opentracing-go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"