summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container_internal_linux.go1
-rw-r--r--libpod/oci_conmon_linux.go6
-rw-r--r--libpod/options.go16
-rw-r--r--libpod/runtime.go77
-rw-r--r--libpod/runtime_ctr.go31
-rw-r--r--libpod/volume_inspect.go3
6 files changed, 85 insertions, 49 deletions
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index b7d353327..283d38a0f 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -550,6 +550,7 @@ func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) erro
Options: []string{"bind", "nodev", "noexec", "nosuid"},
}
g.AddMount(systemdMnt)
+ g.AddLinuxMaskedPaths("/sys/fs/cgroup/systemd/release_agent")
}
return nil
diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go
index 658a2fe4e..448e05bdf 100644
--- a/libpod/oci_conmon_linux.go
+++ b/libpod/oci_conmon_linux.go
@@ -602,7 +602,7 @@ func (r *ConmonOCIRuntime) ExecContainer(c *Container, sessionID string, options
if err != nil {
return -1, nil, errors.Wrapf(err, "cannot start container %s", c.ID())
}
- if err := r.moveConmonToCgroupAndSignal(c, execCmd, parentStartPipe, sessionID); err != nil {
+ if err := r.moveConmonToCgroupAndSignal(c, execCmd, parentStartPipe); err != nil {
return -1, nil, err
}
@@ -986,7 +986,7 @@ func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *Co
if err != nil {
return err
}
- if err := r.moveConmonToCgroupAndSignal(ctr, cmd, parentStartPipe, ctr.ID()); err != nil {
+ if err := r.moveConmonToCgroupAndSignal(ctr, cmd, parentStartPipe); err != nil {
return err
}
/* Wait for initial setup and fork, and reap child */
@@ -1213,7 +1213,7 @@ func startCommandGivenSelinux(cmd *exec.Cmd) error {
// moveConmonToCgroupAndSignal gets a container's cgroupParent and moves the conmon process to that cgroup
// it then signals for conmon to start by sending nonse data down the start fd
-func (r *ConmonOCIRuntime) moveConmonToCgroupAndSignal(ctr *Container, cmd *exec.Cmd, startFd *os.File, uuid string) error {
+func (r *ConmonOCIRuntime) moveConmonToCgroupAndSignal(ctr *Container, cmd *exec.Cmd, startFd *os.File) error {
mustCreateCgroup := true
// If cgroup creation is disabled - just signal.
if ctr.config.NoCgroups {
diff --git a/libpod/options.go b/libpod/options.go
index ddc5993af..f779b0413 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -1014,6 +1014,13 @@ func WithNetNS(portMappings []ocicni.PortMapping, postConfigureNetNS bool, netmo
ctr.config.NetMode = namespaces.NetworkMode(netmode)
ctr.config.CreateNetNS = true
ctr.config.PortMappings = portMappings
+
+ if rootless.IsRootless() {
+ if len(networks) > 0 {
+ return errors.New("cannot use CNI networks with rootless containers")
+ }
+ }
+
ctr.config.Networks = networks
return nil
@@ -1487,6 +1494,8 @@ func WithVolumeLabels(labels map[string]string) VolumeCreateOption {
}
// WithVolumeOptions sets the options of the volume.
+// If the "local" driver has been selected, options will be validated. There are
+// currently 3 valid options for the "local" driver - o, type, and device.
func WithVolumeOptions(options map[string]string) VolumeCreateOption {
return func(volume *Volume) error {
if volume.valid {
@@ -1495,6 +1504,13 @@ func WithVolumeOptions(options map[string]string) VolumeCreateOption {
volume.config.Options = make(map[string]string)
for key, value := range options {
+ switch key {
+ case "type", "device", "o":
+ volume.config.Options[key] = value
+ default:
+ return errors.Wrapf(define.ErrInvalidArg, "unrecognized volume option %q is not supported with local driver", key)
+ }
+
volume.config.Options[key] = value
}
diff --git a/libpod/runtime.go b/libpod/runtime.go
index a0cf0ad7c..a06b2bb51 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -14,7 +14,6 @@ import (
"strings"
"sync"
"syscall"
- "time"
"github.com/BurntSushi/toml"
is "github.com/containers/image/v4/storage"
@@ -353,10 +352,6 @@ func defaultRuntimeConfig() (RuntimeConfig, error) {
// SetXdgDirs ensures the XDG_RUNTIME_DIR env and XDG_CONFIG_HOME variables are set.
// containers/image uses XDG_RUNTIME_DIR to locate the auth file, XDG_CONFIG_HOME is
// use for the libpod.conf configuration file.
-// SetXdgDirs internally calls EnableLinger() so that the user's processes are not
-// killed once the session is terminated. EnableLinger() also attempts to
-// get the runtime directory when XDG_RUNTIME_DIR is not specified.
-// This function should only be called when running rootless.
func SetXdgDirs() error {
if !rootless.IsRootless() {
return nil
@@ -365,21 +360,6 @@ func SetXdgDirs() error {
// Setup XDG_RUNTIME_DIR
runtimeDir := os.Getenv("XDG_RUNTIME_DIR")
- runtimeDirLinger, err := rootless.EnableLinger()
- if err != nil {
- return errors.Wrapf(err, "error enabling user session")
- }
- if runtimeDir == "" && runtimeDirLinger != "" {
- if _, err := os.Stat(runtimeDirLinger); err != nil && os.IsNotExist(err) {
- chWait := make(chan error)
- defer close(chWait)
- if _, err := WaitForFile(runtimeDirLinger, chWait, time.Second*10); err != nil {
- return errors.Wrapf(err, "waiting for directory '%s'", runtimeDirLinger)
- }
- }
- runtimeDir = runtimeDirLinger
- }
-
if runtimeDir == "" {
var err error
runtimeDir, err = util.GetRuntimeDir()
@@ -400,10 +380,11 @@ func SetXdgDirs() error {
// Setup XDG_CONFIG_HOME
if cfgHomeDir := os.Getenv("XDG_CONFIG_HOME"); cfgHomeDir == "" {
- if cfgHomeDir, err = util.GetRootlessConfigHomeDir(); err != nil {
+ cfgHomeDir, err := util.GetRootlessConfigHomeDir()
+ if err != nil {
return err
}
- if err = os.Setenv("XDG_CONFIG_HOME", cfgHomeDir); err != nil {
+ if err := os.Setenv("XDG_CONFIG_HOME", cfgHomeDir); err != nil {
return errors.Wrapf(err, "cannot set XDG_CONFIG_HOME")
}
}
@@ -528,6 +509,17 @@ func newRuntimeFromConfig(ctx context.Context, userConfigPath string, options ..
return nil, err
}
+ // storage.conf
+ storageConfFile, err := storage.DefaultConfigFile(rootless.IsRootless())
+ if err != nil {
+ return nil, err
+ }
+
+ createStorageConfFile := false
+ if _, err := os.Stat(storageConfFile); os.IsNotExist(err) {
+ createStorageConfFile = true
+ }
+
defRunConf, err := defaultRuntimeConfig()
if err != nil {
return nil, err
@@ -702,27 +694,21 @@ func newRuntimeFromConfig(ctx context.Context, userConfigPath string, options ..
}
if rootless.IsRootless() && configPath == "" {
- configPath, err := getRootlessConfigPath()
- if err != nil {
- return nil, err
- }
-
- // storage.conf
- storageConfFile, err := storage.DefaultConfigFile(rootless.IsRootless())
- if err != nil {
- return nil, err
- }
- if _, err := os.Stat(storageConfFile); os.IsNotExist(err) {
+ if createStorageConfFile {
if err := util.WriteStorageConfigFile(&runtime.config.StorageConfig, storageConfFile); err != nil {
return nil, errors.Wrapf(err, "cannot write config file %s", storageConfFile)
}
}
+ configPath, err := getRootlessConfigPath()
+ if err != nil {
+ return nil, err
+ }
if configPath != "" {
- if err := os.MkdirAll(filepath.Dir(configPath), 0755); err != nil {
+ if err := os.MkdirAll(filepath.Dir(configPath), 0711); err != nil {
return nil, err
}
- file, err := os.OpenFile(configPath, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
+ file, err := os.OpenFile(configPath, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
if err != nil && !os.IsExist(err) {
return nil, errors.Wrapf(err, "cannot open file %s", configPath)
}
@@ -1488,6 +1474,25 @@ func (r *Runtime) GetOCIRuntimePath() string {
// TODO Once runc has support for cgroups, this function should be removed.
func cgroupV2Check(configPath string, tmpConfig *RuntimeConfig) error {
if !tmpConfig.CgroupCheck && rootless.IsRootless() {
+ if tmpConfig.CgroupManager == SystemdCgroupsManager {
+ // If we are running rootless and the systemd manager is requested, be sure that dbus is accessible
+ session := os.Getenv("DBUS_SESSION_BUS_ADDRESS")
+ hasSession := session != ""
+ if hasSession && strings.HasPrefix(session, "unix:path=") {
+ _, err := os.Stat(strings.TrimPrefix(session, "unix:path="))
+ hasSession = err == nil
+ }
+
+ if !hasSession {
+ logrus.Warningf("The cgroups manager is set to systemd but there is no systemd user session available")
+ logrus.Warningf("For using systemd, you may need to login using an user session")
+ logrus.Warningf("Alternatively, you can enable lingering with: `loginctl enable-linger %d` (possibily as root)", rootless.GetRootlessUID())
+ logrus.Warningf("Falling back to --cgroup-manager=cgroupfs")
+
+ tmpConfig.CgroupManager = CgroupfsCgroupsManager
+ }
+
+ }
cgroupsV2, err := cgroups.IsCgroup2UnifiedMode()
if err != nil {
return err
@@ -1501,7 +1506,7 @@ func cgroupV2Check(configPath string, tmpConfig *RuntimeConfig) error {
}
tmpConfig.CgroupCheck = true
tmpConfig.OCIRuntime = path
- file, err := os.OpenFile(configPath, os.O_RDWR|os.O_CREATE, 0666)
+ file, err := os.OpenFile(configPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
if err != nil {
return errors.Wrapf(err, "cannot open file %s", configPath)
}
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index 411264d25..2b214d572 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -295,21 +295,32 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (c *Contai
// Maintain an array of them - we need to lock them later.
ctrNamedVolumes := make([]*Volume, 0, len(ctr.config.NamedVolumes))
for _, vol := range ctr.config.NamedVolumes {
- // Check if it exists already
- dbVol, err := r.state.Volume(vol.Name)
- if err == nil {
- ctrNamedVolumes = append(ctrNamedVolumes, dbVol)
- // The volume exists, we're good
- continue
- } else if errors.Cause(err) != define.ErrNoSuchVolume {
- return nil, errors.Wrapf(err, "error retrieving named volume %s for new container", vol.Name)
+ isAnonymous := false
+ if vol.Name == "" {
+ // Anonymous volume. We'll need to create it.
+ // It needs a name first.
+ vol.Name = stringid.GenerateNonCryptoID()
+ isAnonymous = true
+ } else {
+ // Check if it exists already
+ dbVol, err := r.state.Volume(vol.Name)
+ if err == nil {
+ ctrNamedVolumes = append(ctrNamedVolumes, dbVol)
+ // The volume exists, we're good
+ continue
+ } else if errors.Cause(err) != define.ErrNoSuchVolume {
+ return nil, errors.Wrapf(err, "error retrieving named volume %s for new container", vol.Name)
+ }
}
logrus.Debugf("Creating new volume %s for container", vol.Name)
// The volume does not exist, so we need to create it.
- newVol, err := r.newVolume(ctx, WithVolumeName(vol.Name), withSetCtrSpecific(),
- WithVolumeUID(ctr.RootUID()), WithVolumeGID(ctr.RootGID()))
+ volOptions := []VolumeCreateOption{WithVolumeName(vol.Name), WithVolumeUID(ctr.RootUID()), WithVolumeGID(ctr.RootGID())}
+ if isAnonymous {
+ volOptions = append(volOptions, withSetCtrSpecific())
+ }
+ newVol, err := r.newVolume(ctx, volOptions...)
if err != nil {
return nil, errors.Wrapf(err, "error creating named volume %q", vol.Name)
}
diff --git a/libpod/volume_inspect.go b/libpod/volume_inspect.go
index 87ed9d340..c333b8961 100644
--- a/libpod/volume_inspect.go
+++ b/libpod/volume_inspect.go
@@ -62,6 +62,9 @@ func (v *Volume) Inspect() (*InspectVolumeData, error) {
}
data.Scope = v.Scope()
data.Options = make(map[string]string)
+ for k, v := range v.config.Options {
+ data.Options[k] = v
+ }
data.UID = v.config.UID
data.GID = v.config.GID
data.ContainerSpecific = v.config.IsCtrSpecific