diff --git a/rootfs/apply.go b/rootfs/apply.go index 74b7d6a..d64ee94 100644 --- a/rootfs/apply.go +++ b/rootfs/apply.go @@ -30,6 +30,7 @@ type Mounter interface { func ApplyLayer(snapshots snapshot.Snapshotter, mounter Mounter, rd io.Reader, parent digest.Digest) (digest.Digest, error) { digester := digest.Canonical.Digester() // used to calculate diffID. rd = io.TeeReader(rd, digester.Hash()) + ctx := context.TODO() // create a temporary directory to work from, needs to be on same // filesystem. Probably better if this shared but we'll use a tempdir, for @@ -45,13 +46,13 @@ func ApplyLayer(snapshots snapshot.Snapshotter, mounter Mounter, rd io.Reader, p // layerID (since we don't know the diffID until we are done!). key := dir - mounts, err := snapshots.Prepare(key, parent.String()) + mounts, err := snapshots.Prepare(ctx, key, parent.String()) if err != nil { return "", err } if err := mounter.Mount(mounts...); err != nil { - if err := snapshots.Remove(key); err != nil { + if err := snapshots.Remove(ctx, key); err != nil { log.L.WithError(err).Error("snapshot rollback failed") } return "", err @@ -74,7 +75,7 @@ func ApplyLayer(snapshots snapshot.Snapshotter, mounter Mounter, rd io.Reader, p chainID = identity.ChainID([]digest.Digest{parent, chainID}) } - return diffID, snapshots.Commit(chainID.String(), key) + return diffID, snapshots.Commit(ctx, chainID.String(), key) } // Prepare the root filesystem from the set of layers. Snapshots are created @@ -96,6 +97,7 @@ func Prepare(snapshots snapshot.Snapshotter, mounter Mounter, layers []ocispec.D parent digest.Digest chain []digest.Digest ) + ctx := context.TODO() for _, layer := range layers { // TODO: layer.Digest should not be string @@ -110,7 +112,7 @@ func Prepare(snapshots snapshot.Snapshotter, mounter Mounter, layers []ocispec.D chainLocal := append(chain, diffID) chainID := identity.ChainID(chainLocal) - if _, err := snapshots.Stat(chainID.String()); err == nil { + if _, err := snapshots.Stat(ctx, chainID.String()); err == nil { continue } } diff --git a/snapshot/btrfs/btrfs.go b/snapshot/btrfs/btrfs.go index 032a71c..66481b9 100644 --- a/snapshot/btrfs/btrfs.go +++ b/snapshot/btrfs/btrfs.go @@ -1,6 +1,7 @@ package btrfs import ( + "context" "crypto/sha256" "fmt" "io/ioutil" @@ -48,7 +49,7 @@ func NewSnapshotter(device, root string) (*Snapshotter, error) { // // Should be used for parent resolution, existence checks and to discern // the kind of snapshot. -func (b *Snapshotter) Stat(key string) (snapshot.Info, error) { +func (b *Snapshotter) Stat(ctx context.Context, key string) (snapshot.Info, error) { // resolve the snapshot out of the index. target, err := os.Readlink(filepath.Join(b.root, "index", hash(key))) if err != nil { @@ -119,11 +120,11 @@ func (b *Snapshotter) stat(target string) (snapshot.Info, error) { } -func (b *Snapshotter) Prepare(key, parent string) ([]containerd.Mount, error) { +func (b *Snapshotter) Prepare(ctx context.Context, key, parent string) ([]containerd.Mount, error) { return b.makeActive(key, parent, false) } -func (b *Snapshotter) View(key, parent string) ([]containerd.Mount, error) { +func (b *Snapshotter) View(ctx context.Context, key, parent string) ([]containerd.Mount, error) { return b.makeActive(key, parent, true) } @@ -198,7 +199,7 @@ func (b *Snapshotter) mounts(dir string) ([]containerd.Mount, error) { }, nil } -func (b *Snapshotter) Commit(name, key string) error { +func (b *Snapshotter) Commit(ctx context.Context, name, key string) error { var ( active = filepath.Join(b.root, "active") snapshots = filepath.Join(b.root, "snapshots") @@ -283,19 +284,19 @@ func (b *Snapshotter) Commit(name, key string) error { // called on an read-write or readonly transaction. // // This can be used to recover mounts after calling View or Prepare. -func (b *Snapshotter) Mounts(key string) ([]containerd.Mount, error) { +func (b *Snapshotter) Mounts(ctx context.Context, key string) ([]containerd.Mount, error) { dir := filepath.Join(b.root, "active", hash(key)) return b.mounts(dir) } // Remove abandons the transaction identified by key. All resources // associated with the key will be removed. -func (b *Snapshotter) Remove(key string) error { +func (b *Snapshotter) Remove(ctx context.Context, key string) error { panic("not implemented") } // Walk the committed snapshots. -func (b *Snapshotter) Walk(fn func(snapshot.Info) error) error { +func (b *Snapshotter) Walk(ctx context.Context, fn func(context.Context, snapshot.Info) error) error { // TODO(stevvooe): Copy-pasted almost verbatim from overlay. Really need to // unify the metadata for snapshot implementations. root := filepath.Join(b.root, "index") @@ -325,7 +326,7 @@ func (b *Snapshotter) Walk(fn func(snapshot.Info) error) error { return err } - if err := fn(si); err != nil { + if err := fn(ctx, si); err != nil { return err } diff --git a/snapshot/btrfs/btrfs_test.go b/snapshot/btrfs/btrfs_test.go index eaea77f..31d947d 100644 --- a/snapshot/btrfs/btrfs_test.go +++ b/snapshot/btrfs/btrfs_test.go @@ -1,6 +1,7 @@ package btrfs import ( + "context" "io/ioutil" "os" "os/exec" @@ -34,6 +35,7 @@ func TestBtrfs(t *testing.T) { func TestBtrfsMounts(t *testing.T) { testutil.RequiresRoot(t) + ctx := context.TODO() // create temporary directory for mount point mountPoint, err := ioutil.TempDir("", "containerd-btrfs-test") @@ -56,7 +58,7 @@ func TestBtrfsMounts(t *testing.T) { if err != nil { t.Fatal(err) } - mounts, err := b.Prepare(target, "") + mounts, err := b.Prepare(ctx, target, "") if err != nil { t.Fatal(err) } @@ -92,12 +94,12 @@ func TestBtrfsMounts(t *testing.T) { t.Fatal(err) } - if err := b.Commit(filepath.Join(root, "snapshots/committed"), filepath.Join(root, "test")); err != nil { + if err := b.Commit(ctx, filepath.Join(root, "snapshots/committed"), filepath.Join(root, "test")); err != nil { t.Fatal(err) } target = filepath.Join(root, "test2") - mounts, err = b.Prepare(target, filepath.Join(root, "snapshots/committed")) + mounts, err = b.Prepare(ctx, target, filepath.Join(root, "snapshots/committed")) if err != nil { t.Fatal(err) } @@ -116,7 +118,7 @@ func TestBtrfsMounts(t *testing.T) { t.Fatal(err) } - if err := b.Commit(filepath.Join(root, "snapshots/committed2"), target); err != nil { + if err := b.Commit(ctx, filepath.Join(root, "snapshots/committed2"), target); err != nil { t.Fatal(err) } } diff --git a/snapshot/overlay/overlay.go b/snapshot/overlay/overlay.go index 60735f7..2aba97c 100644 --- a/snapshot/overlay/overlay.go +++ b/snapshot/overlay/overlay.go @@ -1,6 +1,7 @@ package overlay import ( + "context" "fmt" "io/ioutil" "os" @@ -43,7 +44,7 @@ func NewSnapshotter(root string) (*Snapshotter, error) { // // Should be used for parent resolution, existence checks and to discern // the kind of snapshot. -func (o *Snapshotter) Stat(key string) (snapshot.Info, error) { +func (o *Snapshotter) Stat(ctx context.Context, key string) (snapshot.Info, error) { path, err := o.links.get(filepath.Join(o.root, "index", hash(key))) if err != nil { if !os.IsNotExist(err) { @@ -100,7 +101,7 @@ func (o *Snapshotter) stat(path string) (snapshot.Info, error) { }, nil } -func (o *Snapshotter) Prepare(key, parent string) ([]containerd.Mount, error) { +func (o *Snapshotter) Prepare(ctx context.Context, key, parent string) ([]containerd.Mount, error) { active, err := o.newActiveDir(key) if err != nil { return nil, err @@ -113,7 +114,7 @@ func (o *Snapshotter) Prepare(key, parent string) ([]containerd.Mount, error) { return active.mounts(o.links) } -func (o *Snapshotter) View(key, parent string) ([]containerd.Mount, error) { +func (o *Snapshotter) View(ctx context.Context, key, parent string) ([]containerd.Mount, error) { panic("not implemented") } @@ -121,24 +122,24 @@ func (o *Snapshotter) View(key, parent string) ([]containerd.Mount, error) { // called on an read-write or readonly transaction. // // This can be used to recover mounts after calling View or Prepare. -func (o *Snapshotter) Mounts(key string) ([]containerd.Mount, error) { +func (o *Snapshotter) Mounts(ctx context.Context, key string) ([]containerd.Mount, error) { active := o.getActive(key) return active.mounts(o.links) } -func (o *Snapshotter) Commit(name, key string) error { +func (o *Snapshotter) Commit(ctx context.Context, name, key string) error { active := o.getActive(key) return active.commit(name, o.links) } // Remove abandons the transaction identified by key. All resources // associated with the key will be removed. -func (o *Snapshotter) Remove(key string) error { +func (o *Snapshotter) Remove(ctx context.Context, key string) error { panic("not implemented") } // Walk the committed snapshots. -func (o *Snapshotter) Walk(fn func(snapshot.Info) error) error { +func (o *Snapshotter) Walk(ctx context.Context, fn func(context.Context, snapshot.Info) error) error { root := filepath.Join(o.root, "index") return filepath.Walk(root, func(path string, fi os.FileInfo, err error) error { if err != nil { @@ -166,7 +167,7 @@ func (o *Snapshotter) Walk(fn func(snapshot.Info) error) error { return err } - if err := fn(si); err != nil { + if err := fn(ctx, si); err != nil { return err } diff --git a/snapshot/overlay/overlay_test.go b/snapshot/overlay/overlay_test.go index b07fbf8..fbd3e5b 100644 --- a/snapshot/overlay/overlay_test.go +++ b/snapshot/overlay/overlay_test.go @@ -1,6 +1,7 @@ package overlay import ( + "context" "io/ioutil" "os" "path/filepath" @@ -25,6 +26,7 @@ func TestOverlay(t *testing.T) { } func TestOverlayMounts(t *testing.T) { + ctx := context.TODO() root, err := ioutil.TempDir("", "overlay") if err != nil { t.Fatal(err) @@ -35,7 +37,7 @@ func TestOverlayMounts(t *testing.T) { t.Error(err) return } - mounts, err := o.Prepare("/tmp/test", "") + mounts, err := o.Prepare(ctx, "/tmp/test", "") if err != nil { t.Error(err) return @@ -60,6 +62,7 @@ func TestOverlayMounts(t *testing.T) { } func TestOverlayCommit(t *testing.T) { + ctx := context.TODO() root, err := ioutil.TempDir("", "overlay") if err != nil { t.Fatal(err) @@ -71,7 +74,7 @@ func TestOverlayCommit(t *testing.T) { return } key := "/tmp/test" - mounts, err := o.Prepare(key, "") + mounts, err := o.Prepare(ctx, key, "") if err != nil { t.Error(err) return @@ -81,13 +84,14 @@ func TestOverlayCommit(t *testing.T) { t.Error(err) return } - if err := o.Commit("base", key); err != nil { + if err := o.Commit(ctx, "base", key); err != nil { t.Error(err) return } } func TestOverlayOverlayMount(t *testing.T) { + ctx := context.TODO() root, err := ioutil.TempDir("", "overlay") if err != nil { t.Fatal(err) @@ -99,16 +103,16 @@ func TestOverlayOverlayMount(t *testing.T) { return } key := "/tmp/test" - mounts, err := o.Prepare(key, "") + mounts, err := o.Prepare(ctx, key, "") if err != nil { t.Error(err) return } - if err := o.Commit("base", key); err != nil { + if err := o.Commit(ctx, "base", key); err != nil { t.Error(err) return } - if mounts, err = o.Prepare("/tmp/layer2", "base"); err != nil { + if mounts, err = o.Prepare(ctx, "/tmp/layer2", "base"); err != nil { t.Error(err) return } @@ -142,6 +146,7 @@ func TestOverlayOverlayMount(t *testing.T) { func TestOverlayOverlayRead(t *testing.T) { testutil.RequiresRoot(t) + ctx := context.TODO() root, err := ioutil.TempDir("", "overlay") if err != nil { t.Fatal(err) @@ -153,7 +158,7 @@ func TestOverlayOverlayRead(t *testing.T) { return } key := "/tmp/test" - mounts, err := o.Prepare(key, "") + mounts, err := o.Prepare(ctx, key, "") if err != nil { t.Error(err) return @@ -163,11 +168,11 @@ func TestOverlayOverlayRead(t *testing.T) { t.Error(err) return } - if err := o.Commit("base", key); err != nil { + if err := o.Commit(ctx, "base", key); err != nil { t.Error(err) return } - if mounts, err = o.Prepare("/tmp/layer2", "base"); err != nil { + if mounts, err = o.Prepare(ctx, "/tmp/layer2", "base"); err != nil { t.Error(err) return } diff --git a/snapshot/snapshotter.go b/snapshot/snapshotter.go index b8cadfc..4715521 100644 --- a/snapshot/snapshotter.go +++ b/snapshot/snapshotter.go @@ -1,6 +1,7 @@ package snapshot import ( + "context" "io/ioutil" "os" "path/filepath" @@ -148,14 +149,14 @@ type Snapshotter interface { // // Should be used for parent resolution, existence checks and to discern // the kind of snapshot. - Stat(key string) (Info, error) + Stat(ctx context.Context, key string) (Info, error) // Mounts returns the mounts for the active snapshot transaction identified // by key. Can be called on an read-write or readonly transaction. This is // available only for active snapshots. // // This can be used to recover mounts after calling View or Prepare. - Mounts(key string) ([]containerd.Mount, error) + Mounts(ctx context.Context, key string) ([]containerd.Mount, error) // Prepare creates an active snapshot identified by key descending from the // provided parent. The returned mounts can be used to mount the snapshot @@ -171,7 +172,7 @@ type Snapshotter interface { // one is done with the transaction, Remove should be called on the key. // // Multiple calls to Prepare or View with the same key should fail. - Prepare(key, parent string) ([]containerd.Mount, error) + Prepare(ctx context.Context, key, parent string) ([]containerd.Mount, error) // View behaves identically to Prepare except the result may not be // committed back to the snapshot snapshotter. View returns a readonly view on @@ -186,7 +187,7 @@ type Snapshotter interface { // Commit may not be called on the provided key and will return an error. // To collect the resources associated with key, Remove must be called with // key as the argument. - View(key, parent string) ([]containerd.Mount, error) + View(ctx context.Context, key, parent string) ([]containerd.Mount, error) // Commit captures the changes between key and its parent into a snapshot // identified by name. The name can then be used with the snapshotter's other @@ -198,7 +199,7 @@ type Snapshotter interface { // Commit may be called multiple times on the same key. Snapshots created // in this manner will all reference the parent used to start the // transaction. - Commit(name, key string) error + Commit(ctx context.Context, name, key string) error // Remove the committed or active snapshot by the provided key. // @@ -206,11 +207,11 @@ type Snapshotter interface { // // If the snapshot is a parent of another snapshot, its children must be // removed before proceeding. - Remove(key string) error + Remove(ctx context.Context, key string) error // Walk the committed snapshots. For each snapshot in the snapshotter, the // function will be called. - Walk(fn func(Info) error) error + Walk(ctx context.Context, fn func(context.Context, Info) error) error } // SnapshotterSuite runs a test suite on the snapshotter given a factory function. @@ -255,12 +256,13 @@ func makeTest(t *testing.T, name string, snapshotterFn func(root string) (Snapsh // checkSnapshotterBasic tests the basic workflow of a snapshot snapshotter. func checkSnapshotterBasic(t *testing.T, snapshotter Snapshotter, work string) { + ctx := context.TODO() preparing := filepath.Join(work, "preparing") if err := os.MkdirAll(preparing, 0777); err != nil { t.Fatal(err) } - mounts, err := snapshotter.Prepare(preparing, "") + mounts, err := snapshotter.Prepare(ctx, preparing, "") if err != nil { t.Fatal(err) } @@ -283,11 +285,11 @@ func checkSnapshotterBasic(t *testing.T, snapshotter Snapshotter, work string) { } committed := filepath.Join(work, "committed") - if err := snapshotter.Commit(committed, preparing); err != nil { + if err := snapshotter.Commit(ctx, committed, preparing); err != nil { t.Fatal(err) } - si, err := snapshotter.Stat(committed) + si, err := snapshotter.Stat(ctx, committed) if err != nil { t.Fatal(err) } @@ -299,7 +301,7 @@ func checkSnapshotterBasic(t *testing.T, snapshotter Snapshotter, work string) { t.Fatal(err) } - mounts, err = snapshotter.Prepare(next, committed) + mounts, err = snapshotter.Prepare(ctx, next, committed) if err != nil { t.Fatal(err) } @@ -322,11 +324,11 @@ func checkSnapshotterBasic(t *testing.T, snapshotter Snapshotter, work string) { } nextCommitted := filepath.Join(work, "committed-next") - if err := snapshotter.Commit(nextCommitted, next); err != nil { + if err := snapshotter.Commit(ctx, nextCommitted, next); err != nil { t.Fatal(err) } - si2, err := snapshotter.Stat(nextCommitted) + si2, err := snapshotter.Stat(ctx, nextCommitted) if err != nil { t.Fatal(err) } @@ -338,7 +340,7 @@ func checkSnapshotterBasic(t *testing.T, snapshotter Snapshotter, work string) { si2.Name: si2, } walked := map[string]Info{} // walk is not ordered - assert.NoError(t, snapshotter.Walk(func(si Info) error { + assert.NoError(t, snapshotter.Walk(ctx, func(ctx context.Context, si Info) error { walked[si.Name] = si return nil }))