mount-utils: add Linux specific non-systemd Mounter

The k8s.io/mount-utils package is used by CSI-drivers, which run mount
calls in containers. Drivers can be Linux specific, and the container
with the driver likely does not have a (functioning) systemd
environment.

There are some useful functions like FormatAndMount() in the package. It
is not practical to add FormatAndMountWithoutSystemd(), or any of the
potential other functions. If an application uses these functions, they
are most likely targetting Linux already. In that case, adding a Linux
specific Mounter that disables systemd detection for all calls keeps the
number of ...WithoutSystemd() function variations small.
This commit is contained in:
Niels de Vos 2022-07-18 15:54:25 +02:00
parent 5108b0a3a0
commit 84f8137530

View File

@ -59,6 +59,7 @@ const (
type Mounter struct {
mounterPath string
withSystemd *bool
trySystemd bool
withSafeNotMountedBehavior bool
}
@ -70,6 +71,19 @@ var _ MounterForceUnmounter = &Mounter{}
func New(mounterPath string) Interface {
return &Mounter{
mounterPath: mounterPath,
trySystemd: true,
withSafeNotMountedBehavior: detectSafeNotMountedBehavior(),
}
}
// NewWithoutSystemd returns a Linux specific mount.Interface for the current
// system. It provides options to override the default mounter behavior.
// mounterPath allows using an alternative to `/bin/mount` for mounting. Any
// detection for systemd functionality is disabled with this Mounter.
func NewWithoutSystemd(mounterPath string) Interface {
return &Mounter{
mounterPath: mounterPath,
trySystemd: false,
withSafeNotMountedBehavior: detectSafeNotMountedBehavior(),
}
}
@ -77,6 +91,10 @@ func New(mounterPath string) Interface {
// hasSystemd validates that the withSystemd bool is set, if it is not,
// detectSystemd will be called once for this Mounter instance.
func (mounter *Mounter) hasSystemd() bool {
if !mounter.trySystemd {
mounter.withSystemd = &mounter.trySystemd
}
if mounter.withSystemd == nil {
withSystemd := detectSystemd()
mounter.withSystemd = &withSystemd
@ -105,11 +123,11 @@ func (mounter *Mounter) MountSensitive(source string, target string, fstype stri
mounterPath := ""
bind, bindOpts, bindRemountOpts, bindRemountOptsSensitive := MakeBindOptsSensitive(options, sensitiveOptions)
if bind {
err := mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, bindOpts, bindRemountOptsSensitive, nil /* mountFlags */, true)
err := mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, bindOpts, bindRemountOptsSensitive, nil /* mountFlags */, mounter.trySystemd)
if err != nil {
return err
}
return mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, bindRemountOpts, bindRemountOptsSensitive, nil /* mountFlags */, true)
return mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, bindRemountOpts, bindRemountOptsSensitive, nil /* mountFlags */, mounter.trySystemd)
}
// The list of filesystems that require containerized mounter on GCI image cluster
fsTypesNeedMounter := map[string]struct{}{
@ -121,7 +139,7 @@ func (mounter *Mounter) MountSensitive(source string, target string, fstype stri
if _, ok := fsTypesNeedMounter[fstype]; ok {
mounterPath = mounter.mounterPath
}
return mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, options, sensitiveOptions, nil /* mountFlags */, true)
return mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, options, sensitiveOptions, nil /* mountFlags */, mounter.trySystemd)
}
// MountSensitiveWithoutSystemd is the same as MountSensitive() but disable using systemd mount.
@ -164,7 +182,7 @@ func (mounter *Mounter) doMount(mounterPath string, mountCmd string, source stri
mountCmd = mounterPath
}
if mounter.hasSystemd() && systemdMountRequired {
if systemdMountRequired && mounter.hasSystemd() {
// Try to run mount via systemd-run --scope. This will escape the
// service where kubelet runs and any fuse daemons will be started in a
// specific scope. kubelet service than can be restarted without killing