remove MemMepFs limitation

This commit is contained in:
Hanno Hecker 2016-01-16 17:25:52 +01:00 committed by Steve Francia
parent 9383100264
commit d660f82c74
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 permitted. If a file is present in the base layer and the overlay, only the
overlay will be removed/renamed. overlay will be removed/renamed.
The writable overlay layer is currently limited to MemMapFs.
```go ```go
base := afero.NewOsFs() base := afero.NewOsFs()
roBase := afero.NewReadOnlyFs(base) roBase := afero.NewReadOnlyFs(base)

View File

@ -2,6 +2,7 @@ package afero
import ( import (
"os" "os"
"path/filepath"
"syscall" "syscall"
"time" "time"
"fmt" "fmt"
@ -12,10 +13,6 @@ import (
// be made in the overlay: Changing an existing file in the base layer which // 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" // is not present in the overlay will copy the file to the overlay ("changing"
// includes also calls to e.g. Chtimes() and Chmod()). // 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(). // Reading directories is currently only supported via Open(), not OpenFile().
type CopyOnWriteFs struct { 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 { if err = u.copyToLayer(name); err != nil {
return nil, err 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 { if b {
return u.base.OpenFile(name, flag, perm) return u.base.OpenFile(name, flag, perm)
@ -217,11 +236,5 @@ func (u *CopyOnWriteFs) MkdirAll(name string, perm os.FileMode) error {
} }
func (u *CopyOnWriteFs) Create(name string) (File, error) { func (u *CopyOnWriteFs) Create(name string) (File, error) {
b, err := u.isBaseFile(name) return u.OpenFile(name, os.O_TRUNC|os.O_RDWR, 0666)
if err == nil && b {
if err = u.copyToLayer(name); err != nil {
return nil, err
}
}
return u.layer.Create(name)
} }