Merge pull request #414 from rhatdan/vendor

Vendor in latest code.
This commit is contained in:
Mrunal Patel 2017-03-28 16:21:27 -07:00 committed by GitHub
commit f2ce1fff0a
35 changed files with 136 additions and 1105 deletions

View file

@ -1,5 +1,5 @@
{ {
"memo": "982a27b328719863bc88dcd24142002eee29fab7f48fdc71340a0620fd5c3ebe", "memo": "c69b3d661a6a19376099d94142598a44f109f155bc519d9b7943ac86e8ebcb8a",
"projects": [ "projects": [
{ {
"name": "github.com/BurntSushi/toml", "name": "github.com/BurntSushi/toml",
@ -75,13 +75,12 @@
{ {
"name": "github.com/containers/storage", "name": "github.com/containers/storage",
"branch": "master", "branch": "master",
"revision": "5cbbc6bafb45bd7ef10486b673deb3b81bb3b787", "revision": "ff48947baaf205756dd67a00ac688d694a778ef6",
"packages": [ "packages": [
"drivers", "drivers",
"drivers/aufs", "drivers/aufs",
"drivers/btrfs", "drivers/btrfs",
"drivers/devmapper", "drivers/devmapper",
"drivers/overlay",
"drivers/overlay2", "drivers/overlay2",
"drivers/register", "drivers/register",
"drivers/vfs", "drivers/vfs",
@ -317,8 +316,6 @@
"revision": "b263a43430ac6996a4302b891688544225197294", "revision": "b263a43430ac6996a4302b891688544225197294",
"packages": [ "packages": [
"libcontainer/apparmor", "libcontainer/apparmor",
"libcontainer/label",
"libcontainer/selinux",
"libcontainer/system", "libcontainer/system",
"libcontainer/user" "libcontainer/user"
] ]

View file

@ -6,6 +6,9 @@
"github.com/containers/image": { "github.com/containers/image": {
"branch": "master" "branch": "master"
}, },
"github.com/containers/storage": {
"branch": "master"
},
"github.com/docker/distribution": { "github.com/docker/distribution": {
"branch": "master" "branch": "master"
}, },

View file

@ -28,3 +28,5 @@ man/man1
man/man5 man/man5
man/man8 man/man8
vendor/pkg/ vendor/pkg/
.vagrant
storageversion/version_autogen.go

View file

@ -9,10 +9,10 @@ before_install:
- sudo apt-get -qq update - sudo apt-get -qq update
- sudo apt-get -qq install btrfs-tools libdevmapper-dev - sudo apt-get -qq install btrfs-tools libdevmapper-dev
script: script:
- AUTO_GOPATH=1 make install.tools - make install.tools
- AUTO_GOPATH=1 ./hack/make.sh validate-gofmt validate-pkg validate-lint validate-test validate-toml validate-vet validate-vendor - ./hack/make.sh validate-gofmt validate-pkg validate-lint validate-test validate-toml validate-vet
- AUTO_GOPATH=1 make .gitvalidation - make .gitvalidation
- AUTO_GOPATH=1 make build-binary - make build-binary
- AUTO_GOPATH=1 ./hack/make.sh cross - ./hack/make.sh cross
- sudo env AUTO_GOPATH=1 PATH="$PATH" ./hack/make.sh test-unit - sudo -E env "PATH=${PATH}" ./hack/make.sh test-unit
- AUTO_GOPATH=1 make docs - make docs

View file

@ -41,16 +41,13 @@ gccgo: build-gccgo ## build the gcc-go linux binaries using VMs
$(RUNINVM) hack/make.sh gccgo $(RUNINVM) hack/make.sh gccgo
test: build ## run the unit and integration tests using VMs test: build ## run the unit and integration tests using VMs
$(RUNINVM) hack/make.sh binary cross test-unit test-integration-cli $(RUNINVM) hack/make.sh binary cross test-unit
test-integration-cli: build ## run the integration tests using VMs
$(RUNINVM) hack/make.sh binary test-integration-cli
test-unit: build ## run the unit tests using VMs test-unit: build ## run the unit tests using VMs
$(RUNINVM) hack/make.sh test-unit $(RUNINVM) hack/make.sh test-unit
validate: build ## validate DCO, Seccomp profile generation, gofmt,\n./pkg/ isolation, golint, tests, tomls, go vet and vendor\nusing VMs validate: build ## validate DCO, Seccomp profile generation, gofmt,\n./pkg/ isolation, golint, tests, tomls, go vet and vendor\nusing VMs
$(RUNINVM) hack/make.sh validate-dco validate-gofmt validate-pkg validate-lint validate-test validate-toml validate-vet validate-vendor $(RUNINVM) hack/make.sh validate-dco validate-gofmt validate-pkg validate-lint validate-test validate-toml validate-vet
lint: lint:
@which gometalinter > /dev/null 2>/dev/null || (echo "ERROR: gometalinter not found. Consider 'make install.tools' target" && false) @which gometalinter > /dev/null 2>/dev/null || (echo "ERROR: gometalinter not found. Consider 'make install.tools' target" && false)

View file

@ -2,9 +2,7 @@
layers, container images, and containers. An `oci-storage` CLI wrapper is also layers, container images, and containers. An `oci-storage` CLI wrapper is also
included for manual and scripting use. included for manual and scripting use.
To build the CLI wrapper, use 'make build-binary', optionally passing To build the CLI wrapper, use 'make build-binary'.
'AUTO_GOPATH=1' as an additional argument to avoid having to set $GOPATH
manually. For information on other recognized targets, run 'make help'.
Operations which use VMs expect to launch them using 'vagrant', defaulting to Operations which use VMs expect to launch them using 'vagrant', defaulting to
using its 'libvirt' provider. The boxes used are also available for the using its 'libvirt' provider. The boxes used are also available for the

View file

@ -1,13 +1,13 @@
# -*- mode: ruby -*- # -*- mode: ruby -*-
# vi: set ft=ruby : # vi: set ft=ruby :
# #
# The fedora/23-cloud-base and debian/jessie64 boxes are also available for # The fedora/25-cloud-base and debian/jessie64 boxes are also available for
# the "virtualbox" provider. Set the VAGRANT_PROVIDER environment variable to # the "virtualbox" provider. Set the VAGRANT_PROVIDER environment variable to
# "virtualbox" to use them instead. # "virtualbox" to use them instead.
# #
Vagrant.configure("2") do |config| Vagrant.configure("2") do |config|
config.vm.define "fedora" do |c| config.vm.define "fedora" do |c|
c.vm.box = "fedora/23-cloud-base" c.vm.box = "fedora/25-cloud-base"
c.vm.synced_folder ".", "/vagrant", type: "rsync", c.vm.synced_folder ".", "/vagrant", type: "rsync",
rsync__exclude: "bundles", rsync__args: "-vadz" rsync__exclude: "bundles", rsync__args: "-vadz"
c.vm.provision "shell", inline: <<-SHELL c.vm.provision "shell", inline: <<-SHELL

View file

@ -45,8 +45,8 @@ import (
mountpk "github.com/containers/storage/pkg/mount" mountpk "github.com/containers/storage/pkg/mount"
"github.com/containers/storage/pkg/stringid" "github.com/containers/storage/pkg/stringid"
"github.com/opencontainers/runc/libcontainer/label"
rsystem "github.com/opencontainers/runc/libcontainer/system" rsystem "github.com/opencontainers/runc/libcontainer/system"
"github.com/opencontainers/selinux/go-selinux/label"
) )
var ( var (

View file

@ -28,7 +28,7 @@ import (
"github.com/containers/storage/pkg/mount" "github.com/containers/storage/pkg/mount"
"github.com/containers/storage/pkg/parsers" "github.com/containers/storage/pkg/parsers"
"github.com/docker/go-units" "github.com/docker/go-units"
"github.com/opencontainers/runc/libcontainer/label" "github.com/opencontainers/selinux/go-selinux/label"
) )
func init() { func init() {

View file

@ -31,7 +31,7 @@ import (
"github.com/containers/storage/storageversion" "github.com/containers/storage/storageversion"
"github.com/docker/go-units" "github.com/docker/go-units"
"github.com/opencontainers/runc/libcontainer/label" "github.com/opencontainers/selinux/go-selinux/label"
) )
var ( var (
@ -2569,7 +2569,7 @@ func NewDeviceSet(root string, doInit bool, options []string, uidMaps, gidMaps [
devices.metaDataLoopbackSize = size devices.metaDataLoopbackSize = size
case "dm.fs": case "dm.fs":
if val != "ext4" && val != "xfs" { 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 devices.filesystem = val
case "dm.mkfsarg": case "dm.mkfsarg":
@ -2631,9 +2631,9 @@ func NewDeviceSet(root string, doInit bool, options []string, uidMaps, gidMaps [
devices.minFreeSpacePercent = uint32(minFreeSpacePercent) devices.minFreeSpacePercent = uint32(minFreeSpacePercent)
default: default:
if nthOption > len(defaults) { 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 settings[key] = val
} }

View file

@ -53,11 +53,11 @@ const (
var ( var (
// Slice of drivers that should be used in an order // Slice of drivers that should be used in an order
priority = []string{ priority = []string{
"overlay2",
"devicemapper",
"aufs", "aufs",
"btrfs", "btrfs",
"zfs", "zfs",
"devicemapper",
"overlay",
"vfs", "vfs",
} }
@ -72,6 +72,7 @@ var (
FsMagicJffs2Fs: "jffs2", FsMagicJffs2Fs: "jffs2",
FsMagicJfs: "jfs", FsMagicJfs: "jfs",
FsMagicNfsFs: "nfs", FsMagicNfsFs: "nfs",
FsMagicOverlay: "overlay",
FsMagicRAMFs: "ramfs", FsMagicRAMFs: "ramfs",
FsMagicReiserFs: "reiserfs", FsMagicReiserFs: "reiserfs",
FsMagicSmbFs: "smb", FsMagicSmbFs: "smb",

View file

@ -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&copyHardlink != 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
}

View file

@ -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
}

View file

@ -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")
}

View file

@ -1,3 +0,0 @@
// +build !linux
package overlay

View file

@ -25,7 +25,7 @@ import (
"github.com/containers/storage/pkg/parsers" "github.com/containers/storage/pkg/parsers"
"github.com/containers/storage/pkg/parsers/kernel" "github.com/containers/storage/pkg/parsers/kernel"
"github.com/opencontainers/runc/libcontainer/label" "github.com/opencontainers/selinux/go-selinux/label"
) )
var ( var (
@ -172,7 +172,7 @@ func parseOptions(options []string) (*overlayOptions, error) {
return nil, err return nil, err
} }
default: default:
return nil, fmt.Errorf("overlay2: Unknown option %s\n", key) return nil, fmt.Errorf("overlay2: Unknown option %s", key)
} }
} }
return o, nil return o, nil

View file

@ -3,7 +3,6 @@
package register package register
import ( import (
// register the overlay graphdriver // register the overlay2 graphdriver
_ "github.com/containers/storage/drivers/overlay"
_ "github.com/containers/storage/drivers/overlay2" _ "github.com/containers/storage/drivers/overlay2"
) )

View file

@ -9,7 +9,7 @@ import (
"github.com/containers/storage/pkg/chrootarchive" "github.com/containers/storage/pkg/chrootarchive"
"github.com/containers/storage/pkg/idtools" "github.com/containers/storage/pkg/idtools"
"github.com/opencontainers/runc/libcontainer/label" "github.com/opencontainers/selinux/go-selinux/label"
) )
var ( var (

View file

@ -19,7 +19,7 @@ import (
"github.com/containers/storage/pkg/mount" "github.com/containers/storage/pkg/mount"
"github.com/containers/storage/pkg/parsers" "github.com/containers/storage/pkg/parsers"
zfs "github.com/mistifyio/go-zfs" zfs "github.com/mistifyio/go-zfs"
"github.com/opencontainers/runc/libcontainer/label" "github.com/opencontainers/selinux/go-selinux/label"
) )
type zfsOptions struct { type zfsOptions struct {

View file

@ -1,120 +0,0 @@
#!/usr/bin/env bash
PROJECT=github.com/containers/storage
# Downloads dependencies into vendor/ directory
mkdir -p vendor
if ! go list github.com/containers/storage/storage &> /dev/null; then
rm -rf .gopath
mkdir -p .gopath/src/github.com/containers
ln -sf ../../../.. .gopath/src/${PROJECT}
export GOPATH="${PWD}/.gopath:${PWD}/vendor"
fi
export GOPATH="$GOPATH:${PWD}/vendor"
find='find'
if [ "$(go env GOHOSTOS)" = 'windows' ]; then
find='/usr/bin/find'
fi
clone() {
local vcs="$1"
local pkg="$2"
local rev="$3"
local url="$4"
: ${url:=https://$pkg}
local target="vendor/src/$pkg"
echo -n "$pkg @ $rev: "
if [ -d "$target" ]; then
echo -n 'rm old, '
rm -rf "$target"
fi
echo -n 'clone, '
case "$vcs" in
git)
git clone --quiet --no-checkout "$url" "$target"
( cd "$target" && git checkout --quiet "$rev" && git reset --quiet --hard "$rev" )
;;
hg)
hg clone --quiet --updaterev "$rev" "$url" "$target"
;;
esac
echo -n 'rm VCS, '
( cd "$target" && rm -rf .{git,hg} )
echo -n 'rm vendor, '
( cd "$target" && rm -rf vendor Godeps/_workspace )
echo done
}
clean() {
local packages=(
"${PROJECT}/cmd/oci-storage"
)
local storagePlatforms=( ${STORAGE_OSARCH:="linux/amd64 linux/i386 linux/arm freebsd/amd64 freebsd/386 freebsd/arm windows/amd64"} )
local buildTagCombos=(
''
'experimental'
)
echo
echo -n 'collecting import graph, '
local IFS=$'\n'
local imports=( $(
for platform in "${storagePlatforms[@]}"; do
export GOOS="${platform%/*}";
export GOARCH="${platform##*/}";
for buildTags in "${buildTagCombos[@]}"; do
go list -e -tags "$buildTags" -f '{{join .Deps "\n"}}' "${packages[@]}"
go list -e -tags "$buildTags" -f '{{join .TestImports "\n"}}' "${packages[@]}"
done
done | grep -vE "^${PROJECT}/" | sort -u
) )
imports=( $(go list -e -f '{{if not .Standard}}{{.ImportPath}}{{end}}' "${imports[@]}") )
unset IFS
echo -n 'pruning unused packages, '
findArgs=-false
for import in "${imports[@]}"; do
[ "${#findArgs[@]}" -eq 0 ] || findArgs+=( -or )
findArgs+=( -path "vendor/src/$import" )
done
local IFS=$'\n'
local prune=( $($find vendor -depth -type d -not '(' "${findArgs[@]}" ')') )
unset IFS
for dir in "${prune[@]}"; do
$find "$dir" -maxdepth 1 -not -type d -not -name 'LICENSE*' -not -name 'COPYING*' -exec rm -v -f '{}' ';'
rmdir "$dir" 2>/dev/null || true
done
echo -n 'pruning unused files, '
$find vendor -type f -name '*_test.go' -exec rm -v '{}' ';'
$find vendor -type f -name 'Vagrantfile' -exec rm -v '{}' ';'
# These are the files that are left over after fix_rewritten_imports is run.
echo -n 'pruning .orig files, '
$find vendor -type f -name '*.orig' -exec rm -v '{}' ';'
echo done
}
# Fix up hard-coded imports that refer to Godeps paths so they'll work with our vendoring
fix_rewritten_imports () {
local pkg="$1"
local remove="${pkg}/Godeps/_workspace/src/"
local target="vendor/src/$pkg"
echo "$pkg: fixing rewritten imports"
$find "$target" -name \*.go -exec sed -i'.orig' -e "s|\"${remove}|\"|g" {} \;
}

View file

@ -17,6 +17,7 @@ set -e
set -o pipefail set -o pipefail
export PATH=/usr/local/go/bin:${PATH}
export PKG='github.com/containers/storage' export PKG='github.com/containers/storage'
export SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" export SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
export MAKEDIR="$SCRIPTDIR/make" export MAKEDIR="$SCRIPTDIR/make"
@ -71,22 +72,16 @@ else
exit 1 exit 1
fi fi
if [ "$AUTO_GOPATH" ]; then export GOPATH="${GOPATH:-/go}"
rm -rf .gopath
mkdir -p .gopath/src/"$(dirname "${PKG}")"
ln -sf ../../../.. .gopath/src/"${PKG}"
export GOPATH="${PWD}/.gopath:${PWD}/vendor"
if [ "$(go env GOOS)" = 'solaris' ]; then if [ "$(go env GOOS)" = 'solaris' ]; then
# sys/unix is installed outside the standard library on solaris # sys/unix is installed outside the standard library on solaris
# TODO need to allow for version change, need to get version from go # TODO need to allow for version change, need to get version from go
export GOPATH="${GOPATH}:/usr/lib/gocode/1.6.2" export GOPATH="${GOPATH}:/usr/lib/gocode/1.6.2"
fi
fi fi
if [ ! "$GOPATH" ]; then if [ ! "$GOPATH" ]; then
echo >&2 'error: missing GOPATH; please see https://golang.org/doc/code.html#GOPATH' echo >&2 'error: missing GOPATH; please see https://golang.org/doc/code.html#GOPATH'
echo >&2 ' alternatively, set AUTO_GOPATH=1'
exit 1 exit 1
fi fi
@ -186,7 +181,7 @@ test_env() {
GOPATH="$GOPATH" \ GOPATH="$GOPATH" \
GOTRACEBACK=all \ GOTRACEBACK=all \
HOME="$ABS_DEST/fake-HOME" \ HOME="$ABS_DEST/fake-HOME" \
PATH="$PATH" \ PATH="${GOPATH}/bin:/usr/local/go/bin:$PATH" \
TEMP="$TEMP" \ TEMP="$TEMP" \
"$@" "$@"
} }

View file

@ -7,6 +7,7 @@ BINARY_FULLNAME="$BINARY_NAME$BINARY_EXTENSION"
source "${MAKEDIR}/.go-autogen" source "${MAKEDIR}/.go-autogen"
export GCCGO=${SCRIPTDIR}/../vagrant/gccgo-wrapper.sh
# gccgo require explicit flag -pthread to allow goroutines to work. # gccgo require explicit flag -pthread to allow goroutines to work.
go build -compiler=gccgo \ go build -compiler=gccgo \
-o "$DEST/$BINARY_FULLNAME" \ -o "$DEST/$BINARY_FULLNAME" \

View file

@ -1,27 +0,0 @@
#!/bin/bash
source "${MAKEDIR}/.validate"
IFS=$'\n'
files=( $(validate_diff --diff-filter=ACMR --name-only -- 'hack/vendor.sh' 'hack/.vendor-helpers.sh' 'vendor/' || true) )
unset IFS
if [ ${#files[@]} -gt 0 ]; then
# We run vendor.sh to and see if we have a diff afterwards
./hack/vendor.sh >/dev/null
# Let see if the working directory is clean
diffs="$(git status --porcelain -- vendor 2>/dev/null)"
if [ "$diffs" ]; then
{
echo 'The result of ./hack/vendor.sh differs'
echo
echo "$diffs"
echo
echo 'Please vendor your package with ./hack/vendor.sh.'
echo
} >&2
false
else
echo 'Congratulations! All vendoring changes are done the right way.'
fi
fi

View file

@ -1,61 +0,0 @@
#!/usr/bin/env bash
set -e
# this script is used to update vendored dependencies
#
# Usage:
# vendor.sh revendor all dependencies
# vendor.sh github.com/docker/engine-api revendor only the engine-api dependency.
# vendor.sh github.com/docker/engine-api v0.3.3 vendor only engine-api at the specified tag/commit.
# vendor.sh git github.com/docker/engine-api v0.3.3 is the same but specifies the VCS for cases where the VCS is something else than git
# vendor.sh git golang.org/x/sys eb2c74142fd19a79b3f237334c7384d5167b1b46 https://github.com/golang/sys.git vendor only golang.org/x/sys downloading from the specified URL
cd "$(dirname "$BASH_SOURCE")/.."
source 'hack/.vendor-helpers.sh'
case $# in
0)
rm -rf vendor/
;;
# If user passed arguments to the script
1)
eval "$(grep -E "^clone [^ ]+ $1" "$0")"
clean
exit 0
;;
2)
rm -rf "vendor/src/$1"
clone git "$1" "$2"
clean
exit 0
;;
[34])
rm -rf "vendor/src/$2"
clone "$@"
clean
exit 0
;;
*)
>&2 echo "error: unexpected parameters"
exit 1
;;
esac
# the following lines are in sorted order, FYI
clone git github.com/Microsoft/hcsshim v0.3.6
clone git github.com/Microsoft/go-winio v0.3.4
clone git github.com/Sirupsen/logrus v0.10.0 # logrus is a common dependency among multiple deps
# forked golang.org/x/net package includes a patch for lazy loading trace templates
clone git golang.org/x/net 2beffdc2e92c8a3027590f898fe88f69af48a3f8 https://github.com/tonistiigi/net.git
clone git golang.org/x/sys eb2c74142fd19a79b3f237334c7384d5167b1b46 https://github.com/golang/sys.git
clone git github.com/docker/go-units 651fc226e7441360384da338d0fd37f2440ffbe3
clone git github.com/docker/go-connections fa2850ff103453a9ad190da0df0af134f0314b3d
clone git github.com/docker/engine-api 1d247454d4307fb1ddf10d09fd2996394b085904
# get graph and distribution packages
clone git github.com/vbatts/tar-split v0.9.13
# get go-zfs packages
clone git github.com/mistifyio/go-zfs 22c9b32c84eb0d0c6f4043b6e90fc94073de92fa
clone git github.com/pborman/uuid v1.0
clone git github.com/opencontainers/runc cc29e3dded8e27ba8f65738f40d251c885030a28 # libcontainer
clean

View file

@ -4,8 +4,6 @@ import (
"crypto/sha256" "crypto/sha256"
"encoding/hex" "encoding/hex"
"io" "io"
"golang.org/x/net/context"
) )
type readCloserWrapper struct { type readCloserWrapper struct {
@ -83,72 +81,3 @@ func (r *OnEOFReader) runFunc() {
r.Fn = nil r.Fn = nil
} }
} }
// cancelReadCloser wraps an io.ReadCloser with a context for cancelling read
// operations.
type cancelReadCloser struct {
cancel func()
pR *io.PipeReader // Stream to read from
pW *io.PipeWriter
}
// NewCancelReadCloser creates a wrapper that closes the ReadCloser when the
// context is cancelled. The returned io.ReadCloser must be closed when it is
// no longer needed.
func NewCancelReadCloser(ctx context.Context, in io.ReadCloser) io.ReadCloser {
pR, pW := io.Pipe()
// Create a context used to signal when the pipe is closed
doneCtx, cancel := context.WithCancel(context.Background())
p := &cancelReadCloser{
cancel: cancel,
pR: pR,
pW: pW,
}
go func() {
_, err := io.Copy(pW, in)
select {
case <-ctx.Done():
// If the context was closed, p.closeWithError
// was already called. Calling it again would
// change the error that Read returns.
default:
p.closeWithError(err)
}
in.Close()
}()
go func() {
for {
select {
case <-ctx.Done():
p.closeWithError(ctx.Err())
case <-doneCtx.Done():
return
}
}
}()
return p
}
// Read wraps the Read method of the pipe that provides data from the wrapped
// ReadCloser.
func (p *cancelReadCloser) Read(buf []byte) (n int, err error) {
return p.pR.Read(buf)
}
// closeWithError closes the wrapper and its underlying reader. It will
// cause future calls to Read to return err.
func (p *cancelReadCloser) closeWithError(err error) {
p.pW.CloseWithError(err)
p.cancel()
}
// Close closes the wrapper its underlying reader. It will cause
// future calls to Read to return io.EOF.
func (p *cancelReadCloser) Close() error {
p.closeWithError(io.EOF)
return nil
}

View file

@ -2,19 +2,15 @@ package ioutils
import ( import (
"fmt" "fmt"
"io/ioutil"
"strings" "strings"
"testing" "testing"
"time"
"golang.org/x/net/context"
) )
// Implement io.Reader // Implement io.Reader
type errorReader struct{} type errorReader struct{}
func (r *errorReader) Read(p []byte) (int, error) { func (r *errorReader) Read(p []byte) (int, error) {
return 0, fmt.Errorf("Error reader always fail.") return 0, fmt.Errorf("error reader always fail")
} }
func TestReadCloserWrapperClose(t *testing.T) { func TestReadCloserWrapperClose(t *testing.T) {
@ -35,7 +31,7 @@ func TestReaderErrWrapperReadOnError(t *testing.T) {
called = true called = true
}) })
_, err := wrapper.Read([]byte{}) _, err := wrapper.Read([]byte{})
if err == nil || !strings.Contains(err.Error(), "Error reader always fail.") { if err == nil || !strings.Contains(err.Error(), "error reader always fail") {
t.Fatalf("readErrWrapper should returned an error") t.Fatalf("readErrWrapper should returned an error")
} }
if !called { if !called {
@ -78,17 +74,3 @@ func (p *perpetualReader) Read(buf []byte) (n int, err error) {
} }
return len(buf), nil return len(buf), nil
} }
func TestCancelReadCloser(t *testing.T) {
ctx, _ := context.WithTimeout(context.Background(), 100*time.Millisecond)
cancelReadCloser := NewCancelReadCloser(ctx, ioutil.NopCloser(&perpetualReader{}))
for {
var buf [128]byte
_, err := cancelReadCloser.Read(buf[:])
if err == context.DeadlineExceeded {
break
} else if err != nil {
t.Fatalf("got unexpected error: %v", err)
}
}
}

View file

@ -151,6 +151,9 @@ func (r *containerStore) Load() error {
func (r *containerStore) Save() error { func (r *containerStore) Save() error {
rpath := r.containerspath() rpath := r.containerspath()
if err := os.MkdirAll(filepath.Dir(rpath), 0700); err != nil {
return err
}
jdata, err := json.Marshal(&r.containers) jdata, err := json.Marshal(&r.containers)
if err != nil { if err != nil {
return err return err

View file

@ -142,6 +142,9 @@ func (r *imageStore) Load() error {
func (r *imageStore) Save() error { func (r *imageStore) Save() error {
rpath := r.imagespath() rpath := r.imagespath()
if err := os.MkdirAll(filepath.Dir(rpath), 0700); err != nil {
return err
}
jdata, err := json.Marshal(&r.images) jdata, err := json.Marshal(&r.images)
if err != nil { if err != nil {
return err return err

View file

@ -252,11 +252,17 @@ func (r *layerStore) Load() error {
func (r *layerStore) Save() error { func (r *layerStore) Save() error {
rpath := r.layerspath() rpath := r.layerspath()
if err := os.MkdirAll(filepath.Dir(rpath), 0700); err != nil {
return err
}
jldata, err := json.Marshal(&r.layers) jldata, err := json.Marshal(&r.layers)
if err != nil { if err != nil {
return err return err
} }
mpath := r.mountspath() mpath := r.mountspath()
if err := os.MkdirAll(filepath.Dir(mpath), 0700); err != nil {
return err
}
mounts := []layerMountPoint{} mounts := []layerMountPoint{}
for _, layer := range r.layers { for _, layer := range r.layers {
if layer.MountPoint != "" && layer.MountCount > 0 { if layer.MountPoint != "" && layer.MountCount > 0 {
@ -846,6 +852,9 @@ func (r *layerStore) ApplyDiff(to string, diff archive.Reader) (size int64, err
size, err = r.driver.ApplyDiff(layer.ID, layer.Parent, payload) size, err = r.driver.ApplyDiff(layer.ID, layer.Parent, payload)
compressor.Close() compressor.Close()
if err == nil { if err == nil {
if err := os.MkdirAll(filepath.Dir(r.tspath(layer.ID)), 0700); err != nil {
return -1, err
}
if err := ioutils.AtomicWriteFile(r.tspath(layer.ID), tsdata.Bytes(), 0600); err != nil { if err := ioutils.AtomicWriteFile(r.tspath(layer.ID), tsdata.Bytes(), 0600); err != nil {
return -1, err return -1, err
} }

View file

@ -749,6 +749,9 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat
id = stringid.GenerateRandomID() id = stringid.GenerateRandomID()
} }
imageTopLayer := ""
imageID := ""
if image != "" {
cimage, err := ristore.Get(image) cimage, err := ristore.Get(image)
if err != nil { if err != nil {
return nil, err return nil, err
@ -756,12 +759,15 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat
if cimage == nil { if cimage == nil {
return nil, ErrImageUnknown return nil, ErrImageUnknown
} }
clayer, err := rlstore.Create(layer, cimage.TopLayer, nil, "", nil, true) imageTopLayer = cimage.TopLayer
imageID = cimage.ID
}
clayer, err := rlstore.Create(layer, imageTopLayer, nil, "", nil, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
layer = clayer.ID layer = clayer.ID
container, err := rcstore.Create(id, names, cimage.ID, layer, metadata) container, err := rcstore.Create(id, names, imageID, layer, metadata)
if err != nil || container == nil { if err != nil || container == nil {
rlstore.Delete(layer) rlstore.Delete(layer)
} }
@ -2171,8 +2177,8 @@ func makeBigDataBaseName(key string) string {
} }
func init() { func init() {
DefaultStoreOptions.RunRoot = "/var/run/containers" DefaultStoreOptions.RunRoot = "/var/run/containers/storage"
DefaultStoreOptions.GraphRoot = "/var/lib/containers" DefaultStoreOptions.GraphRoot = "/var/lib/containers/storage"
DefaultStoreOptions.GraphDriverName = os.Getenv("STORAGE_DRIVER") DefaultStoreOptions.GraphDriverName = os.Getenv("STORAGE_DRIVER")
DefaultStoreOptions.GraphDriverOptions = strings.Split(os.Getenv("STORAGE_OPTS"), ",") DefaultStoreOptions.GraphDriverOptions = strings.Split(os.Getenv("STORAGE_OPTS"), ",")
if len(DefaultStoreOptions.GraphDriverOptions) == 1 && DefaultStoreOptions.GraphDriverOptions[0] == "" { if len(DefaultStoreOptions.GraphDriverOptions) == 1 && DefaultStoreOptions.GraphDriverOptions[0] == "" {

View file

@ -0,0 +1,9 @@
#!/bin/bash
additional=
for arg in "$@" ; do
if test -d "$arg"/github.com/containers/storage ; then
additional="$additional -I $arg/github.com/containers/storage/vendor"
fi
done
echo gccgo $additional "$@" > /tmp/gccgo
gccgo $additional "$@"

View file

@ -1,6 +1,8 @@
#!/bin/bash #!/bin/bash
set -e set -xe
source /etc/os-release source /etc/os-release
case "${ID_LIKE:-${ID:-unknown}}" in case "${ID_LIKE:-${ID:-unknown}}" in
debian) debian)
export DEBIAN_FRONTEND=noninteractive export DEBIAN_FRONTEND=noninteractive
@ -9,16 +11,15 @@ case "${ID_LIKE:-${ID:-unknown}}" in
echo deb http://httpredir.debian.org/debian testing main > /etc/apt/sources.list echo deb http://httpredir.debian.org/debian testing main > /etc/apt/sources.list
echo deb http://httpredir.debian.org/debian testing contrib >> /etc/apt/sources.list echo deb http://httpredir.debian.org/debian testing contrib >> /etc/apt/sources.list
apt-get -q update apt-get -q update
apt-get -q -y install systemd apt-get -q -y install systemd curl
apt-get -q -y install apt make git gccgo golang btrfs-progs libdevmapper-dev apt-get -q -y install apt make git btrfs-progs libdevmapper-dev
apt-get -q -y install zfs-dkms zfsutils-linux apt-get -q -y install zfs-dkms zfsutils-linux
modprobe aufs apt-get -q -y install golang gccgo
modprobe zfs
;; ;;
fedora) fedora)
dnf -y clean all dnf -y clean all
dnf -y install golang-bin make git-core btrfs-progs-devel device-mapper-devel dnf -y install make git gcc btrfs-progs-devel device-mapper-devel
dnf -y install gcc-go dnf -y install golang gcc-go
alternatives --set go /usr/lib/golang/bin/go alternatives --set go /usr/lib/golang/bin/go
;; ;;
unknown) unknown)
@ -29,6 +30,7 @@ esac
mkdir -p /go/src/github.com/containers mkdir -p /go/src/github.com/containers
rm -f /go/src/github.com/containers/storage rm -f /go/src/github.com/containers/storage
ln -s /vagrant /go/src/github.com/containers/storage ln -s /vagrant /go/src/github.com/containers/storage
export GOPATH=/go:/go/src/github.com/containers/storage/vendor export GOPATH=/go
export PATH=/usr/lib/go-1.6/bin:/go/src/${PKG}/vendor/src/github.com/golang/lint/golint:${PATH} export PATH=/go/bin:${PATH}
go get github.com/golang/lint go get github.com/golang/lint/...
exit 0

View file

@ -3,18 +3,20 @@ set -e
export PKG='github.com/containers/storage' export PKG='github.com/containers/storage'
export VAGRANT_MACHINES="fedora debian" export VAGRANT_MACHINES="fedora debian"
if test -z "$VAGRANT_PROVIDER" ; then if test -z "$VAGRANT_PROVIDER" ; then
if lsmod | grep -q '^kvm ' ; then if lsmod | grep -q '^vboxdrv ' ; then
VAGRANT_PROVIDER=libvirt
elif lsmod | grep -q '^vboxdrv ' ; then
VAGRANT_PROVIDER=virtualbox VAGRANT_PROVIDER=virtualbox
elif lsmod | grep -q '^kvm ' ; then
VAGRANT_PROVIDER=libvirt
fi fi
fi fi
export VAGRANT_PROVIDER=${VAGRANT_PROVIDER:-libvirt} export VAGRANT_PROVIDER=${VAGRANT_PROVIDER:-libvirt}
export VAGRANT_PROVIDER=${VAGRANT_PROVIDER:-virtualbox} export VAGRANT_PROVIDER=${VAGRANT_PROVIDER:-virtualbox}
if ${IN_VAGRANT_MACHINE:-false} ; then if ${IN_VAGRANT_MACHINE:-false} ; then
unset AUTO_GOPATH unset AUTO_GOPATH
export GOPATH=/go:/go/src/${PKG}/vendor export GOPATH=/go
export PATH=/usr/lib/go-1.6/bin:/go/src/${PKG}/vendor/src/github.com/golang/lint/golint:${PATH} export PATH=${GOPATH}/bin:/go/src/${PKG}/vendor/src/github.com/golang/lint/golint:${PATH}
sudo modprobe aufs || true
sudo modprobe zfs || true
"$@" "$@"
else else
vagrant up --provider ${VAGRANT_PROVIDER} vagrant up --provider ${VAGRANT_PROVIDER}

16
vendor/github.com/containers/storage/vendor.conf generated vendored Normal file
View file

@ -0,0 +1,16 @@
github.com/Microsoft/go-winio 307e919c663683a9000576fdc855acaf9534c165
github.com/Microsoft/hcsshim 0f615c198a84e0344b4ed49c464d8833d4648dfc
github.com/Sirupsen/logrus 61e43dc76f7ee59a82bdf3d71033dc12bea4c77d
github.com/docker/engine-api 4290f40c056686fcaa5c9caf02eac1dde9315adf
github.com/docker/go-connections eb315e36415380e7c2fdee175262560ff42359da
github.com/docker/go-units 0dadbb0345b35ec7ef35e228dabb8de89a65bf52
github.com/go-check/check 20d25e2804050c1cd24a7eea1e7a6447dd0e74ec
github.com/mattn/go-shellwords 753a2322a99f87c0eff284980e77f53041555bc6
github.com/mistifyio/go-zfs c0224de804d438efd11ea6e52ada8014537d6062
github.com/opencontainers/runc 6c22e77604689db8725fa866f0f2ec0b3e8c3a07
github.com/opencontainers/selinux ba1aefe8057f1d0cfb8e88d0ec1dc85925ef987d
github.com/pborman/uuid 1b00554d822231195d1babd97ff4a781231955c9
github.com/vbatts/tar-split bd4c5d64c3e9297f410025a3b1bd0c58f659e721
github.com/vdemeester/shakers 24d7f1d6a71aa5d9cbe7390e4afb66b7eef9e1b3
golang.org/x/net f2499483f923065a842d38eb4c7f1927e6fc6e6d
golang.org/x/sys d75a52659825e75fff6158388dddc6a5b04f9ba5