@@ -177,8 +177,39 @@ func (graph *Graph) Mktemp(id string) (string, error) {
177177 return tmp .imageRoot (id ), nil
178178}
179179
180+ // getDockerInitLayer returns the path of a layer containing a mountpoint suitable
181+ // for bind-mounting dockerinit into the container. The mountpoint is simply an
182+ // empty file at /.dockerinit
183+ //
184+ // This extra layer is used by all containers as the top-most ro layer. It protects
185+ // the container from unwanted side-effects on the rw layer.
186+ func (graph * Graph ) getDockerInitLayer () (string , error ) {
187+ tmp , err := graph .tmp ()
188+ if err != nil {
189+ return "" , err
190+ }
191+ initLayer := tmp .imageRoot ("_dockerinit" )
192+ if err := os .Mkdir (initLayer , 0755 ); err != nil && ! os .IsExist (err ) {
193+ // If directory already existed, keep going.
194+ // For all other errors, abort.
195+ return "" , err
196+ }
197+ // FIXME: how the hell do I break down this line in a way
198+ // that is idiomatic and not ugly as hell?
199+ if f , err := os .OpenFile (path .Join (initLayer , ".dockerinit" ), os .O_CREATE | os .O_TRUNC , 0700 ); err != nil && ! os .IsExist (err ) {
200+ // If file already existed, keep going.
201+ // For all other errors, abort.
202+ return "" , err
203+ } else {
204+ f .Close ()
205+ }
206+ // Layer is ready to use, if it wasn't before.
207+ return initLayer , nil
208+ }
209+
180210func (graph * Graph ) tmp () (* Graph , error ) {
181- return NewGraph (path .Join (graph .Root , ":tmp:" ))
211+ // Changed to _tmp from :tmp:, because it messed with ":" separators in aufs branch syntax...
212+ return NewGraph (path .Join (graph .Root , "_tmp" ))
182213}
183214
184215// Check if given error is "not empty".
0 commit comments