summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
authorDoug Rabson <dfr@rabson.org>2022-08-27 13:15:05 +0100
committerDoug Rabson <dfr@rabson.org>2022-09-05 10:17:49 +0100
commitc1a86a8c4cbd8be87dbf11277aee055b89c8519a (patch)
treede893136d0757ff6a6a581a66a8b51b37af45b2e /libpod
parente101f4350bdbaad6a70669977a0a254b1bfcb1d3 (diff)
downloadpodman-c1a86a8c4cbd8be87dbf11277aee055b89c8519a.tar.gz
podman-c1a86a8c4cbd8be87dbf11277aee055b89c8519a.tar.bz2
podman-c1a86a8c4cbd8be87dbf11277aee055b89c8519a.zip
libpod: Factor out platform-specific sections from generateSpec
[NO NEW TESTS NEEDED] Signed-off-by: Doug Rabson <dfr@rabson.org>
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container_internal_common.go156
-rw-r--r--libpod/container_internal_freebsd.go82
-rw-r--r--libpod/container_internal_linux.go178
3 files changed, 266 insertions, 150 deletions
diff --git a/libpod/container_internal_common.go b/libpod/container_internal_common.go
index 50d7375cd..95d3c8ad8 100644
--- a/libpod/container_internal_common.go
+++ b/libpod/container_internal_common.go
@@ -89,16 +89,8 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
}
// If network namespace was requested, add it now
- if c.config.CreateNetNS {
- if c.config.PostConfigureNetNS {
- if err := g.AddOrReplaceLinuxNamespace(string(spec.NetworkNamespace), ""); err != nil {
- return nil, err
- }
- } else {
- if err := g.AddOrReplaceLinuxNamespace(string(spec.NetworkNamespace), c.state.NetNS.Path()); err != nil {
- return nil, err
- }
- }
+ if err := c.addNetworkNamespace(&g); err != nil {
+ return nil, err
}
// Apply AppArmor checks and load the default profile if needed.
@@ -222,8 +214,8 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
m.Options = options
}
- g.SetProcessSelinuxLabel(c.ProcessLabel())
- g.SetLinuxMountLabel(c.MountLabel())
+ c.setProcessLabel(&g)
+ c.setMountLabel(&g)
// Add bind mounts to container
for dstPath, srcPath := range c.state.BindMounts {
@@ -351,10 +343,8 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
}
}
- if c.Systemd() {
- if err := c.setupSystemd(g.Mounts(), g); err != nil {
- return nil, fmt.Errorf("error adding systemd-specific mounts: %w", err)
- }
+ if err := c.addSystemdMounts(&g); err != nil {
+ return nil, err
}
// Look up and add groups the user belongs to, if a group wasn't directly specified
@@ -400,106 +390,8 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
}
// Add shared namespaces from other containers
- if c.config.IPCNsCtr != "" {
- if err := c.addNamespaceContainer(&g, IPCNS, c.config.IPCNsCtr, spec.IPCNamespace); err != nil {
- return nil, err
- }
- }
- if c.config.MountNsCtr != "" {
- if err := c.addNamespaceContainer(&g, MountNS, c.config.MountNsCtr, spec.MountNamespace); err != nil {
- return nil, err
- }
- }
- if c.config.NetNsCtr != "" {
- if err := c.addNamespaceContainer(&g, NetNS, c.config.NetNsCtr, spec.NetworkNamespace); err != nil {
- return nil, err
- }
- }
- if c.config.PIDNsCtr != "" {
- if err := c.addNamespaceContainer(&g, PIDNS, c.config.PIDNsCtr, spec.PIDNamespace); err != nil {
- return nil, err
- }
- }
- if c.config.UserNsCtr != "" {
- if err := c.addNamespaceContainer(&g, UserNS, c.config.UserNsCtr, spec.UserNamespace); err != nil {
- return nil, err
- }
- if len(g.Config.Linux.UIDMappings) == 0 {
- // runc complains if no mapping is specified, even if we join another ns. So provide a dummy mapping
- g.AddLinuxUIDMapping(uint32(0), uint32(0), uint32(1))
- g.AddLinuxGIDMapping(uint32(0), uint32(0), uint32(1))
- }
- }
-
- availableUIDs, availableGIDs, err := rootless.GetAvailableIDMaps()
- if err != nil {
- if os.IsNotExist(err) {
- // The kernel-provided files only exist if user namespaces are supported
- logrus.Debugf("User or group ID mappings not available: %s", err)
- } else {
- return nil, err
- }
- } else {
- g.Config.Linux.UIDMappings = rootless.MaybeSplitMappings(g.Config.Linux.UIDMappings, availableUIDs)
- g.Config.Linux.GIDMappings = rootless.MaybeSplitMappings(g.Config.Linux.GIDMappings, availableGIDs)
- }
-
- // Hostname handling:
- // If we have a UTS namespace, set Hostname in the OCI spec.
- // Set the HOSTNAME environment variable unless explicitly overridden by
- // the user (already present in OCI spec). If we don't have a UTS ns,
- // set it to the host's hostname instead.
- hostname := c.Hostname()
- foundUTS := false
-
- for _, i := range c.config.Spec.Linux.Namespaces {
- if i.Type == spec.UTSNamespace && i.Path == "" {
- foundUTS = true
- g.SetHostname(hostname)
- break
- }
- }
- if !foundUTS {
- tmpHostname, err := os.Hostname()
- if err != nil {
- return nil, err
- }
- hostname = tmpHostname
- }
- needEnv := true
- for _, checkEnv := range g.Config.Process.Env {
- if strings.SplitN(checkEnv, "=", 2)[0] == "HOSTNAME" {
- needEnv = false
- break
- }
- }
- if needEnv {
- g.AddProcessEnv("HOSTNAME", hostname)
- }
-
- if c.config.UTSNsCtr != "" {
- if err := c.addNamespaceContainer(&g, UTSNS, c.config.UTSNsCtr, spec.UTSNamespace); err != nil {
- return nil, err
- }
- }
- if c.config.CgroupNsCtr != "" {
- if err := c.addNamespaceContainer(&g, CgroupNS, c.config.CgroupNsCtr, spec.CgroupNamespace); err != nil {
- return nil, err
- }
- }
-
- if c.config.UserNsCtr == "" && c.config.IDMappings.AutoUserNs {
- if err := g.AddOrReplaceLinuxNamespace(string(spec.UserNamespace), ""); err != nil {
- return nil, err
- }
- g.ClearLinuxUIDMappings()
- for _, uidmap := range c.config.IDMappings.UIDMap {
- g.AddLinuxUIDMapping(uint32(uidmap.HostID), uint32(uidmap.ContainerID), uint32(uidmap.Size))
- }
- g.ClearLinuxGIDMappings()
- for _, gidmap := range c.config.IDMappings.GIDMap {
- g.AddLinuxGIDMapping(uint32(gidmap.HostID), uint32(gidmap.ContainerID), uint32(gidmap.Size))
- }
+ if err := c.addSharedNamespaces(&g); err != nil {
+ return nil, err
}
g.SetRootPath(c.state.Mountpoint)
@@ -510,13 +402,10 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
g.AddAnnotation(annotations.ContainerManager, annotations.ContainerManagerLibpod)
}
- cgroupPath, err := c.getOCICgroupPath()
- if err != nil {
+ if err := c.setCgroupsPath(&g); err != nil {
return nil, err
}
- g.SetLinuxCgroupsPath(cgroupPath)
-
// Warning: CDI may alter g.Config in place.
if len(c.config.CDIDevices) > 0 {
registry := cdi.GetRegistry(
@@ -535,14 +424,6 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
mounts := sortMounts(g.Mounts())
g.ClearMounts()
- // Determine property of RootPropagation based on volume properties. If
- // a volume is shared, then keep root propagation shared. This should
- // work for slave and private volumes too.
- //
- // For slave volumes, it can be either [r]shared/[r]slave.
- //
- // For private volumes any root propagation value should work.
- rootPropagation := ""
for _, m := range mounts {
// We need to remove all symlinks from tmpfs mounts.
// Runc and other runtimes may choke on them.
@@ -557,25 +438,10 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
m.Destination = trimmedPath
}
g.AddMount(m)
- for _, opt := range m.Options {
- switch opt {
- case MountShared, MountRShared:
- if rootPropagation != MountShared && rootPropagation != MountRShared {
- rootPropagation = MountShared
- }
- case MountSlave, MountRSlave:
- if rootPropagation != MountShared && rootPropagation != MountRShared && rootPropagation != MountSlave && rootPropagation != MountRSlave {
- rootPropagation = MountRSlave
- }
- }
- }
}
- if rootPropagation != "" {
- logrus.Debugf("Set root propagation to %q", rootPropagation)
- if err := g.SetLinuxRootPropagation(rootPropagation); err != nil {
- return nil, err
- }
+ if err := c.addRootPropagation(&g, mounts); err != nil {
+ return nil, err
}
// Warning: precreate hooks may alter g.Config in place.
diff --git a/libpod/container_internal_freebsd.go b/libpod/container_internal_freebsd.go
index 9cfef5c70..65a74a2e4 100644
--- a/libpod/container_internal_freebsd.go
+++ b/libpod/container_internal_freebsd.go
@@ -9,7 +9,6 @@ import (
"fmt"
"io"
"io/ioutil"
- "math"
"os"
"os/user"
"path"
@@ -22,10 +21,8 @@ import (
metadata "github.com/checkpoint-restore/checkpointctl/lib"
"github.com/checkpoint-restore/go-criu/v5/stats"
- cdi "github.com/container-orchestrated-devices/container-device-interface/pkg/cdi"
"github.com/containers/buildah/pkg/chrootuser"
"github.com/containers/buildah/pkg/overlay"
- butil "github.com/containers/buildah/util"
"github.com/containers/common/libnetwork/etchosts"
"github.com/containers/common/libnetwork/resolvconf"
"github.com/containers/common/libnetwork/types"
@@ -33,10 +30,8 @@ import (
"github.com/containers/common/pkg/config"
"github.com/containers/common/pkg/subscriptions"
"github.com/containers/common/pkg/umask"
- cutil "github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/libpod/events"
- "github.com/containers/podman/v4/pkg/annotations"
"github.com/containers/podman/v4/pkg/checkpoint/crutils"
"github.com/containers/podman/v4/pkg/criu"
"github.com/containers/podman/v4/pkg/lookup"
@@ -2129,3 +2124,80 @@ func openDirectory(path string) (fd int, err error) {
const O_PATH = 0x00400000
return unix.Open(path, unix.O_RDONLY|O_PATH, 0)
}
+
+func (c *Container) addNetworkNamespace(g *generate.Generator) error {
+ if c.config.CreateNetNS {
+ g.AddAnnotation("org.freebsd.parentJail", c.state.NetworkJail)
+ }
+ return nil
+}
+
+func (c *Container) addSystemdMounts(g *generate.Generator) error {
+ return nil
+}
+
+func (c *Container) addSharedNamespaces(g *generate.Generator) error {
+ if c.config.NetNsCtr != "" {
+ if err := c.addNetworkContainer(g, c.config.NetNsCtr); err != nil {
+ return err
+ }
+ }
+
+ availableUIDs, availableGIDs, err := rootless.GetAvailableIDMaps()
+ if err != nil {
+ if os.IsNotExist(err) {
+ // The kernel-provided files only exist if user namespaces are supported
+ logrus.Debugf("User or group ID mappings not available: %s", err)
+ } else {
+ return err
+ }
+ } else {
+ g.Config.Linux.UIDMappings = rootless.MaybeSplitMappings(g.Config.Linux.UIDMappings, availableUIDs)
+ g.Config.Linux.GIDMappings = rootless.MaybeSplitMappings(g.Config.Linux.GIDMappings, availableGIDs)
+ }
+
+ // Hostname handling:
+ // If we have a UTS namespace, set Hostname in the OCI spec.
+ // Set the HOSTNAME environment variable unless explicitly overridden by
+ // the user (already present in OCI spec). If we don't have a UTS ns,
+ // set it to the host's hostname instead.
+ hostname := c.Hostname()
+ foundUTS := false
+
+ // TODO: make this optional, needs progress on adding FreeBSD section to the spec
+ foundUTS = true
+ g.SetHostname(hostname)
+
+ if !foundUTS {
+ tmpHostname, err := os.Hostname()
+ if err != nil {
+ return err
+ }
+ hostname = tmpHostname
+ }
+ needEnv := true
+ for _, checkEnv := range g.Config.Process.Env {
+ if strings.SplitN(checkEnv, "=", 2)[0] == "HOSTNAME" {
+ needEnv = false
+ break
+ }
+ }
+ if needEnv {
+ g.AddProcessEnv("HOSTNAME", hostname)
+ }
+ return nil
+}
+
+func (c *Container) addRootPropagation(g *generate.Generator, mounts []spec.Mount) error {
+ return nil
+}
+
+func (c *Container) setProcessLabel(g *generate.Generator) {
+}
+
+func (c *Container) setMountLabel(g *generate.Generator) {
+}
+
+func (c *Container) setCgroupsPath(g *generate.Generator) error {
+ return nil
+}
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 5ec9d8e43..1cec3a7bc 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -2666,3 +2666,181 @@ func (c *Container) setupRootlessNetwork() error {
func openDirectory(path string) (fd int, err error) {
return unix.Open(path, unix.O_RDONLY|unix.O_PATH, 0)
}
+
+func (c *Container) addNetworkNamespace(g *generate.Generator) error {
+ if c.config.CreateNetNS {
+ if c.config.PostConfigureNetNS {
+ if err := g.AddOrReplaceLinuxNamespace(string(spec.NetworkNamespace), ""); err != nil {
+ return err
+ }
+ } else {
+ if err := g.AddOrReplaceLinuxNamespace(string(spec.NetworkNamespace), c.state.NetNS.Path()); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+func (c *Container) addSystemdMounts(g *generate.Generator) error {
+ if c.Systemd() {
+ if err := c.setupSystemd(g.Mounts(), *g); err != nil {
+ return fmt.Errorf("error adding systemd-specific mounts: %w", err)
+ }
+ }
+ return nil
+}
+
+func (c *Container) addSharedNamespaces(g *generate.Generator) error {
+ if c.config.IPCNsCtr != "" {
+ if err := c.addNamespaceContainer(g, IPCNS, c.config.IPCNsCtr, spec.IPCNamespace); err != nil {
+ return err
+ }
+ }
+ if c.config.MountNsCtr != "" {
+ if err := c.addNamespaceContainer(g, MountNS, c.config.MountNsCtr, spec.MountNamespace); err != nil {
+ return err
+ }
+ }
+ if c.config.NetNsCtr != "" {
+ if err := c.addNamespaceContainer(g, NetNS, c.config.NetNsCtr, spec.NetworkNamespace); err != nil {
+ return err
+ }
+ }
+ if c.config.PIDNsCtr != "" {
+ if err := c.addNamespaceContainer(g, PIDNS, c.config.PIDNsCtr, spec.PIDNamespace); err != nil {
+ return err
+ }
+ }
+ if c.config.UserNsCtr != "" {
+ if err := c.addNamespaceContainer(g, UserNS, c.config.UserNsCtr, spec.UserNamespace); err != nil {
+ return err
+ }
+ if len(g.Config.Linux.UIDMappings) == 0 {
+ // runc complains if no mapping is specified, even if we join another ns. So provide a dummy mapping
+ g.AddLinuxUIDMapping(uint32(0), uint32(0), uint32(1))
+ g.AddLinuxGIDMapping(uint32(0), uint32(0), uint32(1))
+ }
+ }
+
+ availableUIDs, availableGIDs, err := rootless.GetAvailableIDMaps()
+ if err != nil {
+ if os.IsNotExist(err) {
+ // The kernel-provided files only exist if user namespaces are supported
+ logrus.Debugf("User or group ID mappings not available: %s", err)
+ } else {
+ return err
+ }
+ } else {
+ g.Config.Linux.UIDMappings = rootless.MaybeSplitMappings(g.Config.Linux.UIDMappings, availableUIDs)
+ g.Config.Linux.GIDMappings = rootless.MaybeSplitMappings(g.Config.Linux.GIDMappings, availableGIDs)
+ }
+
+ // Hostname handling:
+ // If we have a UTS namespace, set Hostname in the OCI spec.
+ // Set the HOSTNAME environment variable unless explicitly overridden by
+ // the user (already present in OCI spec). If we don't have a UTS ns,
+ // set it to the host's hostname instead.
+ hostname := c.Hostname()
+ foundUTS := false
+
+ for _, i := range c.config.Spec.Linux.Namespaces {
+ if i.Type == spec.UTSNamespace && i.Path == "" {
+ foundUTS = true
+ g.SetHostname(hostname)
+ break
+ }
+ }
+ if !foundUTS {
+ tmpHostname, err := os.Hostname()
+ if err != nil {
+ return err
+ }
+ hostname = tmpHostname
+ }
+ needEnv := true
+ for _, checkEnv := range g.Config.Process.Env {
+ if strings.SplitN(checkEnv, "=", 2)[0] == "HOSTNAME" {
+ needEnv = false
+ break
+ }
+ }
+ if needEnv {
+ g.AddProcessEnv("HOSTNAME", hostname)
+ }
+
+ if c.config.UTSNsCtr != "" {
+ if err := c.addNamespaceContainer(g, UTSNS, c.config.UTSNsCtr, spec.UTSNamespace); err != nil {
+ return err
+ }
+ }
+ if c.config.CgroupNsCtr != "" {
+ if err := c.addNamespaceContainer(g, CgroupNS, c.config.CgroupNsCtr, spec.CgroupNamespace); err != nil {
+ return err
+ }
+ }
+
+ if c.config.UserNsCtr == "" && c.config.IDMappings.AutoUserNs {
+ if err := g.AddOrReplaceLinuxNamespace(string(spec.UserNamespace), ""); err != nil {
+ return err
+ }
+ g.ClearLinuxUIDMappings()
+ for _, uidmap := range c.config.IDMappings.UIDMap {
+ g.AddLinuxUIDMapping(uint32(uidmap.HostID), uint32(uidmap.ContainerID), uint32(uidmap.Size))
+ }
+ g.ClearLinuxGIDMappings()
+ for _, gidmap := range c.config.IDMappings.GIDMap {
+ g.AddLinuxGIDMapping(uint32(gidmap.HostID), uint32(gidmap.ContainerID), uint32(gidmap.Size))
+ }
+ }
+ return nil
+}
+
+func (c *Container) addRootPropagation(g *generate.Generator, mounts []spec.Mount) error {
+ // Determine property of RootPropagation based on volume properties. If
+ // a volume is shared, then keep root propagation shared. This should
+ // work for slave and private volumes too.
+ //
+ // For slave volumes, it can be either [r]shared/[r]slave.
+ //
+ // For private volumes any root propagation value should work.
+ rootPropagation := ""
+ for _, m := range mounts {
+ for _, opt := range m.Options {
+ switch opt {
+ case MountShared, MountRShared:
+ if rootPropagation != MountShared && rootPropagation != MountRShared {
+ rootPropagation = MountShared
+ }
+ case MountSlave, MountRSlave:
+ if rootPropagation != MountShared && rootPropagation != MountRShared && rootPropagation != MountSlave && rootPropagation != MountRSlave {
+ rootPropagation = MountRSlave
+ }
+ }
+ }
+ }
+ if rootPropagation != "" {
+ logrus.Debugf("Set root propagation to %q", rootPropagation)
+ if err := g.SetLinuxRootPropagation(rootPropagation); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (c *Container) setProcessLabel(g *generate.Generator) {
+ g.SetProcessSelinuxLabel(c.ProcessLabel())
+}
+
+func (c *Container) setMountLabel(g *generate.Generator) {
+ g.SetLinuxMountLabel(c.MountLabel())
+}
+
+func (c *Container) setCgroupsPath(g *generate.Generator) error {
+ cgroupPath, err := c.getOCICgroupPath()
+ if err != nil {
+ return err
+ }
+ g.SetLinuxCgroupsPath(cgroupPath)
+ return nil
+}