overlay: add an optional label of upperdir location of each snapshot

Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
This commit is contained in:
ktock 2021-06-17 17:38:15 +09:00 committed by Kohei Tokunaga
parent ba70277fb7
commit 67406b3732
2 changed files with 68 additions and 14 deletions

View File

@ -37,9 +37,15 @@ import (
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
// upperdirKey is a key of an optional lablel to each snapshot.
// This optional label of a snapshot contains the location of "upperdir" where
// the change set between this snapshot and its parent is stored.
const upperdirKey = "containerd.io/snapshot/overlay.upperdir"
// SnapshotterConfig is used to configure the overlay snapshotter instance // SnapshotterConfig is used to configure the overlay snapshotter instance
type SnapshotterConfig struct { type SnapshotterConfig struct {
asyncRemove bool asyncRemove bool
upperdirLabel bool
} }
// Opt is an option to configure the overlay snapshotter // Opt is an option to configure the overlay snapshotter
@ -54,12 +60,22 @@ func AsynchronousRemove(config *SnapshotterConfig) error {
return nil return nil
} }
// WithUpperdirLabel adds as an optional label
// "containerd.io/snapshot/overlay.upperdir". This stores the location
// of the upperdir that contains the changeset between the labelled
// snapshot and its parent.
func WithUpperdirLabel(config *SnapshotterConfig) error {
config.upperdirLabel = true
return nil
}
type snapshotter struct { type snapshotter struct {
root string root string
ms *storage.MetaStore ms *storage.MetaStore
asyncRemove bool asyncRemove bool
indexOff bool upperdirLabel bool
userxattr bool // whether to enable "userxattr" mount option indexOff bool
userxattr bool // whether to enable "userxattr" mount option
} }
// NewSnapshotter returns a Snapshotter which uses overlayfs. The overlayfs // NewSnapshotter returns a Snapshotter which uses overlayfs. The overlayfs
@ -105,11 +121,12 @@ func NewSnapshotter(root string, opts ...Opt) (snapshots.Snapshotter, error) {
} }
return &snapshotter{ return &snapshotter{
root: root, root: root,
ms: ms, ms: ms,
asyncRemove: config.asyncRemove, asyncRemove: config.asyncRemove,
indexOff: indexOff, upperdirLabel: config.upperdirLabel,
userxattr: userxattr, indexOff: indexOff,
userxattr: userxattr,
}, nil }, nil
} }
@ -124,11 +141,18 @@ func (o *snapshotter) Stat(ctx context.Context, key string) (snapshots.Info, err
return snapshots.Info{}, err return snapshots.Info{}, err
} }
defer t.Rollback() defer t.Rollback()
_, info, _, err := storage.GetInfo(ctx, key) id, info, _, err := storage.GetInfo(ctx, key)
if err != nil { if err != nil {
return snapshots.Info{}, err return snapshots.Info{}, err
} }
if o.upperdirLabel {
if info.Labels == nil {
info.Labels = make(map[string]string)
}
info.Labels[upperdirKey] = o.upperPath(id)
}
return info, nil return info, nil
} }
@ -148,6 +172,17 @@ func (o *snapshotter) Update(ctx context.Context, info snapshots.Info, fieldpath
return snapshots.Info{}, err return snapshots.Info{}, err
} }
if o.upperdirLabel {
id, _, _, err := storage.GetInfo(ctx, info.Name)
if err != nil {
return snapshots.Info{}, err
}
if info.Labels == nil {
info.Labels = make(map[string]string)
}
info.Labels[upperdirKey] = o.upperPath(id)
}
return info, nil return info, nil
} }
@ -292,6 +327,19 @@ func (o *snapshotter) Walk(ctx context.Context, fn snapshots.WalkFunc, fs ...str
return err return err
} }
defer t.Rollback() defer t.Rollback()
if o.upperdirLabel {
return storage.WalkInfo(ctx, func(ctx context.Context, info snapshots.Info) error {
id, _, _, err := storage.GetInfo(ctx, info.Name)
if err != nil {
return err
}
if info.Labels == nil {
info.Labels = make(map[string]string)
}
info.Labels[upperdirKey] = o.upperPath(id)
return fn(ctx, info)
}, fs...)
}
return storage.WalkInfo(ctx, fn, fs...) return storage.WalkInfo(ctx, fn, fs...)
} }

View File

@ -29,7 +29,8 @@ import (
// Config represents configuration for the overlay plugin. // Config represents configuration for the overlay plugin.
type Config struct { type Config struct {
// Root directory for the plugin // Root directory for the plugin
RootPath string `toml:"root_path"` RootPath string `toml:"root_path"`
UpperdirLabel bool `toml:"upperdir_label"`
} }
func init() { func init() {
@ -50,8 +51,13 @@ func init() {
root = config.RootPath root = config.RootPath
} }
var oOpts []overlay.Opt
if config.UpperdirLabel {
oOpts = append(oOpts, overlay.WithUpperdirLabel)
}
ic.Meta.Exports["root"] = root ic.Meta.Exports["root"] = root
return overlay.NewSnapshotter(root, overlay.AsynchronousRemove) return overlay.NewSnapshotter(root, append(oOpts, overlay.AsynchronousRemove)...)
}, },
}) })
} }