Skip to content

Commit

Permalink
Merge pull request #211 from tri-adam/user-package
Browse files Browse the repository at this point in the history
Move mount/unmount to user package
  • Loading branch information
tri-adam authored Apr 25, 2022
2 parents fd71e8a + 72d5fc5 commit c40ca61
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
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ package siftool
import (
"context"

"github.com/sylabs/sif/v2/pkg/sif"
"github.com/sylabs/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
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ package siftool
import (
"context"

"github.com/sylabs/sif/v2/pkg/sif"
"github.com/sylabs/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
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"path/filepath"
"testing"

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

func Test_command_getUnmount(t *testing.T) {
Expand All @@ -32,7 +32,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
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,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 @@ -13,10 +13,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 @@ -34,38 +36,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 @@ -76,16 +78,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 @@ -95,13 +97,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 @@ -112,7 +114,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
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,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 @@ -15,7 +15,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 @@ -31,37 +31,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 @@ -70,16 +70,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
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,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 @@ -17,7 +17,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 @@ -38,7 +40,7 @@ func Test_UnmountFUSE(t *testing.T) {
name string
mountSIF string
mountPath string
opts []UnmountFUSEOpt
opts []UnmountOpt
wantErr bool
wantUnmounted bool
}{
Expand All @@ -65,28 +67,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 c40ca61

Please sign in to comment.