Skip to content

Commit

Permalink
temp thing
Browse files Browse the repository at this point in the history
Signed-off-by: David Son <[email protected]>
  • Loading branch information
sondavidb committed Oct 13, 2024
1 parent 7f2fd08 commit 8ba6ca2
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 60 deletions.
90 changes: 38 additions & 52 deletions fs/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ package fs
import (
"context"
"fmt"
"io"
golog "log"
"net/http"
"os"
Expand Down Expand Up @@ -459,14 +460,16 @@ func (fs *filesystem) getSociContext(ctx context.Context, imageRef, indexDigest,
return c, err
}

func (fs *filesystem) getIDMappedMountpoint(mountpoint, activeLayerKey string) string {
func getIDMappedMountpoint(mountpoint, activeLayerKey string) string {
d := filepath.Dir(mountpoint)
return filepath.Join(fmt.Sprintf("%s_%s", d, activeLayerKey), "fs")
}

func (fs *filesystem) IDMapMount(ctx context.Context, mountpoint, activeLayerKey string, idmapper idtools.IDMap) (string, error) {
newMountpoint := fs.getIDMappedMountpoint(mountpoint, activeLayerKey)
log.G(ctx).WithField("mountpoint", newMountpoint).Info("creating remote id-mapped mount")
newMountpoint := getIDMappedMountpoint(mountpoint, activeLayerKey)
logger := log.G(ctx).WithField("mountpoint", newMountpoint)

logger.Debug("creating remote id-mapped mount")
if err := os.Mkdir(filepath.Dir(newMountpoint), 0700); err != nil {
return "", err
}
Expand All @@ -478,7 +481,7 @@ func (fs *filesystem) IDMapMount(ctx context.Context, mountpoint, activeLayerKey
l := fs.layer[mountpoint]
if l == nil {
fs.layerMu.Unlock()
log.G(ctx).WithField("mountpoint", newMountpoint).Info("failed to create remote id-mapped mount")
logger.Debug("failed to create remote id-mapped mount")
return "", errdefs.ErrNotFound
}
fs.layer[newMountpoint] = l
Expand All @@ -488,47 +491,24 @@ func (fs *filesystem) IDMapMount(ctx context.Context, mountpoint, activeLayerKey
return "", err
}

rawFS := fusefs.NewNodeFS(node, &fusefs.Options{
AttrTimeout: &fs.attrTimeout,
EntryTimeout: &fs.entryTimeout,
NegativeTimeout: &fs.negativeTimeout,
NullPermissions: true,
})
mountOpts := &fuse.MountOptions{
AllowOther: true, // allow users other than root&mounter to access fs
FsName: "soci", // name this filesystem as "soci"
Debug: fs.debug,
DisableXAttrs: l.DisableXAttrs(),
Options: []string{"default_permissions", "ro"},
}
if _, err := exec.LookPath(fusermountBin); err == nil {
mountOpts.Options = []string{"suid"} // option for fusermount; allow setuid inside container
} else {
log.G(ctx).WithError(err).Infof("%s not installed; trying direct mount", fusermountBin)
mountOpts.DirectMount = true
}
server, err := fuse.NewServer(rawFS, newMountpoint, mountOpts)
if err != nil {
log.G(ctx).WithError(err).Debug("failed to make filesystem server")
return "", err
}

go server.Serve()
fuseLogger := log.L.
WithField("mountpoint", mountpoint).
WriterLevel(logrus.TraceLevel)

log.G(ctx).WithField("mountpoint", newMountpoint).Info("successfully created remote mountpoint")
return newMountpoint, server.WaitMount()
return newMountpoint, fs.setupFuseServer(ctx, newMountpoint, node, l, fuseLogger, nil)
}

func (fs *filesystem) IDMapMountLocal(ctx context.Context, mountpoint, activeLayerKey string, idmapper idtools.IDMap) (string, error) {
newMountpoint := fs.getIDMappedMountpoint(mountpoint, activeLayerKey)
log.G(ctx).WithField("mountpoint", newMountpoint).Info("creating local id-mapped mount")
newMountpoint := getIDMappedMountpoint(mountpoint, activeLayerKey)
logger := log.G(ctx).WithField("mountpoint", newMountpoint)

logger.Debug("creating local id-mapped mount")
if err := idtools.RemapDir(ctx, mountpoint, newMountpoint, idmapper); err != nil {
log.G(ctx).WithField("mountpoint", newMountpoint).Errorf("failed to create local mount: %v", err)
logger.Errorf("failed to create local mount: %v", err)
return "", err
}

log.G(ctx).WithField("mountpoint", newMountpoint).Info("successfully created local mountpoint")
logger.Debug("successfully created local mountpoint")
return newMountpoint, nil
}

Expand Down Expand Up @@ -660,6 +640,16 @@ func (fs *filesystem) Mount(ctx context.Context, mountpoint string, labels map[s
fs.layerMu.Unlock()
fs.metricsController.Add(mountpoint, l)

// Pass in a logger to go-fuse with the layer digest
// The go-fuse logs are useful for tracing exactly what's happening at the fuse level.
fuseLogger := log.L.
WithField("layerDigest", labels[ctdsnapshotters.TargetLayerDigestLabel]).
WriterLevel(logrus.TraceLevel)

return fs.setupFuseServer(ctx, mountpoint, node, l, fuseLogger, c)
}

func (fs *filesystem) setupFuseServer(ctx context.Context, mountpoint string, node fusefs.InodeEmbedder, l layer.Layer, logger *io.PipeWriter, c *sociContext) error {
// mount the node to the specified mountpoint
// TODO: bind mount the state directory as a read-only fs on snapshotter's side
rawFS := fusefs.NewNodeFS(node, &fusefs.Options{
Expand All @@ -668,11 +658,6 @@ func (fs *filesystem) Mount(ctx context.Context, mountpoint string, labels map[s
NegativeTimeout: &fs.negativeTimeout,
NullPermissions: true,
})
// Pass in a logger to go-fuse with the layer digest
// The go-fuse logs are useful for tracing exactly what's happening at the fuse level.
logger := log.L.
WithField("layerDigest", labels[ctdsnapshotters.TargetLayerDigestLabel]).
WriterLevel(logrus.TraceLevel)
mountOpts := &fuse.MountOptions{
AllowOther: true, // allow users other than root&mounter to access fs
FsName: "soci", // name this filesystem as "soci"
Expand All @@ -684,25 +669,26 @@ func (fs *filesystem) Mount(ctx context.Context, mountpoint string, labels map[s
if _, err := exec.LookPath(fusermountBin); err == nil {
mountOpts.Options = []string{"suid"} // option for fusermount; allow setuid inside container
} else {
log.G(ctx).WithError(err).Infof("%s not installed; trying direct mount", fusermountBin)
log.G(ctx).WithField("binary", fusermountBin).WithError(err).Info("fuse binary not installed; trying direct mount")
mountOpts.DirectMount = true
}
server, err := fuse.NewServer(rawFS, mountpoint, mountOpts)
if err != nil {
log.G(ctx).WithError(err).Debug("failed to make filesystem server")
retErr = err
return
log.G(ctx).WithError(err).Error("failed to make filesystem server")
return err
}

go server.Serve()

// Send a signal to the background fetcher that a new image is being mounted
// and to pause all background fetches.
c.bgFetchPauseOnce.Do(func() {
if fs.bgFetcher != nil {
fs.bgFetcher.Pause()
}
})
if c != nil {
// Send a signal to the background fetcher that a new image is being mounted
// and to pause all background fetches.
c.bgFetchPauseOnce.Do(func() {
if fs.bgFetcher != nil {
fs.bgFetcher.Pause()
}
})
}

return server.WaitMount()
}
Expand Down
5 changes: 3 additions & 2 deletions idtools/idmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func LoadIDMap(id string, labels map[string]string) (IDMap, error) {
return idmap, nil
}

// ToHost returns the host user ID pair for the container ID pair.
// ToHost returns the mapped host user ID pair
func (i IDMap) ToHost(pair User) (User, error) {
var (
target User
Expand Down Expand Up @@ -146,8 +146,9 @@ func RemapDir(ctx context.Context, originalMountpoint, newMountpoint string, idM
return err
}

// It would be preferred to use something like continuity.CopyDir, but we need to avoid copying hardlinks,
// unless there is a more efficient way to ensure we don't id-map the same inode multiple times
if err := exec.Command("cp", "-R", originalMountpoint, idmappedSnapshotBase).Run(); err != nil {
// if err := continuity.CopyDir(newMountpoint, originalMountpoint); err != nil {
return err
}
return filepath.Walk(newMountpoint, chown(idMap))
Expand Down
14 changes: 8 additions & 6 deletions snapshot/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,10 @@ func NewSnapshotter(ctx context.Context, root string, targetFs FileSystem, opts
minLayerSize: config.minLayerSize,
allowInvalidMountsOnRestart: config.allowInvalidMountsOnRestart,
allowIDMap: config.allowIDMap,
idmapped: make(map[string]interface{}),
}

if o.allowIDMap {
o.idmapped = make(map[string]interface{})
}

if err := o.restoreRemoteSnapshot(ctx); err != nil {
Expand Down Expand Up @@ -854,10 +857,9 @@ func (o *snapshotter) mounts(ctx context.Context, s storage.Snapshot, checkKey s
func (o *snapshotter) getParentPaths(ctx context.Context, s storage.Snapshot) ([]string, error) {
parentPaths := make([]string, len(s.ParentIDs))

for i := range s.ParentIDs {
id := s.ParentIDs[i]
for i, id := range s.ParentIDs {
if _, ok := o.idmapped[s.ID]; ok {
id = fmt.Sprintf("%s_%s", s.ParentIDs[i], s.ID)
id = fmt.Sprintf("%s_%s", id, s.ID)
}
parentPaths[i] = o.upperPath(id)
}
Expand All @@ -866,7 +868,7 @@ func (o *snapshotter) getParentPaths(ctx context.Context, s storage.Snapshot) ([
}

func (o *snapshotter) createIDMapMounts(ctx context.Context, s storage.Snapshot, idmap idtools.IDMap) error {
log.G(ctx).Infof("mapping ids")
log.G(ctx).Debug("mapping ids")

for _, id := range s.ParentIDs {
err := o.createIDMapMount(ctx, o.upperPath(id), s.ID, idmap)
Expand All @@ -882,7 +884,7 @@ func (o *snapshotter) createIDMapMount(ctx context.Context, path, id string, idm
// s.ID is the shortest unique identifier for each new container,
// so append it to the end of the new mountpoint
_, err := o.fs.IDMapMount(ctx, path, id, idmap)
if err == errdefs.ErrNotFound {
if errdefs.IsNotFound(err) {
// Remote mount failed, attempt to create a local id-mapped mount

// Cleanup dirty snapshot folder — perhaps we can have a return cleanup func?
Expand Down

0 comments on commit 8ba6ca2

Please sign in to comment.