X Tutup
Skip to content

Commit d0b4ce8

Browse files
committed
snapshot/overlay: add snapshot test suite to overlay
Signed-off-by: Stephen J Day <stephen.day@docker.com>
1 parent 68fd252 commit d0b4ce8

File tree

3 files changed

+124
-31
lines changed

3 files changed

+124
-31
lines changed

snapshot/overlay/overlay.go

Lines changed: 91 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@ package overlay
22

33
import (
44
"fmt"
5+
"io/ioutil"
56
"os"
67
"path/filepath"
78
"strings"
89
"sync"
910

1011
"github.com/docker/containerd"
12+
digest "github.com/opencontainers/go-digest"
1113
)
1214

13-
func NewOverlay(root string) (*Overlay, error) {
15+
func NewDriver(root string) (*Overlay, error) {
1416
if err := os.MkdirAll(root, 0700); err != nil {
1517
return nil, err
1618
}
@@ -33,31 +35,87 @@ type Overlay struct {
3335
cache *cache
3436
}
3537

36-
func (o *Overlay) Prepare(key string, parentName string) ([]containerd.Mount, error) {
37-
if err := validKey(key); err != nil {
38-
return nil, err
39-
}
38+
func (o *Overlay) Prepare(key, parent string) ([]containerd.Mount, error) {
4039
active, err := o.newActiveDir(key)
4140
if err != nil {
4241
return nil, err
4342
}
44-
if parentName != "" {
45-
if err := active.setParent(parentName); err != nil {
43+
if parent != "" {
44+
if err := active.setParent(parent); err != nil {
4645
return nil, err
4746
}
4847
}
48+
return o.Mounts(key)
49+
}
50+
51+
func (o *Overlay) View(key, parent string) ([]containerd.Mount, error) {
52+
panic("not implemented")
53+
}
54+
55+
// Mounts returns the mounts for the transaction identified by key. Can be
56+
// called on an read-write or readonly transaction.
57+
//
58+
// This can be used to recover mounts after calling View or Prepare.
59+
func (o *Overlay) Mounts(key string) ([]containerd.Mount, error) {
60+
active := o.getActive(key)
4961
return active.mounts(o.cache)
5062
}
5163

5264
func (o *Overlay) Commit(name, key string) error {
5365
active := o.getActive(key)
54-
return active.commit(name)
66+
return active.commit(name, o.cache)
67+
}
68+
69+
// Remove abandons the transaction identified by key. All resources
70+
// associated with the key will be removed.
71+
func (o *Overlay) Remove(key string) error {
72+
panic("not implemented")
73+
}
74+
75+
// Parent returns the parent of snapshot identified by name.
76+
func (o *Overlay) Parent(name string) (string, error) {
77+
ppath, err := o.cache.get(filepath.Join(o.root, "snapshots", hash(name)))
78+
if err != nil {
79+
if os.IsNotExist(err) {
80+
return "", nil // no parent
81+
}
82+
83+
return "", err
84+
}
85+
86+
p, err := ioutil.ReadFile(filepath.Join(ppath, "name"))
87+
if err != nil {
88+
return "", err
89+
}
90+
91+
return string(p), nil
92+
}
93+
94+
// Exists returns true if the snapshot with name exists.
95+
func (o *Overlay) Exists(name string) bool {
96+
panic("not implemented")
97+
}
98+
99+
// Delete the snapshot idenfitied by name.
100+
//
101+
// If name has children, the operation will fail.
102+
func (o *Overlay) Delete(name string) error {
103+
panic("not implemented")
104+
}
105+
106+
// Walk the committed snapshots.
107+
func (o *Overlay) Walk(fn func(name string) error) error {
108+
panic("not implemented")
109+
}
110+
111+
// Active will call fn for each active transaction.
112+
func (o *Overlay) Active(fn func(key string) error) error {
113+
panic("not implemented")
55114
}
56115

57116
func (o *Overlay) newActiveDir(key string) (*activeDir, error) {
58117
var (
59-
hash = hash(key)
60-
path = filepath.Join(o.root, "active", hash)
118+
path = filepath.Join(o.root, "active", hash(key))
61119
)
62120
a := &activeDir{
63121
path: path,
@@ -82,15 +140,8 @@ func (o *Overlay) getActive(key string) *activeDir {
82140
}
83141
}
84142

85-
func validKey(key string) error {
86-
_, err := filepath.Abs(key)
87-
return err
88-
}
89-
90143
func hash(k string) string {
91-
h := md5.New()
92-
h.Write([]byte(k))
93-
return hex.EncodeToString(h.Sum(nil))
144+
return digest.FromString(k).Hex()
94145
}
95146

96147
type activeDir struct {
@@ -103,14 +154,26 @@ func (a *activeDir) delete() error {
103154
}
104155

105156
func (a *activeDir) setParent(name string) error {
106-
return os.Symlink(filepath.Join(a.snapshotsDir, name), filepath.Join(a.path, "parent"))
157+
return os.Symlink(filepath.Join(a.snapshotsDir, hash(name)), filepath.Join(a.path, "parent"))
107158
}
108159

109-
func (a *activeDir) commit(name string) error {
160+
func (a *activeDir) commit(name string, c *cache) error {
161+
// TODO(stevvooe): This doesn't quite meet the current model. The new model
162+
// is to copy all of this out and let the transaction continue. We don't
163+
// really have tests for it yet, but this will be the spot to fix it.
164+
//
165+
// Nothing should be removed until remove is called on the active
166+
// transaction.
110167
if err := os.RemoveAll(filepath.Join(a.path, "work")); err != nil {
111168
return err
112169
}
113-
return os.Rename(a.path, filepath.Join(a.snapshotsDir, name))
170+
171+
if err := ioutil.WriteFile(filepath.Join(a.path, "name"), []byte(name), 0644); err != nil {
172+
return err
173+
}
174+
175+
c.invalidate(a.path) // clears parent cache, since we end up moving.
176+
return os.Rename(a.path, filepath.Join(a.snapshotsDir, hash(name)))
114177
}
115178

116179
func (a *activeDir) mounts(c *cache) ([]containerd.Mount, error) {
@@ -180,3 +243,10 @@ func (c *cache) get(path string) (string, error) {
180243
}
181244
return parentRoot, nil
182245
}
246+
247+
func (c *cache) invalidate(path string) {
248+
c.mu.Lock()
249+
defer c.mu.Unlock()
250+
251+
delete(c.parents, path)
252+
}

snapshot/overlay/overlay_test.go

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import (
88
"testing"
99

1010
"github.com/docker/containerd"
11-
"github.com/docker/containerd/snapshot/testutil"
11+
"github.com/docker/containerd/snapshot"
12+
"github.com/docker/containerd/testutil"
1213
)
1314

1415
func TestOverlay(t *testing.T) {
@@ -17,7 +18,7 @@ func TestOverlay(t *testing.T) {
1718
t.Fatal(err)
1819
}
1920
defer os.RemoveAll(root)
20-
o, err := NewOverlay(root)
21+
o, err := NewDriver(root)
2122
if err != nil {
2223
t.Error(err)
2324
return
@@ -52,7 +53,7 @@ func TestOverlayCommit(t *testing.T) {
5253
t.Fatal(err)
5354
}
5455
defer os.RemoveAll(root)
55-
o, err := NewOverlay(root)
56+
o, err := NewDriver(root)
5657
if err != nil {
5758
t.Error(err)
5859
return
@@ -80,7 +81,7 @@ func TestOverlayOverlayMount(t *testing.T) {
8081
t.Fatal(err)
8182
}
8283
defer os.RemoveAll(root)
83-
o, err := NewOverlay(root)
84+
o, err := NewDriver(root)
8485
if err != nil {
8586
t.Error(err)
8687
return
@@ -110,10 +111,11 @@ func TestOverlayOverlayMount(t *testing.T) {
110111
t.Errorf("expected source %q but received %q", "overlay", m.Source)
111112
}
112113
var (
113-
hash = hash("/tmp/layer2")
114-
work = "workdir=" + filepath.Join(root, "active", hash, "work")
115-
upper = "upperdir=" + filepath.Join(root, "active", hash, "fs")
116-
lower = "lowerdir=" + filepath.Join(root, "snapshots", "base", "fs")
114+
ah = hash("/tmp/layer2")
115+
sh = hash("base")
116+
work = "workdir=" + filepath.Join(root, "active", ah, "work")
117+
upper = "upperdir=" + filepath.Join(root, "active", ah, "fs")
118+
lower = "lowerdir=" + filepath.Join(root, "snapshots", sh, "fs")
117119
)
118120
for i, v := range []string{
119121
work,
@@ -133,7 +135,7 @@ func TestOverlayOverlayRead(t *testing.T) {
133135
t.Fatal(err)
134136
}
135137
defer os.RemoveAll(root)
136-
o, err := NewOverlay(root)
138+
o, err := NewDriver(root)
137139
if err != nil {
138140
t.Error(err)
139141
return
@@ -177,3 +179,15 @@ func TestOverlayOverlayRead(t *testing.T) {
177179
return
178180
}
179181
}
182+
183+
func TestOverlayDriverSuite(t *testing.T) {
184+
testutil.RequiresRoot(t)
185+
snapshot.DriverSuite(t, "Overlay", func(root string) (snapshot.Driver, func(), error) {
186+
driver, err := NewDriver(root)
187+
if err != nil {
188+
t.Fatal(err)
189+
}
190+
191+
return driver, func() {}, nil
192+
})
193+
}

testutil/helpers.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,16 @@ func DumpDir(t *testing.T, root string) {
4949
return err
5050
}
5151

52-
t.Log(fi.Mode(), path)
52+
if fi.Mode()&os.ModeSymlink != 0 {
53+
target, err := os.Readlink(path)
54+
if err != nil {
55+
return err
56+
}
57+
t.Log(fi.Mode(), path, "->", target)
58+
} else {
59+
t.Log(fi.Mode(), path)
60+
}
61+
5362
return nil
5463
}); err != nil {
5564
t.Fatalf("error dumping directory: %v", err)

0 commit comments

Comments
 (0)
X Tutup