Support all volume mounts for rootless containers

Fix handling of "bind" and "tmpfs" olumes to actually work.
Allow bind, tmpfs local volumes to work in rootless mode.

Also removed the string "error" from all error messages that begine with it.
All Podman commands are printed with Error:, so this causes an ugly
stutter.

Fixes: https://github.com/containers/podman/issues/12013

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
Daniel J Walsh
2021-12-22 15:07:37 -05:00
parent 47cf00eb13
commit 2e0d3e9ea4
6 changed files with 61 additions and 47 deletions

View File

@ -7,7 +7,6 @@ import (
"strings"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/rootless"
pluginapi "github.com/docker/go-plugins-helpers/volume"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@ -32,13 +31,6 @@ func (v *Volume) mount() error {
return nil
}
// We cannot mount 'local' volumes as rootless.
if !v.UsesVolumeDriver() && rootless.IsRootless() {
// This check should only be applied to 'local' driver
// so Volume Drivers must be excluded
return errors.Wrapf(define.ErrRootless, "cannot mount volumes without root privileges")
}
// Update the volume from the DB to get an accurate mount counter.
if err := v.update(); err != nil {
return err
@ -90,22 +82,27 @@ func (v *Volume) mount() error {
// TODO: might want to cache this path in the runtime?
mountPath, err := exec.LookPath("mount")
if err != nil {
return errors.Wrapf(err, "error locating 'mount' binary")
return errors.Wrapf(err, "locating 'mount' binary")
}
mountArgs := []string{}
if volOptions != "" {
mountArgs = append(mountArgs, "-o", volOptions)
}
if volType != "" {
switch volType {
case "":
case "bind":
mountArgs = append(mountArgs, "-o", volType)
default:
mountArgs = append(mountArgs, "-t", volType)
}
mountArgs = append(mountArgs, volDevice, v.config.MountPoint)
mountCmd := exec.Command(mountPath, mountArgs...)
logrus.Debugf("Running mount command: %s %s", mountPath, strings.Join(mountArgs, " "))
if output, err := mountCmd.CombinedOutput(); err != nil {
logrus.Debugf("Mount %v failed with %v", mountCmd, err)
return errors.Wrapf(errors.Errorf(string(output)), "error mounting volume %s", v.Name())
return errors.Errorf(string(output))
}
logrus.Debugf("Mounted volume %s", v.Name())
@ -139,20 +136,6 @@ func (v *Volume) unmount(force bool) error {
return nil
}
// We cannot unmount 'local' volumes as rootless.
if !v.UsesVolumeDriver() && rootless.IsRootless() {
// If force is set, just clear the counter and bail without
// error, so we can remove volumes from the state if they are in
// an awkward configuration.
if force {
logrus.Errorf("Volume %s is mounted despite being rootless - state is not sane", v.Name())
v.state.MountCount = 0
return v.save()
}
return errors.Wrapf(define.ErrRootless, "cannot mount or unmount volumes without root privileges")
}
if !force {
v.state.MountCount--
} else {
@ -184,7 +167,7 @@ func (v *Volume) unmount(force bool) error {
// Ignore EINVAL - the mount no longer exists.
return nil
}
return errors.Wrapf(err, "error unmounting volume %s", v.Name())
return errors.Wrapf(err, "unmounting volume %s", v.Name())
}
logrus.Debugf("Unmounted volume %s", v.Name())
}