Skip to content

Commit

Permalink
refactor: move mount/unmount to user package
Browse files Browse the repository at this point in the history
Signed-off-by: Edita Kizinevic <edita.kizinevic@cern.ch>
  • Loading branch information
Adam Hughes authored and edytuk committed May 10, 2022
1 parent a9cf1d2 commit 683f227
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 60 deletions.
8 changes: 4 additions & 4 deletions internal/app/siftool/mount.go
Expand Up @@ -12,13 +12,13 @@ package siftool
import (
"context"

"github.com/apptainer/sif/v2/pkg/sif"
"github.com/apptainer/sif/v2/pkg/user"
)

// Mount mounts the primary system partition of the SIF file at path into mountPath.
func (a *App) Mount(ctx context.Context, path, mountPath string) error {
return sif.MountFUSE(ctx, path, mountPath,
sif.OptMountFUSEStdout(a.opts.out),
sif.OptMountFUSEStderr(a.opts.err),
return user.Mount(ctx, path, mountPath,
user.OptMountStdout(a.opts.out),
user.OptMountStderr(a.opts.err),
)
}
10 changes: 5 additions & 5 deletions internal/app/siftool/unmount.go
Expand Up @@ -12,13 +12,13 @@ package siftool
import (
"context"

"github.com/apptainer/sif/v2/pkg/sif"
"github.com/apptainer/sif/v2/pkg/user"
)

// Unmounts the FUSE mounted filesystem at mountPath.
// Unmounts the filesystem at mountPath.
func (a *App) Unmount(ctx context.Context, mountPath string) error {
return sif.UnmountFUSE(ctx, mountPath,
sif.OptUnmountFUSEStdout(a.opts.out),
sif.OptUnmountFUSEStderr(a.opts.err),
return user.Unmount(ctx, mountPath,
user.OptUnmountStdout(a.opts.out),
user.OptUnmountStderr(a.opts.err),
)
}
4 changes: 2 additions & 2 deletions pkg/siftool/unmount_test.go
Expand Up @@ -16,7 +16,7 @@ import (
"path/filepath"
"testing"

"github.com/apptainer/sif/v2/pkg/sif"
"github.com/apptainer/sif/v2/pkg/user"
)

func Test_command_getUnmount(t *testing.T) {
Expand All @@ -36,7 +36,7 @@ func Test_command_getUnmount(t *testing.T) {
})

testSIF := filepath.Join(corpus, "one-group.sif")
if err := sif.MountFUSE(context.Background(), testSIF, path); err != nil {
if err := user.Mount(context.Background(), testSIF, path); err != nil {
t.Fatal(err)
}

Expand Down
46 changes: 24 additions & 22 deletions pkg/sif/mount.go → pkg/user/mount.go
Expand Up @@ -7,7 +7,7 @@
// LICENSE file distributed with the sources of this project regarding your
// rights to use or distribute this software.

package sif
package user

import (
"context"
Expand All @@ -17,10 +17,12 @@ import (
"os"
"os/exec"
"path/filepath"

"github.com/sylabs/sif/v2/pkg/sif"
)

// mountSquashFS mounts the SquashFS filesystem from path at offset into mountPath.
func mountSquashFS(ctx context.Context, offset int64, path, mountPath string, mo mountFUSEOpts) error {
func mountSquashFS(ctx context.Context, offset int64, path, mountPath string, mo mountOpts) error {
args := []string{
"-o", fmt.Sprintf("ro,offset=%d", offset),
filepath.Clean(path),
Expand All @@ -38,38 +40,38 @@ func mountSquashFS(ctx context.Context, offset int64, path, mountPath string, mo
return nil
}

// mountFUSEOpts accumulates mount options.
type mountFUSEOpts struct {
// mountOpts accumulates mount options.
type mountOpts struct {
stdout io.Writer
stderr io.Writer
squashfusePath string
}

// MountFUSEOpt are used to specify mount options.
type MountFUSEOpt func(*mountFUSEOpts) error
// MountOpt are used to specify mount options.
type MountOpt func(*mountOpts) error

// OptMountStdout writes standard output to w.
func OptMountFUSEStdout(w io.Writer) MountFUSEOpt {
return func(mo *mountFUSEOpts) error {
func OptMountStdout(w io.Writer) MountOpt {
return func(mo *mountOpts) error {
mo.stdout = w
return nil
}
}

// OptMountFUSEStderr writes standard error to w.
func OptMountFUSEStderr(w io.Writer) MountFUSEOpt {
return func(mo *mountFUSEOpts) error {
// OptMountStderr writes standard error to w.
func OptMountStderr(w io.Writer) MountOpt {
return func(mo *mountOpts) error {
mo.stderr = w
return nil
}
}

var errSquashfusePathInvalid = errors.New("squashfuse path must be relative or absolute")

// OptMountFUSESquashfusePath sets an explicit path to the squashfuse binary. The path must be an
// OptMountSquashfusePath sets an explicit path to the squashfuse binary. The path must be an
// absolute or relative path.
func OptMountFUSESquashfusePath(path string) MountFUSEOpt {
return func(mo *mountFUSEOpts) error {
func OptMountSquashfusePath(path string) MountOpt {
return func(mo *mountOpts) error {
if filepath.Base(path) == path {
return errSquashfusePathInvalid
}
Expand All @@ -80,16 +82,16 @@ func OptMountFUSESquashfusePath(path string) MountFUSEOpt {

var errUnsupportedFSType = errors.New("unrecognized filesystem type")

// MountFUSE mounts the primary system partition of the SIF file at path into mountPath.
// Mount mounts the primary system partition of the SIF file at path into mountPath.
//
// MountFUSE may start one or more underlying processes. By default, stdout and stderr of these
// Mount may start one or more underlying processes. By default, stdout and stderr of these
// processes is discarded. To modify this behavior, consider using OptMountStdout and/or
// OptMountStderr.
//
// By default, MountFUSE searches for a squashfuse binary in the directories named by the PATH
// By default, Mount searches for a squashfuse binary in the directories named by the PATH
// environment variable. To override this behavior, consider using OptMountSquashfusePath().
func MountFUSE(ctx context.Context, path, mountPath string, opts ...MountFUSEOpt) error {
mo := mountFUSEOpts{
func Mount(ctx context.Context, path, mountPath string, opts ...MountOpt) error {
mo := mountOpts{
squashfusePath: "squashfuse",
}

Expand All @@ -99,13 +101,13 @@ func MountFUSE(ctx context.Context, path, mountPath string, opts ...MountFUSEOpt
}
}

f, err := LoadContainerFromPath(path, OptLoadWithFlag(os.O_RDONLY))
f, err := sif.LoadContainerFromPath(path, sif.OptLoadWithFlag(os.O_RDONLY))
if err != nil {
return fmt.Errorf("failed to load image: %w", err)
}
defer func() { _ = f.UnloadContainer() }()

d, err := f.GetDescriptor(WithPartitionType(PartPrimSys))
d, err := f.GetDescriptor(sif.WithPartitionType(sif.PartPrimSys))
if err != nil {
return fmt.Errorf("failed to get partition descriptor: %w", err)
}
Expand All @@ -116,7 +118,7 @@ func MountFUSE(ctx context.Context, path, mountPath string, opts ...MountFUSEOpt
}

switch fs {
case FsSquash:
case sif.FsSquash:
return mountSquashFS(ctx, d.Offset(), path, mountPath, mo)
default:
return errUnsupportedFSType
Expand Down
40 changes: 20 additions & 20 deletions pkg/sif/unmount.go → pkg/user/unmount.go
Expand Up @@ -7,7 +7,7 @@
// LICENSE file distributed with the sources of this project regarding your
// rights to use or distribute this software.

package sif
package user

import (
"context"
Expand All @@ -19,7 +19,7 @@ import (
)

// unmountSquashFS unmounts the filesystem at mountPath.
func unmountSquashFS(ctx context.Context, mountPath string, uo unmountFUSEOpts) error {
func unmountSquashFS(ctx context.Context, mountPath string, uo unmountOpts) error {
args := []string{
"-u",
filepath.Clean(mountPath),
Expand All @@ -35,37 +35,37 @@ func unmountSquashFS(ctx context.Context, mountPath string, uo unmountFUSEOpts)
return nil
}

// unmountFUSEOpts accumulates unmount options.
type unmountFUSEOpts struct {
// unmountOpts accumulates unmount options.
type unmountOpts struct {
stdout io.Writer
stderr io.Writer
fusermountPath string
}

// UnmountFUSEOpt are used to specify unmount options.
type UnmountFUSEOpt func(*unmountFUSEOpts) error
// UnmountOpt are used to specify unmount options.
type UnmountOpt func(*unmountOpts) error

// OptUnmountFUSEStdout writes standard output to w.
func OptUnmountFUSEStdout(w io.Writer) UnmountFUSEOpt {
return func(mo *unmountFUSEOpts) error {
// OptUnmountStdout writes standard output to w.
func OptUnmountStdout(w io.Writer) UnmountOpt {
return func(mo *unmountOpts) error {
mo.stdout = w
return nil
}
}

// OptUnmountFUSEStderr writes standard error to w.
func OptUnmountFUSEStderr(w io.Writer) UnmountFUSEOpt {
return func(mo *unmountFUSEOpts) error {
// OptUnmountStderr writes standard error to w.
func OptUnmountStderr(w io.Writer) UnmountOpt {
return func(mo *unmountOpts) error {
mo.stderr = w
return nil
}
}

var errFusermountPathInvalid = errors.New("fusermount path must be relative or absolute")

// OptUnmountFUSEFusermountPath sets the path to the fusermount binary.
func OptUnmountFUSEFusermountPath(path string) UnmountFUSEOpt {
return func(mo *unmountFUSEOpts) error {
// OptUnmountFusermountPath sets the path to the fusermount binary.
func OptUnmountFusermountPath(path string) UnmountOpt {
return func(mo *unmountOpts) error {
if filepath.Base(path) == path {
return errFusermountPathInvalid
}
Expand All @@ -74,16 +74,16 @@ func OptUnmountFUSEFusermountPath(path string) UnmountFUSEOpt {
}
}

// UnmountFUSE unmounts the FUSE mounted filesystem at mountPath.
// Unmount unmounts the filesystem at mountPath.
//
// UnmountFUSE may start one or more underlying processes. By default, stdout and stderr of these
// Unmount may start one or more underlying processes. By default, stdout and stderr of these
// processes is discarded. To modify this behavior, consider using OptUnmountStdout and/or
// OptUnmountStderr.
//
// By default, UnmountFUSE searches for a fusermount binary in the directories named by the PATH
// By default, Unmount searches for a fusermount binary in the directories named by the PATH
// environment variable. To override this behavior, consider using OptUnmountFusermountPath().
func UnmountFUSE(ctx context.Context, mountPath string, opts ...UnmountFUSEOpt) error {
uo := unmountFUSEOpts{
func Unmount(ctx context.Context, mountPath string, opts ...UnmountOpt) error {
uo := unmountOpts{
fusermountPath: "fusermount",
}

Expand Down
16 changes: 9 additions & 7 deletions pkg/sif/unmount_test.go → pkg/user/unmount_test.go
Expand Up @@ -7,7 +7,7 @@
// LICENSE file distributed with the sources of this project regarding your
// rights to use or distribute this software.

package sif
package user

import (
"bufio"
Expand All @@ -21,7 +21,9 @@ import (
"testing"
)

func Test_UnmountFUSE(t *testing.T) {
var corpus = filepath.Join("..", "..", "test", "images")

func Test_Unmount(t *testing.T) {
if _, err := exec.LookPath("squashfuse"); err != nil {
t.Skip(" not found, skipping mount tests")
}
Expand All @@ -42,7 +44,7 @@ func Test_UnmountFUSE(t *testing.T) {
name string
mountSIF string
mountPath string
opts []UnmountFUSEOpt
opts []UnmountOpt
wantErr bool
wantUnmounted bool
}{
Expand All @@ -69,28 +71,28 @@ func Test_UnmountFUSE(t *testing.T) {
name: "FusermountBare",
mountSIF: "",
mountPath: path,
opts: []UnmountFUSEOpt{OptUnmountFUSEFusermountPath("fusermount")},
opts: []UnmountOpt{OptUnmountFusermountPath("fusermount")},
wantErr: true,
},
{
name: "FusermountValid",
mountSIF: filepath.Join(corpus, "one-group.sif"),
mountPath: path,
opts: []UnmountFUSEOpt{OptUnmountFUSEFusermountPath(fusermountPath)},
opts: []UnmountOpt{OptUnmountFusermountPath(fusermountPath)},
wantErr: false,
wantUnmounted: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.mountSIF != "" {
err := MountFUSE(context.Background(), tt.mountSIF, path)
err := Mount(context.Background(), tt.mountSIF, path)
if err != nil {
t.Fatal(err)
}
}

err := UnmountFUSE(context.Background(), tt.mountPath, tt.opts...)
err := Unmount(context.Background(), tt.mountPath, tt.opts...)

if err != nil && !tt.wantErr {
t.Errorf("Unexpected error: %s", err)
Expand Down

0 comments on commit 683f227

Please sign in to comment.