aboutsummaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container.go2
-rw-r--r--libpod/container_exec.go16
-rw-r--r--libpod/container_inspect.go3
-rw-r--r--libpod/container_internal_linux.go48
-rw-r--r--libpod/networking_linux.go10
-rw-r--r--libpod/options.go5
6 files changed, 71 insertions, 13 deletions
diff --git a/libpod/container.go b/libpod/container.go
index 9841bddf7..ee6e243ac 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -236,6 +236,8 @@ type ContainerOverlayVolume struct {
Dest string `json:"dest"`
// Source specifies the source path of the mount.
Source string `json:"source,omitempty"`
+ // Options holds overlay volume options.
+ Options []string `json:"options,omitempty"`
}
// ContainerImageVolume is a volume based on a container image. The container
diff --git a/libpod/container_exec.go b/libpod/container_exec.go
index 7b1d797bb..8d63ef90f 100644
--- a/libpod/container_exec.go
+++ b/libpod/container_exec.go
@@ -954,18 +954,22 @@ func (c *Container) removeAllExecSessions() error {
}
// Delete all exec sessions
if err := c.runtime.state.RemoveContainerExecSessions(c); err != nil {
- if lastErr != nil {
- logrus.Errorf("Error stopping container %s exec sessions: %v", c.ID(), lastErr)
+ if errors.Cause(err) != define.ErrCtrRemoved {
+ if lastErr != nil {
+ logrus.Errorf("Error stopping container %s exec sessions: %v", c.ID(), lastErr)
+ }
+ lastErr = err
}
- lastErr = err
}
c.state.ExecSessions = nil
c.state.LegacyExecSessions = nil
if err := c.save(); err != nil {
- if lastErr != nil {
- logrus.Errorf("Error stopping container %s exec sessions: %v", c.ID(), lastErr)
+ if errors.Cause(err) != define.ErrCtrRemoved {
+ if lastErr != nil {
+ logrus.Errorf("Error stopping container %s exec sessions: %v", c.ID(), lastErr)
+ }
+ lastErr = err
}
- lastErr = err
}
return lastErr
diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go
index 399eff845..e0569e2d4 100644
--- a/libpod/container_inspect.go
+++ b/libpod/container_inspect.go
@@ -2,6 +2,7 @@ package libpod
import (
"fmt"
+ "sort"
"strings"
"github.com/containers/common/pkg/config"
@@ -698,6 +699,8 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named
for cap := range boundingCaps {
capDrop = append(capDrop, cap)
}
+ // Sort CapDrop so it displays in consistent order (GH #9490)
+ sort.Strings(capDrop)
}
hostConfig.CapAdd = capAdd
hostConfig.CapDrop = capDrop
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 43a345ea9..dc0418148 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -23,7 +23,9 @@ import (
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containers/buildah/pkg/chrootuser"
"github.com/containers/buildah/pkg/overlay"
+ butil "github.com/containers/buildah/util"
"github.com/containers/common/pkg/apparmor"
+ "github.com/containers/common/pkg/chown"
"github.com/containers/common/pkg/config"
"github.com/containers/common/pkg/subscriptions"
"github.com/containers/common/pkg/umask"
@@ -356,13 +358,28 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
return nil, err
}
- // Check if the spec file mounts contain the label Relabel flags z or Z.
- // If they do, relabel the source directory and then remove the option.
+ // Get host UID and GID based on the container process UID and GID.
+ hostUID, hostGID, err := butil.GetHostIDs(util.IDtoolsToRuntimeSpec(c.config.IDMappings.UIDMap), util.IDtoolsToRuntimeSpec(c.config.IDMappings.GIDMap), uint32(execUser.Uid), uint32(execUser.Gid))
+ if err != nil {
+ return nil, err
+ }
+
+ // Check if the spec file mounts contain the options z, Z or U.
+ // If they have z or Z, relabel the source directory and then remove the option.
+ // If they have U, chown the source directory and them remove the option.
for i := range g.Config.Mounts {
m := &g.Config.Mounts[i]
var options []string
for _, o := range m.Options {
switch o {
+ case "U":
+ if m.Type == "tmpfs" {
+ options = append(options, []string{fmt.Sprintf("uid=%d", execUser.Uid), fmt.Sprintf("gid=%d", execUser.Gid)}...)
+ } else {
+ if err := chown.ChangeHostPathOwnership(m.Source, true, int(hostUID), int(hostGID)); err != nil {
+ return nil, err
+ }
+ }
case "z":
fallthrough
case "Z":
@@ -427,6 +444,21 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
if err != nil {
return nil, errors.Wrapf(err, "mounting overlay failed %q", overlayVol.Source)
}
+
+ // Check overlay volume options
+ for _, o := range overlayVol.Options {
+ switch o {
+ case "U":
+ if err := chown.ChangeHostPathOwnership(overlayVol.Source, true, int(hostUID), int(hostGID)); err != nil {
+ return nil, err
+ }
+
+ if err := chown.ChangeHostPathOwnership(contentDir, true, int(hostUID), int(hostGID)); err != nil {
+ return nil, err
+ }
+ }
+ }
+
g.AddMount(overlayMount)
}
@@ -1681,8 +1713,9 @@ rootless=%d
// generateResolvConf generates a containers resolv.conf
func (c *Container) generateResolvConf() (string, error) {
var (
- nameservers []string
- cniNameServers []string
+ nameservers []string
+ cniNameServers []string
+ cniSearchDomains []string
)
resolvConf := "/etc/resolv.conf"
@@ -1734,6 +1767,10 @@ func (c *Container) generateResolvConf() (string, error) {
cniNameServers = append(cniNameServers, i.DNS.Nameservers...)
logrus.Debugf("adding nameserver(s) from cni response of '%q'", i.DNS.Nameservers)
}
+ if i.DNS.Search != nil {
+ cniSearchDomains = append(cniSearchDomains, i.DNS.Search...)
+ logrus.Debugf("adding search domain(s) from cni response of '%q'", i.DNS.Search)
+ }
}
dns := make([]net.IP, 0, len(c.runtime.config.Containers.DNSServers))
@@ -1765,10 +1802,11 @@ func (c *Container) generateResolvConf() (string, error) {
}
var search []string
- if len(c.config.DNSSearch) > 0 || len(c.runtime.config.Containers.DNSSearches) > 0 {
+ if len(c.config.DNSSearch) > 0 || len(c.runtime.config.Containers.DNSSearches) > 0 || len(cniSearchDomains) > 0 {
if !util.StringInSlice(".", c.config.DNSSearch) {
search = c.runtime.config.Containers.DNSSearches
search = append(search, c.config.DNSSearch...)
+ search = append(search, cniSearchDomains...)
}
} else {
search = resolvconf.GetSearchDomains(resolv.Content)
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go
index c1b2c694d..0526e646e 100644
--- a/libpod/networking_linux.go
+++ b/libpod/networking_linux.go
@@ -1134,6 +1134,11 @@ func (w *logrusDebugWriter) Write(p []byte) (int, error) {
// NetworkDisconnect removes a container from the network
func (c *Container) NetworkDisconnect(nameOrID, netName string, force bool) error {
+ // only the bridge mode supports cni networks
+ if !c.config.NetMode.IsBridge() {
+ return errors.Errorf("network mode %q is not supported", c.config.NetMode)
+ }
+
networks, err := c.networksByNameIndex()
if err != nil {
return err
@@ -1190,6 +1195,11 @@ func (c *Container) NetworkDisconnect(nameOrID, netName string, force bool) erro
// ConnectNetwork connects a container to a given network
func (c *Container) NetworkConnect(nameOrID, netName string, aliases []string) error {
+ // only the bridge mode supports cni networks
+ if !c.config.NetMode.IsBridge() {
+ return errors.Errorf("network mode %q is not supported", c.config.NetMode)
+ }
+
networks, err := c.networksByNameIndex()
if err != nil {
return err
diff --git a/libpod/options.go b/libpod/options.go
index 627ea8c57..6344e1acc 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -1429,8 +1429,9 @@ func WithOverlayVolumes(volumes []*ContainerOverlayVolume) CtrCreateOption {
for _, vol := range volumes {
ctr.config.OverlayVolumes = append(ctr.config.OverlayVolumes, &ContainerOverlayVolume{
- Dest: vol.Dest,
- Source: vol.Source,
+ Dest: vol.Dest,
+ Source: vol.Source,
+ Options: vol.Options,
})
}