@@ -2,15 +2,17 @@ package overlay
22
33import (
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
5264func (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
57116func (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-
90143func 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
96147type activeDir struct {
@@ -103,14 +154,26 @@ func (a *activeDir) delete() error {
103154}
104155
105156func (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
116179func (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+ }
0 commit comments