Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use either "trusted.overlay.opaque" or "user.overlay.opaque" #33

Merged
merged 2 commits into from
Aug 24, 2022
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
15 changes: 11 additions & 4 deletions fs/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,10 @@ const (
type Option func(*options)

type options struct {
getSources source.GetSources
resolveHandlers map[string]remote.Handler
metadataStore metadata.Store
getSources source.GetSources
resolveHandlers map[string]remote.Handler
metadataStore metadata.Store
overlayOpaqueType layer.OverlayOpaqueType
}

func WithGetSources(s source.GetSources) Option {
Expand All @@ -108,6 +109,12 @@ func WithMetadataStore(metadataStore metadata.Store) Option {
}
}

func WithOverlayOpaqueType(overlayOpaqueType layer.OverlayOpaqueType) Option {
return func(opts *options) {
opts.overlayOpaqueType = overlayOpaqueType
}
}

func NewFilesystem(root string, cfg config.Config, opts ...Option) (_ snapshot.FileSystem, err error) {
var fsOpts options
for _, o := range opts {
Expand Down Expand Up @@ -143,7 +150,7 @@ func NewFilesystem(root string, cfg config.Config, opts ...Option) (_ snapshot.F
}

tm := task.NewBackgroundTaskManager(maxConcurrency, 5*time.Second)
r, err := layer.NewResolver(root, tm, cfg, fsOpts.resolveHandlers, metadataStore, store)
r, err := layer.NewResolver(root, tm, cfg, fsOpts.resolveHandlers, metadataStore, store, fsOpts.overlayOpaqueType)
if err != nil {
return nil, errors.Wrapf(err, "failed to setup resolver")
}
Expand Down
7 changes: 5 additions & 2 deletions fs/layer/layer.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,12 @@ type Resolver struct {
config config.Config
metadataStore metadata.Store
artifactStore content.Storage
overlayOpaqueType OverlayOpaqueType
}

// NewResolver returns a new layer resolver.
func NewResolver(root string, backgroundTaskManager *task.BackgroundTaskManager, cfg config.Config, resolveHandlers map[string]remote.Handler, metadataStore metadata.Store, artifactStore content.Storage) (*Resolver, error) {
func NewResolver(root string, backgroundTaskManager *task.BackgroundTaskManager, cfg config.Config, resolveHandlers map[string]remote.Handler,
metadataStore metadata.Store, artifactStore content.Storage, overlayOpaqueType OverlayOpaqueType) (*Resolver, error) {
resolveResultEntry := cfg.ResolveResultEntry
if resolveResultEntry == 0 {
resolveResultEntry = defaultResolveResultEntry
Expand Down Expand Up @@ -177,6 +179,7 @@ func NewResolver(root string, backgroundTaskManager *task.BackgroundTaskManager,
resolveLock: new(namedmutex.NamedMutex),
metadataStore: metadataStore,
artifactStore: artifactStore,
overlayOpaqueType: overlayOpaqueType,
}, nil
}

Expand Down Expand Up @@ -521,7 +524,7 @@ func (l *layer) RootNode(baseInode uint32) (fusefs.InodeEmbedder, error) {
if l.r == nil {
return nil, fmt.Errorf("layer hasn't been verified yet")
}
return newNode(l.desc.Digest, l.r, l.blob, baseInode)
return newNode(l.desc.Digest, l.r, l.blob, baseInode, l.resolver.overlayOpaqueType)
}

func (l *layer) ReadAt(p []byte, offset int64, opts ...remote.Option) (int, error) {
Expand Down
44 changes: 31 additions & 13 deletions fs/layer/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,19 +74,36 @@ const (
stateDirMode = syscall.S_IFDIR | 0500 // dr-x------
)

var opaqueXattrs = []string{"trusted.overlay.opaque", "user.overlay.opaque"}
type OverlayOpaqueType int

func newNode(layerDgst digest.Digest, r reader.Reader, blob remote.Blob, baseInode uint32) (fusefs.InodeEmbedder, error) {
const (
OverlayOpaqueAll OverlayOpaqueType = iota
OverlayOpaqueTrusted
OverlayOpaqueUser
)

var opaqueXattrs = map[OverlayOpaqueType][]string{
OverlayOpaqueAll: {"trusted.overlay.opaque", "user.overlay.opaque"},
OverlayOpaqueTrusted: {"trusted.overlay.opaque"},
OverlayOpaqueUser: {"user.overlay.opaque"},
}

func newNode(layerDgst digest.Digest, r reader.Reader, blob remote.Blob, baseInode uint32, opaque OverlayOpaqueType) (fusefs.InodeEmbedder, error) {
rootID := r.Metadata().RootID()
rootAttr, err := r.Metadata().GetAttr(rootID)
if err != nil {
return nil, err
}
opq, ok := opaqueXattrs[opaque]
if !ok {
return nil, fmt.Errorf("unknown overlay opaque type")
}
ffs := &fs{
r: r,
layerDigest: layerDgst,
baseInode: baseInode,
rootID: rootID,
r: r,
layerDigest: layerDgst,
baseInode: baseInode,
rootID: rootID,
opaqueXattrs: opq,
}
ffs.s = ffs.newState(layerDgst, blob)
return &node{
Expand All @@ -98,11 +115,12 @@ func newNode(layerDgst digest.Digest, r reader.Reader, blob remote.Blob, baseIno

// fs contains global metadata used by nodes
type fs struct {
r reader.Reader
s *state
layerDigest digest.Digest
baseInode uint32
rootID uint32
r reader.Reader
s *state
layerDigest digest.Digest
baseInode uint32
rootID uint32
opaqueXattrs []string
}

func (fs *fs) inodeOfState() uint64 {
Expand Down Expand Up @@ -338,7 +356,7 @@ var _ = (fusefs.NodeGetxattrer)((*node)(nil))
func (n *node) Getxattr(ctx context.Context, attr string, dest []byte) (uint32, syscall.Errno) {
ent := n.attr
opq := n.isOpaque()
for _, opaqueXattr := range opaqueXattrs {
for _, opaqueXattr := range n.fs.opaqueXattrs {
if attr == opaqueXattr && opq {
// This node is an opaque directory so give overlayfs-compliant indicator.
if len(dest) < len(opaqueXattrValue) {
Expand All @@ -364,7 +382,7 @@ func (n *node) Listxattr(ctx context.Context, dest []byte) (uint32, syscall.Errn
var attrs []byte
if opq {
// This node is an opaque directory so add overlayfs-compliant indicator.
for _, opaqueXattr := range opaqueXattrs {
for _, opaqueXattr := range n.fs.opaqueXattrs {
attrs = append(attrs, []byte(opaqueXattr+"\x00")...)
}
}
Expand Down
30 changes: 20 additions & 10 deletions fs/layer/testutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ func makeNodeReader(t *testing.T, contents []byte, spanSize int64, factory metad
t.Fatalf("failed to make new reader: %v", err)
}
r := vr.GetReader()
rootNode := getRootNode(t, r)
rootNode := getRootNode(t, r, OverlayOpaqueAll)
var eo fuse.EntryOut
inode, errno := rootNode.Lookup(context.Background(), testName, &eo)
if errno != 0 {
Expand All @@ -199,6 +199,19 @@ func makeNodeReader(t *testing.T, contents []byte, spanSize int64, factory metad
}

func testExistence(t *testing.T, factory metadata.Store) {
for _, o := range []OverlayOpaqueType{OverlayOpaqueAll, OverlayOpaqueTrusted, OverlayOpaqueUser} {
testExistenceWithOpaque(t, factory, o)
}
}

func testExistenceWithOpaque(t *testing.T, factory metadata.Store, opaque OverlayOpaqueType) {
hasOpaque := func(entry string) check {
return func(t *testing.T, root *node) {
for _, k := range opaqueXattrs[opaque] {
hasNodeXattrs(entry, k, opaqueXattrValue)(t, root)
}
}
}
tests := []struct {
name string
in []testutil.TarEntry
Expand Down Expand Up @@ -235,8 +248,7 @@ func testExistence(t *testing.T, factory metadata.Store) {
testutil.File("foo/.wh..wh..opq", ""),
},
want: []check{
hasNodeXattrs("foo/", opaqueXattrs[0], opaqueXattrValue),
hasNodeXattrs("foo/", opaqueXattrs[1], opaqueXattrValue),
hasOpaque("foo/"),
fileNotExist("foo/.wh..wh..opq"),
},
},
Expand All @@ -248,8 +260,7 @@ func testExistence(t *testing.T, factory metadata.Store) {
testutil.File("foo/bar.txt", "test"),
},
want: []check{
hasNodeXattrs("foo/", opaqueXattrs[0], opaqueXattrValue),
hasNodeXattrs("foo/", opaqueXattrs[1], opaqueXattrValue),
hasOpaque("foo/"),
hasFileDigest("foo/bar.txt", digestFor("test")),
fileNotExist("foo/.wh..wh..opq"),
},
Expand All @@ -261,8 +272,7 @@ func testExistence(t *testing.T, factory metadata.Store) {
testutil.File("foo/.wh..wh..opq", ""),
},
want: []check{
hasNodeXattrs("foo/", opaqueXattrs[0], opaqueXattrValue),
hasNodeXattrs("foo/", opaqueXattrs[1], opaqueXattrValue),
hasOpaque("foo/"),
hasNodeXattrs("foo/", "SCHILY.xattr.foo", "bar"),
fileNotExist("foo/.wh..wh..opq"),
},
Expand Down Expand Up @@ -326,7 +336,7 @@ func testExistence(t *testing.T, factory metadata.Store) {
}
r := vr.GetReader()
defer r.Close()
rootNode := getRootNode(t, r)
rootNode := getRootNode(t, r, opaque)
for _, want := range tt.want {
want(t, rootNode)
}
Expand All @@ -335,8 +345,8 @@ func testExistence(t *testing.T, factory metadata.Store) {
}
}

func getRootNode(t *testing.T, r reader.Reader) *node {
rootNode, err := newNode(testStateLayerDigest, &testReader{r}, &testBlobState{10, 5}, 100)
func getRootNode(t *testing.T, r reader.Reader, opaque OverlayOpaqueType) *node {
rootNode, err := newNode(testStateLayerDigest, &testReader{r}, &testBlobState{10, 5}, 100, opaque)
if err != nil {
t.Fatalf("failed to get root node: %v", err)
}
Expand Down
12 changes: 10 additions & 2 deletions service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (
"path/filepath"

socifs "github.com/awslabs/soci-snapshotter/fs"
"github.com/awslabs/soci-snapshotter/fs/layer"
"github.com/awslabs/soci-snapshotter/fs/source"
"github.com/awslabs/soci-snapshotter/service/resolver"
snbase "github.com/awslabs/soci-snapshotter/snapshot"
Expand Down Expand Up @@ -87,12 +88,19 @@ func NewSociSnapshotterService(ctx context.Context, root string, config *Config,
// Use RegistryHosts based on ResolverConfig and keychain
hosts = resolver.RegistryHostsFromConfig(resolver.Config(config.ResolverConfig), sOpts.credsFuncs...)
}

userxattr, err := overlayutils.NeedsUserXAttr(snapshotterRoot(root))
if err != nil {
log.G(ctx).WithError(err).Warnf("cannot detect whether \"userxattr\" option needs to be used, assuming to be %v", userxattr)
}
opq := layer.OverlayOpaqueTrusted
if userxattr {
opq = layer.OverlayOpaqueUser
}
// Configure filesystem and snapshotter
fsOpts := append(sOpts.fsOpts, socifs.WithGetSources(sources(
sourceFromCRILabels(hosts), // provides source info based on CRI labels
source.FromDefaultLabels(hosts), // provides source info based on default labels
)))
)), socifs.WithOverlayOpaqueType(opq))
fs, err := socifs.NewFilesystem(fsRoot(root), config.Config, fsOpts...)
if err != nil {
log.G(ctx).WithError(err).Fatalf("failed to configure filesystem")
Expand Down