remove MemMepFs limitation

This commit is contained in:
Hanno Hecker 2016-01-16 17:25:52 +01:00
parent 2ec8b79d61
commit 548e7a5ab9
2 changed files with 25 additions and 14 deletions

View File

@ -357,8 +357,6 @@ Removing and Renaming files present only in the base layer is not currently
permitted. If a file is present in the base layer and the overlay, only the
overlay will be removed/renamed.
The writable overlay layer is currently limited to MemMapFs.
```go
base := afero.NewOsFs()
roBase := afero.NewReadOnlyFs(base)

View File

@ -2,6 +2,7 @@ package afero
import (
"os"
"path/filepath"
"syscall"
"time"
)
@ -11,10 +12,6 @@ import (
// be made in the overlay: Changing an existing file in the base layer which
// is not present in the overlay will copy the file to the overlay ("changing"
// includes also calls to e.g. Chtimes() and Chmod()).
// The overlay is currently limited to MemMapFs:
// - missing MkdirAll() calls in the code below, MemMapFs creates them
// implicitly (or better: records the full path and afero.Readdir()
// can handle this).
//
// Reading directories is currently only supported via Open(), not OpenFile().
type CopyOnWriteFs struct {
@ -132,8 +129,30 @@ func (u *CopyOnWriteFs) OpenFile(name string, flag int, perm os.FileMode) (File,
if err = u.copyToLayer(name); err != nil {
return nil, err
}
return u.layer.OpenFile(name, flag, perm)
}
return u.layer.OpenFile(name, flag, perm)
dir := filepath.Dir(name)
isaDir, err := IsDir(u.base, dir)
if err != nil {
return nil, err
}
if isaDir {
if err = u.layer.MkdirAll(dir, 0777); err != nil {
return nil, err
}
return u.layer.OpenFile(name, flag, perm)
}
isaDir, err = IsDir(u.layer, dir)
if err != nil {
return nil, err
}
if isaDir {
return u.layer.OpenFile(name, flag, perm)
}
return nil, &os.PathError{Op: "open", Path: name, Err: syscall.ENOTDIR} // ...or os.ErrNotExist?
}
if b {
return u.base.OpenFile(name, flag, perm)
@ -197,11 +216,5 @@ func (u *CopyOnWriteFs) MkdirAll(name string, perm os.FileMode) error {
}
func (u *CopyOnWriteFs) Create(name string) (File, error) {
b, err := u.isBaseFile(name)
if err == nil && b {
if err = u.copyToLayer(name); err != nil {
return nil, err
}
}
return u.layer.Create(name)
return u.OpenFile(name, os.O_TRUNC|os.O_RDWR, 0666)
}