Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion driver/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func NewDriver(ep, token, urlstr string, logLevel logrus.Level) (*Driver, error)
serverId: serverId,
zone: zone,
cloudscaleClient: cloudscaleClient,
mounter: newMounter(log),
mounter: newMounter(),
log: log,
volumeLocks: NewVolumeLocks(),
}, nil
Expand Down
14 changes: 7 additions & 7 deletions driver/driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,18 +125,18 @@ type fakeMounter struct {
mu sync.RWMutex
}

func (f *fakeMounter) Format(source string, fsType string, luksContext LuksContext) error {
func (f *fakeMounter) Format(source, fsType string, luksContext LuksContext, log *logrus.Entry) error {
return nil
}

func (f *fakeMounter) Mount(source string, target string, fsType string, luksContext LuksContext, options ...string) error {
func (f *fakeMounter) Mount(source, target, fsType string, luksContext LuksContext, log *logrus.Entry, options ...string) error {
f.mu.Lock()
defer f.mu.Unlock()
f.mounted[target] = source
return nil
}

func (f *fakeMounter) Unmount(target string, luksContext LuksContext) error {
func (f *fakeMounter) Unmount(target string, luksContext LuksContext, log *logrus.Entry) error {
f.mu.Lock()
defer f.mu.Unlock()
delete(f.mounted, target)
Expand All @@ -153,22 +153,22 @@ func (f *fakeMounter) GetDeviceName(_ mount.Interface, mountPath string) (string
return "", nil
}

func (f *fakeMounter) FindAbsoluteDeviceByIDPath(volumeName string) (string, error) {
func (f *fakeMounter) FindAbsoluteDeviceByIDPath(volumeName string, log *logrus.Entry) (string, error) {
return "/dev/sdb", nil
}

func (f *fakeMounter) IsFormatted(source string, luksContext LuksContext) (bool, error) {
func (f *fakeMounter) IsFormatted(source string, luksContext LuksContext, log *logrus.Entry) (bool, error) {
return true, nil
}
func (f *fakeMounter) IsMounted(target string) (bool, error) {
func (f *fakeMounter) IsMounted(target string, log *logrus.Entry) (bool, error) {
f.mu.RLock()
defer f.mu.RUnlock()
_, ok := f.mounted[target]
return ok, nil
}

func (f *fakeMounter) checkMountPath(path string) (sanity.PathKind, error) {
isMounted, err := f.IsMounted(path)
isMounted, err := f.IsMounted(path, nil)
if err != nil {
return "", err
}
Expand Down
64 changes: 31 additions & 33 deletions driver/mounter.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,22 +69,22 @@ type volumeStatistics struct {
// more than just mounting functionality by now.
type Mounter interface {
// Format formats the source with the given filesystem type
Format(source, fsType string, luksContext LuksContext) error
Format(source, fsType string, luksContext LuksContext, log *logrus.Entry) error

// Mount mounts source to target with the given fstype and options.
Mount(source, target, fsType string, luksContext LuksContext, options ...string) error
Mount(source, target, fsType string, luksContext LuksContext, log *logrus.Entry, options ...string) error

// Unmount unmounts the given target
Unmount(target string, luksContext LuksContext) error
Unmount(target string, luksContext LuksContext, log *logrus.Entry) error

// IsFormatted checks whether the source device is formatted or not. It
// returns true if the source device is already formatted.
IsFormatted(source string, luksContext LuksContext) (bool, error)
IsFormatted(source string, luksContext LuksContext, log *logrus.Entry) (bool, error)

// IsMounted checks whether the target path is a correct mount (i.e:
// propagated). It returns true if it's mounted. An error is returned in
// case of system errors or if it's mounted incorrectly.
IsMounted(target string) (bool, error)
IsMounted(target string, log *logrus.Entry) (bool, error)

// Used to find a path in /dev/disk/by-id with a serial that we have from
// the cloudscale API.
Expand All @@ -99,37 +99,35 @@ type Mounter interface {

GetDeviceName(mounter mount.Interface, mountPath string) (string, error)

FindAbsoluteDeviceByIDPath(volumeName string) (string, error)
FindAbsoluteDeviceByIDPath(volumeName string, log *logrus.Entry) (string, error)
HasRequiredSize(log *logrus.Entry, path string, requiredSize int64) (bool, error)
}

// TODO(arslan): this is Linux only for now. Refactor this into a package with
// architecture specific code in the future, such as mounter_darwin.go,
// mounter_linux.go, etc..
type mounter struct {
log *logrus.Entry
kMounter *mount.SafeFormatAndMount
}

// newMounter returns a new mounter instance
func newMounter(log *logrus.Entry) *mounter {
func newMounter() *mounter {
kMounter := &mount.SafeFormatAndMount{
Interface: mount.New(""),
Exec: kexec.New(),
}

return &mounter{
kMounter: kMounter,
log: log,
}
}

func (m *mounter) Format(source, fsType string, luksContext LuksContext) error {
func (m *mounter) Format(source, fsType string, luksContext LuksContext, log *logrus.Entry) error {
mkfsCmd := fmt.Sprintf("mkfs.%s", fsType)

_, err := exec.LookPath(mkfsCmd)
if err != nil {
if err == exec.ErrNotFound {
if errors.Is(err, exec.ErrNotFound) {
return fmt.Errorf("%q executable not found in $PATH", mkfsCmd)
}
return err
Expand All @@ -155,7 +153,7 @@ func (m *mounter) Format(source, fsType string, luksContext LuksContext) error {
}

if !luksContext.EncryptionEnabled {
m.log.WithFields(logrus.Fields{
log.WithFields(logrus.Fields{
"cmd": mkfsCmd,
"args": mkfsArgs,
}).Info("executing format command")
Expand All @@ -172,15 +170,15 @@ func (m *mounter) Format(source, fsType string, luksContext LuksContext) error {
if err != nil {
return err
}
err = luksFormat(source, mkfsCmd, mkfsArgs, luksContext, m.log)
err = luksFormat(source, mkfsCmd, mkfsArgs, luksContext, log)
if err != nil {
return err
}
return nil
}
}

func (m *mounter) Mount(source, target, fsType string, luksContext LuksContext, options ...string) error {
func (m *mounter) Mount(source, target, fsType string, luksContext LuksContext, log *logrus.Entry, options ...string) error {
if source == "" {
return errors.New("source is not specified for mounting the volume")
}
Expand All @@ -203,7 +201,7 @@ func (m *mounter) Mount(source, target, fsType string, luksContext LuksContext,
return fmt.Errorf("failed to create target file for raw block bind mount: %v", err)
}
if err := file.Close(); err != nil {
m.log.WithFields(logrus.Fields{"target": target}).Error("failed to close file handle")
log.WithFields(logrus.Fields{"target": target}).Error("failed to close file handle")
}
} else {
// create target, os.Mkdirall is noop if directory exists
Expand All @@ -214,9 +212,9 @@ func (m *mounter) Mount(source, target, fsType string, luksContext LuksContext,
}

if luksContext.EncryptionEnabled && luksContext.VolumeLifecycle == VolumeLifecycleNodeStageVolume {
luksSource, err := luksPrepareMount(source, luksContext, m.log)
luksSource, err := luksPrepareMount(source, luksContext, log)
if err != nil {
m.log.WithFields(logrus.Fields{
log.WithFields(logrus.Fields{
"error": err.Error(),
"volume": luksContext.VolumeName,
}).Error("failed to prepare luks volume for mounting")
Expand All @@ -226,18 +224,18 @@ func (m *mounter) Mount(source, target, fsType string, luksContext LuksContext,
source = luksSource
}

if m.log.Logger.IsLevelEnabled(logrus.DebugLevel) {
if log.Logger.IsLevelEnabled(logrus.DebugLevel) {
resolvedSource, resolveErr := filepath.EvalSymlinks(source)
if resolveErr != nil {
m.log.WithFields(logrus.Fields{
log.WithFields(logrus.Fields{
"source": source,
"target": target,
"fs_type": fsType,
"options": options,
"resolve_error": resolveErr,
}).Debug("Mount: failed to resolve source symlink")
} else {
m.log.WithFields(logrus.Fields{
log.WithFields(logrus.Fields{
"source": source,
"resolved_source": resolvedSource,
"target": target,
Expand All @@ -247,7 +245,7 @@ func (m *mounter) Mount(source, target, fsType string, luksContext LuksContext,
}
}

m.log.WithFields(logrus.Fields{
log.WithFields(logrus.Fields{
"source": source,
"target": target,
"options": options,
Expand All @@ -260,7 +258,7 @@ func (m *mounter) Mount(source, target, fsType string, luksContext LuksContext,
return nil
}

func (m *mounter) Unmount(target string, luksContext LuksContext) error {
func (m *mounter) Unmount(target string, luksContext LuksContext, log *logrus.Entry) error {
if target == "" {
return errors.New("target is not specified for unmounting the volume")
}
Expand All @@ -286,7 +284,7 @@ func (m *mounter) Unmount(target string, luksContext LuksContext) error {
return err
}
if isLuksMapping {
err := luksClose(mappingName, m.log)
err := luksClose(mappingName, log)
if err != nil {
return err
}
Expand All @@ -301,7 +299,7 @@ func (m *mounter) Unmount(target string, luksContext LuksContext) error {
func getMountSources(target string) ([]string, error) {
_, err := exec.LookPath("findmnt")
if err != nil {
if err == exec.ErrNotFound {
if errors.Is(err, exec.ErrNotFound) {
return nil, fmt.Errorf("%q executable not found in $PATH", "findmnt")
}
return nil, err
Expand All @@ -318,12 +316,12 @@ func getMountSources(target string) ([]string, error) {
return strings.Split(string(out), "\n"), nil
}

func (m *mounter) IsFormatted(source string, luksContext LuksContext) (bool, error) {
func (m *mounter) IsFormatted(source string, luksContext LuksContext, log *logrus.Entry) (bool, error) {
if !luksContext.EncryptionEnabled {
return isVolumeFormatted(source, m.log)
return isVolumeFormatted(source, log)
}

formatted, err := isLuksVolumeFormatted(source, luksContext, m.log)
formatted, err := isLuksVolumeFormatted(source, luksContext, log)
if err != nil {
return false, err
}
Expand All @@ -338,7 +336,7 @@ func isVolumeFormatted(source string, log *logrus.Entry) (bool, error) {
blkidCmd := "blkid"
_, err := exec.LookPath(blkidCmd)
if err != nil {
if err == exec.ErrNotFound {
if errors.Is(err, exec.ErrNotFound) {
return false, fmt.Errorf("%q executable not found in $PATH", blkidCmd)
}
return false, err
Expand Down Expand Up @@ -371,23 +369,23 @@ func isVolumeFormatted(source string, log *logrus.Entry) (bool, error) {
return true, nil
}

func (m *mounter) IsMounted(target string) (bool, error) {
func (m *mounter) IsMounted(target string, log *logrus.Entry) (bool, error) {
if target == "" {
return false, errors.New("target is not specified for checking the mount")
}

findmntCmd := "findmnt"
_, err := exec.LookPath(findmntCmd)
if err != nil {
if err == exec.ErrNotFound {
if errors.Is(err, exec.ErrNotFound) {
return false, fmt.Errorf("%q executable not found in $PATH", findmntCmd)
}
return false, err
}

findmntArgs := []string{"-o", "TARGET,PROPAGATION,FSTYPE,OPTIONS", "-M", target, "-J"}

m.log.WithFields(logrus.Fields{
log.WithFields(logrus.Fields{
"cmd": findmntCmd,
"args": findmntArgs,
}).Info("checking if target is mounted")
Expand Down Expand Up @@ -618,8 +616,8 @@ func (m *mounter) GetDeviceName(mounter mount.Interface, mountPath string) (stri
}

// FindAbsoluteDeviceByIDPath follows the /dev/disk/by-id symlink to find the absolute path of a device
func (m *mounter) FindAbsoluteDeviceByIDPath(volumeName string) (string, error) {
path := guessDiskIDPathByVolumeID(volumeName, m.log)
func (m *mounter) FindAbsoluteDeviceByIDPath(volumeName string, log *logrus.Entry) (string, error) {
path := guessDiskIDPathByVolumeID(volumeName, log)
if path == "" {
return "", fmt.Errorf("could not find device-path for volume: %s", volumeName)
}
Expand Down
Loading