Vendor in latest code.
Add support for vendoring in containers/storage and ran dep ensure Need to get default storage for containers to include and default to overlay2. Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
parent
37f118d73a
commit
549d734da9
35 changed files with 136 additions and 1105 deletions
2
vendor/github.com/containers/storage/drivers/aufs/aufs.go
generated
vendored
2
vendor/github.com/containers/storage/drivers/aufs/aufs.go
generated
vendored
|
@ -45,8 +45,8 @@ import (
|
|||
mountpk "github.com/containers/storage/pkg/mount"
|
||||
"github.com/containers/storage/pkg/stringid"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/label"
|
||||
rsystem "github.com/opencontainers/runc/libcontainer/system"
|
||||
"github.com/opencontainers/selinux/go-selinux/label"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
2
vendor/github.com/containers/storage/drivers/btrfs/btrfs.go
generated
vendored
2
vendor/github.com/containers/storage/drivers/btrfs/btrfs.go
generated
vendored
|
@ -28,7 +28,7 @@ import (
|
|||
"github.com/containers/storage/pkg/mount"
|
||||
"github.com/containers/storage/pkg/parsers"
|
||||
"github.com/docker/go-units"
|
||||
"github.com/opencontainers/runc/libcontainer/label"
|
||||
"github.com/opencontainers/selinux/go-selinux/label"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
|
8
vendor/github.com/containers/storage/drivers/devmapper/deviceset.go
generated
vendored
8
vendor/github.com/containers/storage/drivers/devmapper/deviceset.go
generated
vendored
|
@ -31,7 +31,7 @@ import (
|
|||
"github.com/containers/storage/storageversion"
|
||||
"github.com/docker/go-units"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/label"
|
||||
"github.com/opencontainers/selinux/go-selinux/label"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -2569,7 +2569,7 @@ func NewDeviceSet(root string, doInit bool, options []string, uidMaps, gidMaps [
|
|||
devices.metaDataLoopbackSize = size
|
||||
case "dm.fs":
|
||||
if val != "ext4" && val != "xfs" {
|
||||
return nil, fmt.Errorf("devmapper: Unsupported filesystem %s\n", val)
|
||||
return nil, fmt.Errorf("devmapper: Unsupported filesystem %s", val)
|
||||
}
|
||||
devices.filesystem = val
|
||||
case "dm.mkfsarg":
|
||||
|
@ -2631,9 +2631,9 @@ func NewDeviceSet(root string, doInit bool, options []string, uidMaps, gidMaps [
|
|||
devices.minFreeSpacePercent = uint32(minFreeSpacePercent)
|
||||
default:
|
||||
if nthOption > len(defaults) {
|
||||
return nil, fmt.Errorf("devmapper: Unknown option %s\n", key)
|
||||
return nil, fmt.Errorf("devmapper: Unknown option %s", key)
|
||||
}
|
||||
logrus.Errorf("devmapper: Unknown option %s, ignoring\n", key)
|
||||
logrus.Errorf("devmapper: Unknown option %s, ignoring", key)
|
||||
}
|
||||
settings[key] = val
|
||||
}
|
||||
|
|
5
vendor/github.com/containers/storage/drivers/driver_linux.go
generated
vendored
5
vendor/github.com/containers/storage/drivers/driver_linux.go
generated
vendored
|
@ -53,11 +53,11 @@ const (
|
|||
var (
|
||||
// Slice of drivers that should be used in an order
|
||||
priority = []string{
|
||||
"overlay2",
|
||||
"devicemapper",
|
||||
"aufs",
|
||||
"btrfs",
|
||||
"zfs",
|
||||
"devicemapper",
|
||||
"overlay",
|
||||
"vfs",
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,7 @@ var (
|
|||
FsMagicJffs2Fs: "jffs2",
|
||||
FsMagicJfs: "jfs",
|
||||
FsMagicNfsFs: "nfs",
|
||||
FsMagicOverlay: "overlay",
|
||||
FsMagicRAMFs: "ramfs",
|
||||
FsMagicReiserFs: "reiserfs",
|
||||
FsMagicSmbFs: "smb",
|
||||
|
|
169
vendor/github.com/containers/storage/drivers/overlay/copy.go
generated
vendored
169
vendor/github.com/containers/storage/drivers/overlay/copy.go
generated
vendored
|
@ -1,169 +0,0 @@
|
|||
// +build linux
|
||||
|
||||
package overlay
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/containers/storage/pkg/pools"
|
||||
"github.com/containers/storage/pkg/system"
|
||||
)
|
||||
|
||||
type copyFlags int
|
||||
|
||||
const (
|
||||
copyHardlink copyFlags = 1 << iota
|
||||
)
|
||||
|
||||
func copyRegular(srcPath, dstPath string, mode os.FileMode) error {
|
||||
srcFile, err := os.Open(srcPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer srcFile.Close()
|
||||
|
||||
dstFile, err := os.OpenFile(dstPath, os.O_WRONLY|os.O_CREATE, mode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer dstFile.Close()
|
||||
|
||||
_, err = pools.Copy(dstFile, srcFile)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func copyXattr(srcPath, dstPath, attr string) error {
|
||||
data, err := system.Lgetxattr(srcPath, attr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if data != nil {
|
||||
if err := system.Lsetxattr(dstPath, attr, data, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func copyDir(srcDir, dstDir string, flags copyFlags) error {
|
||||
err := filepath.Walk(srcDir, func(srcPath string, f os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Rebase path
|
||||
relPath, err := filepath.Rel(srcDir, srcPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dstPath := filepath.Join(dstDir, relPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
stat, ok := f.Sys().(*syscall.Stat_t)
|
||||
if !ok {
|
||||
return fmt.Errorf("Unable to get raw syscall.Stat_t data for %s", srcPath)
|
||||
}
|
||||
|
||||
isHardlink := false
|
||||
|
||||
switch f.Mode() & os.ModeType {
|
||||
case 0: // Regular file
|
||||
if flags©Hardlink != 0 {
|
||||
isHardlink = true
|
||||
if err := os.Link(srcPath, dstPath); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := copyRegular(srcPath, dstPath, f.Mode()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
case os.ModeDir:
|
||||
if err := os.Mkdir(dstPath, f.Mode()); err != nil && !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
case os.ModeSymlink:
|
||||
link, err := os.Readlink(srcPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.Symlink(link, dstPath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
case os.ModeNamedPipe:
|
||||
fallthrough
|
||||
case os.ModeSocket:
|
||||
if err := syscall.Mkfifo(dstPath, stat.Mode); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
case os.ModeDevice:
|
||||
if err := syscall.Mknod(dstPath, stat.Mode, int(stat.Rdev)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
default:
|
||||
return fmt.Errorf("Unknown file type for %s\n", srcPath)
|
||||
}
|
||||
|
||||
// Everything below is copying metadata from src to dst. All this metadata
|
||||
// already shares an inode for hardlinks.
|
||||
if isHardlink {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := os.Lchown(dstPath, int(stat.Uid), int(stat.Gid)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := copyXattr(srcPath, dstPath, "security.capability"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// We need to copy this attribute if it appears in an overlay upper layer, as
|
||||
// this function is used to copy those. It is set by overlay if a directory
|
||||
// is removed and then re-created and should not inherit anything from the
|
||||
// same dir in the lower dir.
|
||||
if err := copyXattr(srcPath, dstPath, "trusted.overlay.opaque"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
isSymlink := f.Mode()&os.ModeSymlink != 0
|
||||
|
||||
// There is no LChmod, so ignore mode for symlink. Also, this
|
||||
// must happen after chown, as that can modify the file mode
|
||||
if !isSymlink {
|
||||
if err := os.Chmod(dstPath, f.Mode()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// system.Chtimes doesn't support a NOFOLLOW flag atm
|
||||
if !isSymlink {
|
||||
aTime := time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec))
|
||||
mTime := time.Unix(int64(stat.Mtim.Sec), int64(stat.Mtim.Nsec))
|
||||
if err := system.Chtimes(dstPath, aTime, mTime); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
ts := []syscall.Timespec{stat.Atim, stat.Mtim}
|
||||
if err := system.LUtimesNano(dstPath, ts); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
}
|
450
vendor/github.com/containers/storage/drivers/overlay/overlay.go
generated
vendored
450
vendor/github.com/containers/storage/drivers/overlay/overlay.go
generated
vendored
|
@ -1,450 +0,0 @@
|
|||
// +build linux
|
||||
|
||||
package overlay
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"syscall"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
|
||||
"github.com/containers/storage/drivers"
|
||||
"github.com/containers/storage/pkg/archive"
|
||||
"github.com/containers/storage/pkg/idtools"
|
||||
|
||||
"github.com/containers/storage/pkg/mount"
|
||||
"github.com/opencontainers/runc/libcontainer/label"
|
||||
)
|
||||
|
||||
// This is a small wrapper over the NaiveDiffWriter that lets us have a custom
|
||||
// implementation of ApplyDiff()
|
||||
|
||||
var (
|
||||
// ErrApplyDiffFallback is returned to indicate that a normal ApplyDiff is applied as a fallback from Naive diff writer.
|
||||
ErrApplyDiffFallback = fmt.Errorf("Fall back to normal ApplyDiff")
|
||||
backingFs = "<unknown>"
|
||||
)
|
||||
|
||||
// ApplyDiffProtoDriver wraps the ProtoDriver by extending the interface with ApplyDiff method.
|
||||
type ApplyDiffProtoDriver interface {
|
||||
graphdriver.ProtoDriver
|
||||
// ApplyDiff writes the diff to the archive for the given id and parent id.
|
||||
// It returns the size in bytes written if successful, an error ErrApplyDiffFallback is returned otherwise.
|
||||
ApplyDiff(id, parent string, diff archive.Reader) (size int64, err error)
|
||||
}
|
||||
|
||||
type naiveDiffDriverWithApply struct {
|
||||
graphdriver.Driver
|
||||
applyDiff ApplyDiffProtoDriver
|
||||
}
|
||||
|
||||
// NaiveDiffDriverWithApply returns a NaiveDiff driver with custom ApplyDiff.
|
||||
func NaiveDiffDriverWithApply(driver ApplyDiffProtoDriver, uidMaps, gidMaps []idtools.IDMap) graphdriver.Driver {
|
||||
return &naiveDiffDriverWithApply{
|
||||
Driver: graphdriver.NewNaiveDiffDriver(driver, uidMaps, gidMaps),
|
||||
applyDiff: driver,
|
||||
}
|
||||
}
|
||||
|
||||
// ApplyDiff creates a diff layer with either the NaiveDiffDriver or with a fallback.
|
||||
func (d *naiveDiffDriverWithApply) ApplyDiff(id, parent string, diff archive.Reader) (int64, error) {
|
||||
b, err := d.applyDiff.ApplyDiff(id, parent, diff)
|
||||
if err == ErrApplyDiffFallback {
|
||||
return d.Driver.ApplyDiff(id, parent, diff)
|
||||
}
|
||||
return b, err
|
||||
}
|
||||
|
||||
// This backend uses the overlay union filesystem for containers
|
||||
// plus hard link file sharing for images.
|
||||
|
||||
// Each container/image can have a "root" subdirectory which is a plain
|
||||
// filesystem hierarchy, or they can use overlay.
|
||||
|
||||
// If they use overlay there is a "upper" directory and a "lower-id"
|
||||
// file, as well as "merged" and "work" directories. The "upper"
|
||||
// directory has the upper layer of the overlay, and "lower-id" contains
|
||||
// the id of the parent whose "root" directory shall be used as the lower
|
||||
// layer in the overlay. The overlay itself is mounted in the "merged"
|
||||
// directory, and the "work" dir is needed for overlay to work.
|
||||
|
||||
// When an overlay layer is created there are two cases, either the
|
||||
// parent has a "root" dir, then we start out with an empty "upper"
|
||||
// directory overlaid on the parents root. This is typically the
|
||||
// case with the init layer of a container which is based on an image.
|
||||
// If there is no "root" in the parent, we inherit the lower-id from
|
||||
// the parent and start by making a copy in the parent's "upper" dir.
|
||||
// This is typically the case for a container layer which copies
|
||||
// its parent -init upper layer.
|
||||
|
||||
// Additionally we also have a custom implementation of ApplyLayer
|
||||
// which makes a recursive copy of the parent "root" layer using
|
||||
// hardlinks to share file data, and then applies the layer on top
|
||||
// of that. This means all child images share file (but not directory)
|
||||
// data with the parent.
|
||||
|
||||
// Driver contains information about the home directory and the list of active mounts that are created using this driver.
|
||||
type Driver struct {
|
||||
home string
|
||||
uidMaps []idtools.IDMap
|
||||
gidMaps []idtools.IDMap
|
||||
ctr *graphdriver.RefCounter
|
||||
}
|
||||
|
||||
func init() {
|
||||
graphdriver.Register("overlay", Init)
|
||||
}
|
||||
|
||||
// Init returns the NaiveDiffDriver, a native diff driver for overlay filesystem.
|
||||
// If overlay filesystem is not supported on the host, graphdriver.ErrNotSupported is returned as error.
|
||||
// If an overlay filesystem is not supported over an existing filesystem then error graphdriver.ErrIncompatibleFS is returned.
|
||||
func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (graphdriver.Driver, error) {
|
||||
|
||||
if err := supportsOverlay(); err != nil {
|
||||
return nil, graphdriver.ErrNotSupported
|
||||
}
|
||||
|
||||
fsMagic, err := graphdriver.GetFSMagic(home)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if fsName, ok := graphdriver.FsNames[fsMagic]; ok {
|
||||
backingFs = fsName
|
||||
}
|
||||
|
||||
switch fsMagic {
|
||||
case graphdriver.FsMagicAufs, graphdriver.FsMagicBtrfs, graphdriver.FsMagicOverlay, graphdriver.FsMagicZfs, graphdriver.FsMagicEcryptfs:
|
||||
logrus.Errorf("'overlay' is not supported over %s", backingFs)
|
||||
return nil, graphdriver.ErrIncompatibleFS
|
||||
}
|
||||
|
||||
rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Create the driver home dir
|
||||
if err := idtools.MkdirAllAs(home, 0700, rootUID, rootGID); err != nil && !os.IsExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := mount.MakePrivate(home); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
d := &Driver{
|
||||
home: home,
|
||||
uidMaps: uidMaps,
|
||||
gidMaps: gidMaps,
|
||||
ctr: graphdriver.NewRefCounter(graphdriver.NewFsChecker(graphdriver.FsMagicOverlay)),
|
||||
}
|
||||
|
||||
return NaiveDiffDriverWithApply(d, uidMaps, gidMaps), nil
|
||||
}
|
||||
|
||||
func supportsOverlay() error {
|
||||
// We can try to modprobe overlay first before looking at
|
||||
// proc/filesystems for when overlay is supported
|
||||
exec.Command("modprobe", "overlay").Run()
|
||||
|
||||
f, err := os.Open("/proc/filesystems")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
s := bufio.NewScanner(f)
|
||||
for s.Scan() {
|
||||
if s.Text() == "nodev\toverlay" {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
logrus.Error("'overlay' not found as a supported filesystem on this host. Please ensure kernel is new enough and has overlay support loaded.")
|
||||
return graphdriver.ErrNotSupported
|
||||
}
|
||||
|
||||
func (d *Driver) String() string {
|
||||
return "overlay"
|
||||
}
|
||||
|
||||
// Status returns current driver information in a two dimensional string array.
|
||||
// Output contains "Backing Filesystem" used in this implementation.
|
||||
func (d *Driver) Status() [][2]string {
|
||||
return [][2]string{
|
||||
{"Backing Filesystem", backingFs},
|
||||
}
|
||||
}
|
||||
|
||||
// GetMetadata returns meta data about the overlay driver such as root, LowerDir, UpperDir, WorkDir and MergeDir used to store data.
|
||||
func (d *Driver) GetMetadata(id string) (map[string]string, error) {
|
||||
dir := d.dir(id)
|
||||
if _, err := os.Stat(dir); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
metadata := make(map[string]string)
|
||||
|
||||
// If id has a root, it is an image
|
||||
rootDir := path.Join(dir, "root")
|
||||
if _, err := os.Stat(rootDir); err == nil {
|
||||
metadata["RootDir"] = rootDir
|
||||
return metadata, nil
|
||||
}
|
||||
|
||||
lowerID, err := ioutil.ReadFile(path.Join(dir, "lower-id"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
metadata["LowerDir"] = path.Join(d.dir(string(lowerID)), "root")
|
||||
metadata["UpperDir"] = path.Join(dir, "upper")
|
||||
metadata["WorkDir"] = path.Join(dir, "work")
|
||||
metadata["MergedDir"] = path.Join(dir, "merged")
|
||||
|
||||
return metadata, nil
|
||||
}
|
||||
|
||||
// Cleanup any state created by overlay which should be cleaned when daemon
|
||||
// is being shutdown. For now, we just have to unmount the bind mounted
|
||||
// we had created.
|
||||
func (d *Driver) Cleanup() error {
|
||||
return mount.Unmount(d.home)
|
||||
}
|
||||
|
||||
// CreateReadWrite creates a layer that is writable for use as a container
|
||||
// file system.
|
||||
func (d *Driver) CreateReadWrite(id, parent, mountLabel string, storageOpt map[string]string) error {
|
||||
return d.Create(id, parent, mountLabel, storageOpt)
|
||||
}
|
||||
|
||||
// Create is used to create the upper, lower, and merge directories required for overlay fs for a given id.
|
||||
// The parent filesystem is used to configure these directories for the overlay.
|
||||
func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]string) (retErr error) {
|
||||
|
||||
if len(storageOpt) != 0 {
|
||||
return fmt.Errorf("--storage-opt is not supported for overlay")
|
||||
}
|
||||
|
||||
dir := d.dir(id)
|
||||
|
||||
rootUID, rootGID, err := idtools.GetRootUIDGID(d.uidMaps, d.gidMaps)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := idtools.MkdirAllAs(path.Dir(dir), 0700, rootUID, rootGID); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := idtools.MkdirAs(dir, 0700, rootUID, rootGID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
// Clean up on failure
|
||||
if retErr != nil {
|
||||
os.RemoveAll(dir)
|
||||
}
|
||||
}()
|
||||
|
||||
// Toplevel images are just a "root" dir
|
||||
if parent == "" {
|
||||
if err := idtools.MkdirAs(path.Join(dir, "root"), 0755, rootUID, rootGID); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
parentDir := d.dir(parent)
|
||||
|
||||
// Ensure parent exists
|
||||
if _, err := os.Lstat(parentDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If parent has a root, just do an overlay to it
|
||||
parentRoot := path.Join(parentDir, "root")
|
||||
|
||||
if s, err := os.Lstat(parentRoot); err == nil {
|
||||
if err := idtools.MkdirAs(path.Join(dir, "upper"), s.Mode(), rootUID, rootGID); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := idtools.MkdirAs(path.Join(dir, "work"), 0700, rootUID, rootGID); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := idtools.MkdirAs(path.Join(dir, "merged"), 0700, rootUID, rootGID); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ioutil.WriteFile(path.Join(dir, "lower-id"), []byte(parent), 0666); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Otherwise, copy the upper and the lower-id from the parent
|
||||
|
||||
lowerID, err := ioutil.ReadFile(path.Join(parentDir, "lower-id"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(path.Join(dir, "lower-id"), lowerID, 0666); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
parentUpperDir := path.Join(parentDir, "upper")
|
||||
s, err := os.Lstat(parentUpperDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
upperDir := path.Join(dir, "upper")
|
||||
if err := idtools.MkdirAs(upperDir, s.Mode(), rootUID, rootGID); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := idtools.MkdirAs(path.Join(dir, "work"), 0700, rootUID, rootGID); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := idtools.MkdirAs(path.Join(dir, "merged"), 0700, rootUID, rootGID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return copyDir(parentUpperDir, upperDir, 0)
|
||||
}
|
||||
|
||||
func (d *Driver) dir(id string) string {
|
||||
return path.Join(d.home, id)
|
||||
}
|
||||
|
||||
// Remove cleans the directories that are created for this id.
|
||||
func (d *Driver) Remove(id string) error {
|
||||
if err := os.RemoveAll(d.dir(id)); err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get creates and mounts the required file system for the given id and returns the mount path.
|
||||
func (d *Driver) Get(id string, mountLabel string) (s string, err error) {
|
||||
dir := d.dir(id)
|
||||
if _, err := os.Stat(dir); err != nil {
|
||||
return "", err
|
||||
}
|
||||
// If id has a root, just return it
|
||||
rootDir := path.Join(dir, "root")
|
||||
if _, err := os.Stat(rootDir); err == nil {
|
||||
return rootDir, nil
|
||||
}
|
||||
mergedDir := path.Join(dir, "merged")
|
||||
if count := d.ctr.Increment(mergedDir); count > 1 {
|
||||
return mergedDir, nil
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if c := d.ctr.Decrement(mergedDir); c <= 0 {
|
||||
syscall.Unmount(mergedDir, 0)
|
||||
}
|
||||
}
|
||||
}()
|
||||
lowerID, err := ioutil.ReadFile(path.Join(dir, "lower-id"))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var (
|
||||
lowerDir = path.Join(d.dir(string(lowerID)), "root")
|
||||
upperDir = path.Join(dir, "upper")
|
||||
workDir = path.Join(dir, "work")
|
||||
opts = fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", lowerDir, upperDir, workDir)
|
||||
)
|
||||
if err := syscall.Mount("overlay", mergedDir, "overlay", 0, label.FormatMountLabel(opts, mountLabel)); err != nil {
|
||||
return "", fmt.Errorf("error creating overlay mount to %s: %v", mergedDir, err)
|
||||
}
|
||||
// chown "workdir/work" to the remapped root UID/GID. Overlay fs inside a
|
||||
// user namespace requires this to move a directory from lower to upper.
|
||||
rootUID, rootGID, err := idtools.GetRootUIDGID(d.uidMaps, d.gidMaps)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if err := os.Chown(path.Join(workDir, "work"), rootUID, rootGID); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return mergedDir, nil
|
||||
}
|
||||
|
||||
// Put unmounts the mount path created for the give id.
|
||||
func (d *Driver) Put(id string) error {
|
||||
mountpoint := path.Join(d.dir(id), "merged")
|
||||
if count := d.ctr.Decrement(mountpoint); count > 0 {
|
||||
return nil
|
||||
}
|
||||
err := syscall.Unmount(mountpoint, 0)
|
||||
if err != nil {
|
||||
rootDir := path.Join(d.dir(id), "root")
|
||||
if _, err := os.Stat(rootDir); err == nil {
|
||||
// We weren't mounting a "merged" directory anyway
|
||||
return nil
|
||||
}
|
||||
logrus.Debugf("Failed to unmount %s overlay: %v", id, err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// ApplyDiff applies the new layer on top of the root, if parent does not exist with will return an ErrApplyDiffFallback error.
|
||||
func (d *Driver) ApplyDiff(id string, parent string, diff archive.Reader) (size int64, err error) {
|
||||
dir := d.dir(id)
|
||||
|
||||
if parent == "" {
|
||||
return 0, ErrApplyDiffFallback
|
||||
}
|
||||
|
||||
parentRootDir := path.Join(d.dir(parent), "root")
|
||||
if _, err := os.Stat(parentRootDir); err != nil {
|
||||
return 0, ErrApplyDiffFallback
|
||||
}
|
||||
|
||||
// We now know there is a parent, and it has a "root" directory containing
|
||||
// the full root filesystem. We can just hardlink it and apply the
|
||||
// layer. This relies on two things:
|
||||
// 1) ApplyDiff is only run once on a clean (no writes to upper layer) container
|
||||
// 2) ApplyDiff doesn't do any in-place writes to files (would break hardlinks)
|
||||
// These are all currently true and are not expected to break
|
||||
|
||||
tmpRootDir, err := ioutil.TempDir(dir, "tmproot")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
os.RemoveAll(tmpRootDir)
|
||||
} else {
|
||||
os.RemoveAll(path.Join(dir, "upper"))
|
||||
os.RemoveAll(path.Join(dir, "work"))
|
||||
os.RemoveAll(path.Join(dir, "merged"))
|
||||
os.RemoveAll(path.Join(dir, "lower-id"))
|
||||
}
|
||||
}()
|
||||
|
||||
if err = copyDir(parentRootDir, tmpRootDir, copyHardlink); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
options := &archive.TarOptions{UIDMaps: d.uidMaps, GIDMaps: d.gidMaps}
|
||||
if size, err = graphdriver.ApplyUncompressedLayer(tmpRootDir, diff, options); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
rootDir := path.Join(dir, "root")
|
||||
if err := os.Rename(tmpRootDir, rootDir); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Exists checks to see if the id is already mounted.
|
||||
func (d *Driver) Exists(id string) bool {
|
||||
_, err := os.Stat(d.dir(id))
|
||||
return err == nil
|
||||
}
|
93
vendor/github.com/containers/storage/drivers/overlay/overlay_test.go
generated
vendored
93
vendor/github.com/containers/storage/drivers/overlay/overlay_test.go
generated
vendored
|
@ -1,93 +0,0 @@
|
|||
// +build linux
|
||||
|
||||
package overlay
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/containers/storage/drivers"
|
||||
"github.com/containers/storage/drivers/graphtest"
|
||||
"github.com/containers/storage/pkg/archive"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Do not sure chroot to speed run time and allow archive
|
||||
// errors or hangs to be debugged directly from the test process.
|
||||
graphdriver.ApplyUncompressedLayer = archive.ApplyUncompressedLayer
|
||||
}
|
||||
|
||||
// This avoids creating a new driver for each test if all tests are run
|
||||
// Make sure to put new tests between TestOverlaySetup and TestOverlayTeardown
|
||||
func TestOverlaySetup(t *testing.T) {
|
||||
graphtest.GetDriver(t, "overlay")
|
||||
}
|
||||
|
||||
func TestOverlayCreateEmpty(t *testing.T) {
|
||||
graphtest.DriverTestCreateEmpty(t, "overlay")
|
||||
}
|
||||
|
||||
func TestOverlayCreateBase(t *testing.T) {
|
||||
graphtest.DriverTestCreateBase(t, "overlay")
|
||||
}
|
||||
|
||||
func TestOverlayCreateSnap(t *testing.T) {
|
||||
graphtest.DriverTestCreateSnap(t, "overlay")
|
||||
}
|
||||
|
||||
func TestOverlay50LayerRead(t *testing.T) {
|
||||
graphtest.DriverTestDeepLayerRead(t, 50, "overlay")
|
||||
}
|
||||
|
||||
// Fails due to bug in calculating changes after apply
|
||||
// likely related to https://github.com/docker/docker/issues/21555
|
||||
func TestOverlayDiffApply10Files(t *testing.T) {
|
||||
t.Skipf("Fails to compute changes after apply intermittently")
|
||||
graphtest.DriverTestDiffApply(t, 10, "overlay")
|
||||
}
|
||||
|
||||
func TestOverlayChanges(t *testing.T) {
|
||||
t.Skipf("Fails to compute changes intermittently")
|
||||
graphtest.DriverTestChanges(t, "overlay")
|
||||
}
|
||||
|
||||
func TestOverlayTeardown(t *testing.T) {
|
||||
graphtest.PutDriver(t)
|
||||
}
|
||||
|
||||
// Benchmarks should always setup new driver
|
||||
|
||||
func BenchmarkExists(b *testing.B) {
|
||||
graphtest.DriverBenchExists(b, "overlay")
|
||||
}
|
||||
|
||||
func BenchmarkGetEmpty(b *testing.B) {
|
||||
graphtest.DriverBenchGetEmpty(b, "overlay")
|
||||
}
|
||||
|
||||
func BenchmarkDiffBase(b *testing.B) {
|
||||
graphtest.DriverBenchDiffBase(b, "overlay")
|
||||
}
|
||||
|
||||
func BenchmarkDiffSmallUpper(b *testing.B) {
|
||||
graphtest.DriverBenchDiffN(b, 10, 10, "overlay")
|
||||
}
|
||||
|
||||
func BenchmarkDiff10KFileUpper(b *testing.B) {
|
||||
graphtest.DriverBenchDiffN(b, 10, 10000, "overlay")
|
||||
}
|
||||
|
||||
func BenchmarkDiff10KFilesBottom(b *testing.B) {
|
||||
graphtest.DriverBenchDiffN(b, 10000, 10, "overlay")
|
||||
}
|
||||
|
||||
func BenchmarkDiffApply100(b *testing.B) {
|
||||
graphtest.DriverBenchDiffApplyN(b, 100, "overlay")
|
||||
}
|
||||
|
||||
func BenchmarkDiff20Layers(b *testing.B) {
|
||||
graphtest.DriverBenchDeepLayerDiff(b, 20, "overlay")
|
||||
}
|
||||
|
||||
func BenchmarkRead20Layers(b *testing.B) {
|
||||
graphtest.DriverBenchDeepLayerRead(b, 20, "overlay")
|
||||
}
|
3
vendor/github.com/containers/storage/drivers/overlay/overlay_unsupported.go
generated
vendored
3
vendor/github.com/containers/storage/drivers/overlay/overlay_unsupported.go
generated
vendored
|
@ -1,3 +0,0 @@
|
|||
// +build !linux
|
||||
|
||||
package overlay
|
4
vendor/github.com/containers/storage/drivers/overlay2/overlay.go
generated
vendored
4
vendor/github.com/containers/storage/drivers/overlay2/overlay.go
generated
vendored
|
@ -25,7 +25,7 @@ import (
|
|||
"github.com/containers/storage/pkg/parsers"
|
||||
"github.com/containers/storage/pkg/parsers/kernel"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/label"
|
||||
"github.com/opencontainers/selinux/go-selinux/label"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -172,7 +172,7 @@ func parseOptions(options []string) (*overlayOptions, error) {
|
|||
return nil, err
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("overlay2: Unknown option %s\n", key)
|
||||
return nil, fmt.Errorf("overlay2: Unknown option %s", key)
|
||||
}
|
||||
}
|
||||
return o, nil
|
||||
|
|
3
vendor/github.com/containers/storage/drivers/register/register_overlay.go
generated
vendored
3
vendor/github.com/containers/storage/drivers/register/register_overlay.go
generated
vendored
|
@ -3,7 +3,6 @@
|
|||
package register
|
||||
|
||||
import (
|
||||
// register the overlay graphdriver
|
||||
_ "github.com/containers/storage/drivers/overlay"
|
||||
// register the overlay2 graphdriver
|
||||
_ "github.com/containers/storage/drivers/overlay2"
|
||||
)
|
||||
|
|
2
vendor/github.com/containers/storage/drivers/vfs/driver.go
generated
vendored
2
vendor/github.com/containers/storage/drivers/vfs/driver.go
generated
vendored
|
@ -9,7 +9,7 @@ import (
|
|||
"github.com/containers/storage/pkg/chrootarchive"
|
||||
"github.com/containers/storage/pkg/idtools"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/label"
|
||||
"github.com/opencontainers/selinux/go-selinux/label"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
2
vendor/github.com/containers/storage/drivers/zfs/zfs.go
generated
vendored
2
vendor/github.com/containers/storage/drivers/zfs/zfs.go
generated
vendored
|
@ -19,7 +19,7 @@ import (
|
|||
"github.com/containers/storage/pkg/mount"
|
||||
"github.com/containers/storage/pkg/parsers"
|
||||
zfs "github.com/mistifyio/go-zfs"
|
||||
"github.com/opencontainers/runc/libcontainer/label"
|
||||
"github.com/opencontainers/selinux/go-selinux/label"
|
||||
)
|
||||
|
||||
type zfsOptions struct {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue