Run (make vendor)

Temporarily vendor opencontainers/image-spec from a fork
to fix "id" value duplication, which is detected and
refused by gojsonschema now
( https://github.com/opencontainers/image-spec/pull/750 ).

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This commit is contained in:
Miloslav Trmač
2018-09-17 14:12:12 +02:00
parent a581847345
commit 67ffa00b1d
195 changed files with 21962 additions and 3828 deletions

View File

@@ -192,6 +192,9 @@ func (r *containerStore) Load() error {
}
func (r *containerStore) Save() error {
if !r.Locked() {
return errors.New("container store is not locked")
}
rpath := r.containerspath()
if err := os.MkdirAll(filepath.Dir(rpath), 0700); err != nil {
return err
@@ -560,3 +563,7 @@ func (r *containerStore) IsReadWrite() bool {
func (r *containerStore) TouchedSince(when time.Time) bool {
return r.lockfile.TouchedSince(when)
}
func (r *containerStore) Locked() bool {
return r.lockfile.Locked()
}

View File

@@ -42,6 +42,7 @@ import (
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/locker"
mountpk "github.com/containers/storage/pkg/mount"
"github.com/containers/storage/pkg/parsers"
"github.com/containers/storage/pkg/system"
rsystem "github.com/opencontainers/runc/libcontainer/system"
"github.com/opencontainers/selinux/go-selinux/label"
@@ -77,6 +78,7 @@ type Driver struct {
pathCache map[string]string
naiveDiff graphdriver.DiffDriver
locker *locker.Locker
mountOptions string
}
// Init returns a new AUFS driver.
@@ -103,6 +105,20 @@ func Init(root string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
return nil, errors.Wrapf(graphdriver.ErrIncompatibleFS, "AUFS is not supported over %q", backingFs)
}
var mountOptions string
for _, option := range options {
key, val, err := parsers.ParseKeyValueOpt(option)
if err != nil {
return nil, err
}
key = strings.ToLower(key)
switch key {
case "aufs.mountopt":
mountOptions = val
default:
return nil, fmt.Errorf("option %s not supported", option)
}
}
paths := []string{
"mnt",
"diff",
@@ -110,12 +126,13 @@ func Init(root string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
}
a := &Driver{
root: root,
uidMaps: uidMaps,
gidMaps: gidMaps,
pathCache: make(map[string]string),
ctr: graphdriver.NewRefCounter(graphdriver.NewFsChecker(graphdriver.FsMagicAufs)),
locker: locker.New(),
root: root,
uidMaps: uidMaps,
gidMaps: gidMaps,
pathCache: make(map[string]string),
ctr: graphdriver.NewRefCounter(graphdriver.NewFsChecker(graphdriver.FsMagicAufs)),
locker: locker.New(),
mountOptions: mountOptions,
}
rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
@@ -399,7 +416,7 @@ func atomicRemove(source string) error {
// Get returns the rootfs path for the id.
// This will mount the dir at its given path
func (a *Driver) Get(id, mountLabel string) (string, error) {
func (a *Driver) Get(id, mountLabel string, uidMaps, gidMaps []idtools.IDMap) (string, error) {
a.locker.Lock(id)
defer a.locker.Unlock(id)
parents, err := a.getParentLayerPaths(id)
@@ -653,6 +670,10 @@ func (a *Driver) aufsMount(ro []string, rw, target, mountLabel string) (err erro
}
opts := "dio,xino=/dev/shm/aufs.xino"
if a.mountOptions != "" {
opts += fmt.Sprintf(",%s", a.mountOptions)
}
if useDirperm() {
opts += ",dirperm1"
}
@@ -707,3 +728,8 @@ func useDirperm() bool {
func (a *Driver) UpdateLayerIDMap(id string, toContainer, toHost *idtools.IDMappings, mountLabel string) error {
return fmt.Errorf("aufs doesn't support changing ID mappings")
}
// SupportsShifting tells whether the driver support shifting of the UIDs/GIDs in an userNS
func (a *Driver) SupportsShifting() bool {
return false
}

View File

@@ -110,6 +110,8 @@ func parseOptions(opt []string) (btrfsOptions, bool, error) {
}
userDiskQuota = true
options.minSpace = uint64(minSpace)
case "btrfs.mountopt":
return options, userDiskQuota, fmt.Errorf("btrfs driver does not support mount options")
default:
return options, userDiskQuota, fmt.Errorf("Unknown option %s", key)
}
@@ -632,7 +634,7 @@ func (d *Driver) Remove(id string) error {
}
// Get the requested filesystem id.
func (d *Driver) Get(id, mountLabel string) (string, error) {
func (d *Driver) Get(id, mountLabel string, uidMaps, gidMaps []idtools.IDMap) (string, error) {
dir := d.subvolumesDirID(id)
st, err := os.Stat(dir)
if err != nil {

View File

@@ -114,7 +114,7 @@ func NewNaiveLayerIDMapUpdater(driver ProtoDriver) LayerIDMapUpdater {
// same "container" IDs.
func (n *naiveLayerIDMapUpdater) UpdateLayerIDMap(id string, toContainer, toHost *idtools.IDMappings, mountLabel string) error {
driver := n.ProtoDriver
layerFs, err := driver.Get(id, mountLabel)
layerFs, err := driver.Get(id, mountLabel, nil, nil)
if err != nil {
return err
}
@@ -124,3 +124,8 @@ func (n *naiveLayerIDMapUpdater) UpdateLayerIDMap(id string, toContainer, toHost
return ChownPathByMaps(layerFs, toContainer, toHost)
}
// SupportsShifting tells whether the driver support shifting of the UIDs/GIDs in an userNS
func (n *naiveLayerIDMapUpdater) SupportsShifting() bool {
return false
}

View File

@@ -2690,7 +2690,7 @@ func NewDeviceSet(root string, doInit bool, options []string, uidMaps, gidMaps [
devices.filesystem = val
case "dm.mkfsarg":
devices.mkfsArgs = append(devices.mkfsArgs, val)
case "dm.mountopt":
case "dm.mountopt", "devicemapper.mountopt":
devices.mountOptions = joinMountOptions(devices.mountOptions, val)
case "dm.metadatadev":
devices.metadataDevice = val

View File

@@ -163,7 +163,7 @@ func (d *Driver) Remove(id string) error {
}
// Get mounts a device with given id into the root filesystem
func (d *Driver) Get(id, mountLabel string) (string, error) {
func (d *Driver) Get(id, mountLabel string, uidMaps, gidMaps []idtools.IDMap) (string, error) {
d.locker.Lock(id)
defer d.locker.Unlock(id)
mp := path.Join(d.home, "mnt", id)

View File

@@ -66,8 +66,9 @@ type ProtoDriver interface {
Remove(id string) error
// Get returns the mountpoint for the layered filesystem referred
// to by this id. You can optionally specify a mountLabel or "".
// Optionally it gets the mappings used to create the layer.
// Returns the absolute path to the mounted layered filesystem.
Get(id, mountLabel string) (dir string, err error)
Get(id, mountLabel string, uidMaps, gidMaps []idtools.IDMap) (dir string, err error)
// Put releases the system resources for the specified id,
// e.g, unmounting layered filesystem.
Put(id string) error
@@ -118,6 +119,10 @@ type LayerIDMapUpdater interface {
// relative to a parent layer, but before this method is called, may be discarded
// by Diff().
UpdateLayerIDMap(id string, toContainer, toHost *idtools.IDMappings, mountLabel string) error
// SupportsShifting tells whether the driver support shifting of the UIDs/GIDs in a
// image and it is not required to Chown the files when running in an user namespace.
SupportsShifting() bool
}
// Driver is the interface for layered/snapshot file system drivers.

View File

@@ -51,7 +51,7 @@ func (gdw *NaiveDiffDriver) Diff(id string, idMappings *idtools.IDMappings, pare
parentMappings = &idtools.IDMappings{}
}
layerFs, err := driver.Get(id, mountLabel)
layerFs, err := driver.Get(id, mountLabel, nil, nil)
if err != nil {
return nil, err
}
@@ -78,7 +78,7 @@ func (gdw *NaiveDiffDriver) Diff(id string, idMappings *idtools.IDMappings, pare
}), nil
}
parentFs, err := driver.Get(parent, mountLabel)
parentFs, err := driver.Get(parent, mountLabel, nil, nil)
if err != nil {
return nil, err
}
@@ -119,7 +119,7 @@ func (gdw *NaiveDiffDriver) Changes(id string, idMappings *idtools.IDMappings, p
parentMappings = &idtools.IDMappings{}
}
layerFs, err := driver.Get(id, mountLabel)
layerFs, err := driver.Get(id, mountLabel, nil, nil)
if err != nil {
return nil, err
}
@@ -128,7 +128,7 @@ func (gdw *NaiveDiffDriver) Changes(id string, idMappings *idtools.IDMappings, p
parentFs := ""
if parent != "" {
parentFs, err = driver.Get(parent, mountLabel)
parentFs, err = driver.Get(parent, mountLabel, nil, nil)
if err != nil {
return nil, err
}
@@ -149,7 +149,7 @@ func (gdw *NaiveDiffDriver) ApplyDiff(id string, applyMappings *idtools.IDMappin
}
// Mount the root filesystem so we can apply the diff/layer.
layerFs, err := driver.Get(id, mountLabel)
layerFs, err := driver.Get(id, mountLabel, nil, nil)
if err != nil {
return
}
@@ -189,7 +189,7 @@ func (gdw *NaiveDiffDriver) DiffSize(id string, idMappings *idtools.IDMappings,
return
}
layerFs, err := driver.Get(id, mountLabel)
layerFs, err := driver.Get(id, mountLabel, nil, nil)
if err != nil {
return
}

View File

@@ -3,6 +3,7 @@
package overlay
import (
"bytes"
"fmt"
"io"
"io/ioutil"
@@ -88,6 +89,7 @@ type overlayOptions struct {
mountProgram string
ostreeRepo string
skipMountHome bool
mountOptions string
}
// Driver contains information about the home directory and the list of active mounts that are created using this driver.
@@ -222,6 +224,8 @@ func parseOptions(options []string) (*overlayOptions, error) {
if err != nil {
return nil, err
}
case ".mountopt", "overlay.mountopt", "overlay2.mountopt":
o.mountOptions = val
case ".size", "overlay.size", "overlay2.size":
logrus.Debugf("overlay: size=%s", val)
size, err := units.RAMInBytes(val)
@@ -587,6 +591,32 @@ func (d *Driver) getLowerDirs(id string) ([]string, error) {
return lowersArray, nil
}
func (d *Driver) optsAppendMappings(opts string, uidMaps, gidMaps []idtools.IDMap) string {
if uidMaps == nil {
uidMaps = d.uidMaps
}
if gidMaps == nil {
gidMaps = d.gidMaps
}
if uidMaps != nil {
var uids, gids bytes.Buffer
for _, i := range uidMaps {
if uids.Len() > 0 {
uids.WriteString(":")
}
uids.WriteString(fmt.Sprintf("%d:%d:%d", i.ContainerID, i.HostID, i.Size))
}
for _, i := range gidMaps {
if gids.Len() > 0 {
gids.WriteString(":")
}
gids.WriteString(fmt.Sprintf("%d:%d:%d", i.ContainerID, i.HostID, i.Size))
}
return fmt.Sprintf("%s,uidmapping=%s,gidmapping=%s", opts, uids.String(), gids.String())
}
return opts
}
// Remove cleans the directories that are created for this id.
func (d *Driver) Remove(id string) error {
d.locker.Lock(id)
@@ -612,7 +642,11 @@ func (d *Driver) Remove(id string) error {
}
// Get creates and mounts the required file system for the given id and returns the mount path.
func (d *Driver) Get(id, mountLabel string) (_ string, retErr error) {
func (d *Driver) Get(id, mountLabel string, uidMaps, gidMaps []idtools.IDMap) (_ string, retErr error) {
return d.get(id, mountLabel, false, uidMaps, gidMaps)
}
func (d *Driver) get(id, mountLabel string, disableShifting bool, uidMaps, gidMaps []idtools.IDMap) (_ string, retErr error) {
d.locker.Lock(id)
defer d.locker.Unlock(id)
dir := d.dir(id)
@@ -703,8 +737,11 @@ func (d *Driver) Get(id, mountLabel string) (_ string, retErr error) {
workDir := path.Join(dir, "work")
opts := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", strings.Join(absLowers, ":"), diffDir, workDir)
if d.options.mountOptions != "" {
opts = fmt.Sprintf("%s,%s", d.options.mountOptions, opts)
}
mountData := label.FormatMountLabel(opts, mountLabel)
mount := unix.Mount
mountFunc := unix.Mount
mountTarget := mergedDir
pageSize := unix.Getpagesize()
@@ -713,28 +750,30 @@ func (d *Driver) Get(id, mountLabel string) (_ string, retErr error) {
// the page size. The mount syscall fails if the mount data cannot
// fit within a page and relative links make the mount data much
// smaller at the expense of requiring a fork exec to chroot.
if len(mountData) > pageSize || d.options.mountProgram != "" {
if d.options.mountProgram != "" {
mountFunc = func(source string, target string, mType string, flags uintptr, label string) error {
if !disableShifting {
label = d.optsAppendMappings(label, uidMaps, gidMaps)
}
mountProgram := exec.Command(d.options.mountProgram, "-o", label, target)
mountProgram.Dir = d.home
return mountProgram.Run()
}
} else if len(mountData) > pageSize {
//FIXME: We need to figure out to get this to work with additional stores
opts = fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", strings.Join(relLowers, ":"), path.Join(id, "diff"), path.Join(id, "work"))
mountData = label.FormatMountLabel(opts, mountLabel)
if len(mountData) > pageSize {
return "", fmt.Errorf("cannot mount layer, mount label too large %d", len(mountData))
}
if d.options.mountProgram != "" {
mount = func(source string, target string, mType string, flags uintptr, label string) error {
mountProgram := exec.Command(d.options.mountProgram, "-o", label, target)
mountProgram.Dir = d.home
return mountProgram.Run()
}
} else {
mount = func(source string, target string, mType string, flags uintptr, label string) error {
return mountFrom(d.home, source, target, mType, flags, label)
}
mountFunc = func(source string, target string, mType string, flags uintptr, label string) error {
return mountFrom(d.home, source, target, mType, flags, label)
}
mountTarget = path.Join(id, "merged")
}
if err := mount("overlay", mountTarget, "overlay", 0, mountData); err != nil {
flags, data := mount.ParseOptions(mountData)
if err := mountFunc("overlay", mountTarget, "overlay", uintptr(flags), data); err != nil {
return "", fmt.Errorf("error creating overlay mount to %s: %v", mountTarget, err)
}
@@ -913,7 +952,7 @@ func (d *Driver) UpdateLayerIDMap(id string, toContainer, toHost *idtools.IDMapp
}
// Mount the new layer and handle ownership changes and possible copy_ups in it.
layerFs, err := d.Get(id, mountLabel)
layerFs, err := d.get(id, mountLabel, true, nil, nil)
if err != nil {
return err
}
@@ -950,6 +989,14 @@ func (d *Driver) UpdateLayerIDMap(id string, toContainer, toHost *idtools.IDMapp
return nil
}
// SupportsShifting tells whether the driver support shifting of the UIDs/GIDs in an userNS
func (d *Driver) SupportsShifting() bool {
if os.Getenv("_TEST_FORCE_SUPPORT_SHIFTING") == "yes-please" {
return true
}
return d.options.mountProgram != ""
}
// dumbJoin is more or less a dumber version of filepath.Join, but one which
// won't Clean() the path, allowing us to append ".." as a component and trust
// pathname resolution to do some non-obvious work.

View File

@@ -55,6 +55,9 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
}
d.ostreeRepo = option[13:]
}
if strings.HasPrefix(option, "vfs.mountopt=") {
return nil, fmt.Errorf("vfs driver does not support mount options")
}
}
if d.ostreeRepo != "" {
rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
@@ -134,7 +137,7 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, ro bool
label.SetFileLabel(dir, mountLabel)
}
if parent != "" {
parentDir, err := d.Get(parent, "")
parentDir, err := d.Get(parent, "", nil, nil)
if err != nil {
return fmt.Errorf("%s: %s", parent, err)
}
@@ -176,7 +179,7 @@ func (d *Driver) Remove(id string) error {
}
// Get returns the directory for the given id.
func (d *Driver) Get(id, mountLabel string) (string, error) {
func (d *Driver) Get(id, mountLabel string, uidMaps, gidMaps []idtools.IDMap) (string, error) {
dir := d.dir(id)
if st, err := os.Stat(dir); err != nil {
return "", err

View File

@@ -86,6 +86,14 @@ type Driver struct {
func InitFilter(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (graphdriver.Driver, error) {
logrus.Debugf("WindowsGraphDriver InitFilter at %s", home)
for _, option := range options {
if strings.HasPrefix(option, "windows.mountopt=") {
return nil, fmt.Errorf("windows driver does not support mount options")
} else {
return nil, fmt.Errorf("option %s not supported", option)
}
}
fsType, err := getFileSystemType(string(home[0]))
if err != nil {
return nil, err
@@ -354,7 +362,7 @@ func (d *Driver) Remove(id string) error {
}
// Get returns the rootfs path for the id. This will mount the dir at its given path.
func (d *Driver) Get(id, mountLabel string) (string, error) {
func (d *Driver) Get(id, mountLabel string, uidMaps, gidMaps []idtools.IDMap) (string, error) {
panicIfUsedByLcow()
logrus.Debugf("WindowsGraphDriver Get() id %s mountLabel %s", id, mountLabel)
var dir string
@@ -612,7 +620,7 @@ func (d *Driver) DiffSize(id string, idMappings *idtools.IDMappings, parent stri
return
}
layerFs, err := d.Get(id, "")
layerFs, err := d.Get(id, "", nil, nil)
if err != nil {
return
}
@@ -946,6 +954,11 @@ func (d *Driver) UpdateLayerIDMap(id string, toContainer, toHost *idtools.IDMapp
return fmt.Errorf("windows doesn't support changing ID mappings")
}
// SupportsShifting tells whether the driver support shifting of the UIDs/GIDs in an userNS
func (d *Driver) SupportsShifting() bool {
return false
}
type storageOptions struct {
size uint64
}

View File

@@ -24,8 +24,9 @@ import (
)
type zfsOptions struct {
fsName string
mountPath string
fsName string
mountPath string
mountOptions string
}
func init() {
@@ -134,6 +135,8 @@ func parseOptions(opt []string) (zfsOptions, error) {
switch key {
case "zfs.fsname":
options.fsName = val
case "zfs.mountopt":
options.mountOptions = val
default:
return options, fmt.Errorf("Unknown option %s", key)
}
@@ -357,14 +360,14 @@ func (d *Driver) Remove(id string) error {
}
// Get returns the mountpoint for the given id after creating the target directories if necessary.
func (d *Driver) Get(id, mountLabel string) (string, error) {
func (d *Driver) Get(id, mountLabel string, uidMaps, gidMaps []idtools.IDMap) (string, error) {
mountpoint := d.mountPath(id)
if count := d.ctr.Increment(mountpoint); count > 1 {
return mountpoint, nil
}
filesystem := d.zfsPath(id)
options := label.FormatMountLabel("", mountLabel)
options := label.FormatMountLabel(d.options.mountOptions, mountLabel)
logrus.Debugf(`[zfs] mount("%s", "%s", "%s")`, filesystem, mountpoint, options)
rootUID, rootGID, err := idtools.GetRootUIDGID(d.uidMaps, d.gidMaps)

View File

@@ -219,6 +219,9 @@ func (r *imageStore) Save() error {
if !r.IsReadWrite() {
return errors.Wrapf(ErrStoreIsReadOnly, "not allowed to modify the image store at %q", r.imagespath())
}
if !r.Locked() {
return errors.New("image store is not locked")
}
rpath := r.imagespath()
if err := os.MkdirAll(filepath.Dir(rpath), 0700); err != nil {
return err
@@ -701,3 +704,7 @@ func (r *imageStore) IsReadWrite() bool {
func (r *imageStore) TouchedSince(when time.Time) bool {
return r.lockfile.TouchedSince(when)
}
func (r *imageStore) Locked() bool {
return r.lockfile.Locked()
}

View File

@@ -4,6 +4,7 @@ import (
"bytes"
"compress/gzip"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"os"
@@ -208,13 +209,14 @@ type LayerStore interface {
// Mount mounts a layer for use. If the specified layer is the parent of other
// layers, it should not be written to. An SELinux label to be applied to the
// mount can be specified to override the one configured for the layer.
Mount(id, mountLabel string) (string, error)
// The mappings used by the container can be specified.
Mount(id, mountLabel string, uidMaps, gidMaps []idtools.IDMap) (string, error)
// Unmount unmounts a layer when it is no longer in use.
Unmount(id string, force bool) (bool, error)
// Mounted returns whether or not the layer is mounted.
Mounted(id string) (bool, error)
// Mounted returns number of times the layer has been mounted.
Mounted(id string) (int, error)
// ParentOwners returns the UIDs and GIDs of parents of the layer's mountpoint
// for which the layer's UID and GID maps don't contain corresponding entries.
@@ -369,6 +371,9 @@ func (r *layerStore) Save() error {
if !r.IsReadWrite() {
return errors.Wrapf(ErrStoreIsReadOnly, "not allowed to modify the layer store at %q", r.layerspath())
}
if !r.Locked() {
return errors.New("layer store is not locked")
}
rpath := r.layerspath()
if err := os.MkdirAll(filepath.Dir(rpath), 0700); err != nil {
return err
@@ -627,15 +632,15 @@ func (r *layerStore) Create(id string, parent *Layer, names []string, mountLabel
return r.CreateWithFlags(id, parent, names, mountLabel, options, moreOptions, writeable, nil)
}
func (r *layerStore) Mounted(id string) (bool, error) {
func (r *layerStore) Mounted(id string) (int, error) {
layer, ok := r.lookup(id)
if !ok {
return false, ErrLayerUnknown
return 0, ErrLayerUnknown
}
return layer.MountCount > 0, nil
return layer.MountCount, nil
}
func (r *layerStore) Mount(id, mountLabel string) (string, error) {
func (r *layerStore) Mount(id, mountLabel string, uidMaps, gidMaps []idtools.IDMap) (string, error) {
if !r.IsReadWrite() {
return "", errors.Wrapf(ErrStoreIsReadOnly, "not allowed to update mount locations for layers at %q", r.mountspath())
}
@@ -650,7 +655,13 @@ func (r *layerStore) Mount(id, mountLabel string) (string, error) {
if mountLabel == "" {
mountLabel = layer.MountLabel
}
mountpoint, err := r.driver.Get(id, mountLabel)
if (uidMaps != nil || gidMaps != nil) && !r.driver.SupportsShifting() {
if !reflect.DeepEqual(uidMaps, layer.UIDMap) || !reflect.DeepEqual(gidMaps, layer.GIDMap) {
return "", fmt.Errorf("cannot mount layer %v: shifting not enabled", layer.ID)
}
}
mountpoint, err := r.driver.Get(id, mountLabel, uidMaps, gidMaps)
if mountpoint != "" && err == nil {
if layer.MountPoint != "" {
delete(r.bymount, layer.MountPoint)
@@ -937,7 +948,7 @@ func (r *layerStore) newFileGetter(id string) (drivers.FileGetCloser, error) {
if getter, ok := r.driver.(drivers.DiffGetterDriver); ok {
return getter.DiffGetter(id)
}
path, err := r.Mount(id, "")
path, err := r.Mount(id, "", nil, nil)
if err != nil {
return nil, err
}
@@ -1173,3 +1184,7 @@ func (r *layerStore) IsReadWrite() bool {
func (r *layerStore) TouchedSince(when time.Time) bool {
return r.lockfile.TouchedSince(when)
}
func (r *layerStore) Locked() bool {
return r.lockfile.Locked()
}

View File

@@ -1,5 +1,5 @@
// Code generated by ffjson <https://github.com/pquerna/ffjson>. DO NOT EDIT.
// source: ./layers.go
// source: layers.go
package storage

View File

@@ -28,6 +28,9 @@ type Locker interface {
// IsReadWrite() checks if the lock file is read-write
IsReadWrite() bool
// Locked() checks if lock is locked
Locked() bool
}
var (

View File

@@ -25,9 +25,9 @@ func getLockFile(path string, ro bool) (Locker, error) {
}
unix.CloseOnExec(fd)
if ro {
return &lockfile{file: path, fd: uintptr(fd), lw: stringid.GenerateRandomID(), locktype: unix.F_RDLCK}, nil
return &lockfile{file: path, fd: uintptr(fd), lw: stringid.GenerateRandomID(), locktype: unix.F_RDLCK, locked: false}, nil
}
return &lockfile{file: path, fd: uintptr(fd), lw: stringid.GenerateRandomID(), locktype: unix.F_WRLCK}, nil
return &lockfile{file: path, fd: uintptr(fd), lw: stringid.GenerateRandomID(), locktype: unix.F_WRLCK, locked: false}, nil
}
type lockfile struct {
@@ -36,6 +36,7 @@ type lockfile struct {
fd uintptr
lw string
locktype int16
locked bool
}
// Lock locks the lock file
@@ -48,6 +49,7 @@ func (l *lockfile) Lock() {
Pid: int32(os.Getpid()),
}
l.mu.Lock()
l.locked = true
for unix.FcntlFlock(l.fd, unix.F_SETLKW, &lk) != nil {
time.Sleep(10 * time.Millisecond)
}
@@ -65,9 +67,15 @@ func (l *lockfile) Unlock() {
for unix.FcntlFlock(l.fd, unix.F_SETLKW, &lk) != nil {
time.Sleep(10 * time.Millisecond)
}
l.locked = false
l.mu.Unlock()
}
// Check if lock is locked
func (l *lockfile) Locked() bool {
return l.locked
}
// Touch updates the lock file with the UID of the user
func (l *lockfile) Touch() error {
l.lw = stringid.GenerateRandomID()

View File

@@ -9,18 +9,29 @@ import (
)
func getLockFile(path string, ro bool) (Locker, error) {
return &lockfile{}, nil
return &lockfile{locked: false}, nil
}
type lockfile struct {
mu sync.Mutex
file string
mu sync.Mutex
file string
locked bool
}
func (l *lockfile) Lock() {
l.mu.Lock()
l.locked = true
}
func (l *lockfile) Unlock() {
l.locked = false
l.mu.Unlock()
}
func (l *lockfile) Locked() bool {
return l.locked
}
func (l *lockfile) Modified() (bool, error) {
return false, nil
}

View File

@@ -140,10 +140,10 @@ func NewIDMappings(username, groupname string) (*IDMappings, error) {
return nil, err
}
if len(subuidRanges) == 0 {
return nil, fmt.Errorf("No subuid ranges found for user %q", username)
return nil, fmt.Errorf("No subuid ranges found for user %q in %s", username, subuidFileName)
}
if len(subgidRanges) == 0 {
return nil, fmt.Errorf("No subgid ranges found for group %q", groupname)
return nil, fmt.Errorf("No subgid ranges found for group %q in %s", groupname, subgidFileName)
}
return &IDMappings{

View File

@@ -111,9 +111,9 @@ func MergeTmpfsOptions(options []string) ([]string, error) {
return newOptions, nil
}
// Parse fstab type mount options into mount() flags
// ParseOptions parses fstab type mount options into mount() flags
// and device specific data
func parseOptions(options string) (int, string) {
func ParseOptions(options string) (int, string) {
var (
flag int
data []string
@@ -138,7 +138,7 @@ func parseOptions(options string) (int, string) {
// ParseTmpfsOptions parse fstab type mount options into flags and data
func ParseTmpfsOptions(options string) (int, string, error) {
flags, data := parseOptions(options)
flags, data := ParseOptions(options)
for _, o := range strings.Split(data, ",") {
opt := strings.SplitN(o, "=", 2)
if !validFlags[opt[0]] {

View File

@@ -39,7 +39,7 @@ func Mounted(mountpoint string) (bool, error) {
// specified like the mount or fstab unix commands: "opt1=val1,opt2=val2". See
// flags.go for supported option flags.
func Mount(device, target, mType, options string) error {
flag, _ := parseOptions(options)
flag, _ := ParseOptions(options)
if flag&REMOUNT != REMOUNT {
if mounted, err := Mounted(target); err != nil || mounted {
return err
@@ -53,7 +53,7 @@ func Mount(device, target, mType, options string) error {
// specified like the mount or fstab unix commands: "opt1=val1,opt2=val2". See
// flags.go for supported option flags.
func ForceMount(device, target, mType, options string) error {
flag, data := parseOptions(options)
flag, data := ParseOptions(options)
return mount(device, target, mType, uintptr(flag), data)
}

View File

@@ -265,8 +265,8 @@ type Store interface {
// name, or a mount path. Returns whether or not the layer is still mounted.
Unmount(id string, force bool) (bool, error)
// Unmount attempts to discover whether the specified id is mounted.
Mounted(id string) (bool, error)
// Mounted returns number of times the layer has been mounted.
Mounted(id string) (int, error)
// Changes returns a summary of the changes which would need to be made
// to one layer to make its contents the same as a second layer. If
@@ -896,13 +896,18 @@ func (s *store) PutLayer(id, parent string, names []string, mountLabel string, w
gidMap = s.gidMap
}
}
layerOptions := &LayerOptions{
IDMappingOptions: IDMappingOptions{
HostUIDMapping: options.HostUIDMapping,
HostGIDMapping: options.HostGIDMapping,
UIDMap: copyIDMap(uidMap),
GIDMap: copyIDMap(gidMap),
},
var layerOptions *LayerOptions
if s.graphDriver.SupportsShifting() {
layerOptions = &LayerOptions{IDMappingOptions: IDMappingOptions{HostUIDMapping: true, HostGIDMapping: true, UIDMap: nil, GIDMap: nil}}
} else {
layerOptions = &LayerOptions{
IDMappingOptions: IDMappingOptions{
HostUIDMapping: options.HostUIDMapping,
HostGIDMapping: options.HostGIDMapping,
UIDMap: copyIDMap(uidMap),
GIDMap: copyIDMap(gidMap),
},
}
}
return rlstore.Put(id, parentLayer, names, mountLabel, nil, layerOptions, writeable, nil, diff)
}
@@ -964,6 +969,10 @@ func (s *store) CreateImage(id string, names []string, layer, metadata string, o
func (s *store) imageTopLayerForMapping(image *Image, ristore ROImageStore, readWrite bool, rlstore LayerStore, lstores []ROLayerStore, options IDMappingOptions) (*Layer, error) {
layerMatchesMappingOptions := func(layer *Layer, options IDMappingOptions) bool {
// If the driver supports shifting and the layer has no mappings, we can use it.
if s.graphDriver.SupportsShifting() && len(layer.UIDMap) == 0 && len(layer.GIDMap) == 0 {
return true
}
// If we want host mapping, and the layer uses mappings, it's not the best match.
if options.HostUIDMapping && len(layer.UIDMap) != 0 {
return false
@@ -1036,16 +1045,22 @@ func (s *store) imageTopLayerForMapping(image *Image, ristore ROImageStore, read
}
rc, err := layerHomeStore.Diff("", layer.ID, &diffOptions)
if err != nil {
return nil, errors.Wrapf(err, "error reading layer %q to create an ID-mapped version of it")
return nil, errors.Wrapf(err, "error reading layer %q to create an ID-mapped version of it", layer.ID)
}
defer rc.Close()
layerOptions := LayerOptions{
IDMappingOptions: IDMappingOptions{
HostUIDMapping: options.HostUIDMapping,
HostGIDMapping: options.HostGIDMapping,
UIDMap: copyIDMap(options.UIDMap),
GIDMap: copyIDMap(options.GIDMap),
},
var layerOptions LayerOptions
if s.graphDriver.SupportsShifting() {
layerOptions = LayerOptions{IDMappingOptions: IDMappingOptions{HostUIDMapping: true, HostGIDMapping: true, UIDMap: nil, GIDMap: nil}}
} else {
layerOptions = LayerOptions{
IDMappingOptions: IDMappingOptions{
HostUIDMapping: options.HostUIDMapping,
HostGIDMapping: options.HostGIDMapping,
UIDMap: copyIDMap(options.UIDMap),
GIDMap: copyIDMap(options.GIDMap),
},
}
}
mappedLayer, _, err := rlstore.Put("", parentLayer, nil, layer.MountLabel, nil, &layerOptions, false, nil, rc)
if err != nil {
@@ -1076,11 +1091,6 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat
if err != nil {
return nil, err
}
rlstore.Lock()
defer rlstore.Unlock()
if modified, err := rlstore.Modified(); modified || err != nil {
rlstore.Load()
}
if id == "" {
id = stringid.GenerateRandomID()
}
@@ -1089,8 +1099,14 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat
imageID := ""
uidMap := options.UIDMap
gidMap := options.GIDMap
idMappingsOptions := options.IDMappingOptions
if image != "" {
var imageHomeStore ROImageStore
lstores, err := s.ROLayerStores()
if err != nil {
return nil, err
}
istore, err := s.ImageStore()
if err != nil {
return nil, err
@@ -1099,6 +1115,11 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat
if err != nil {
return nil, err
}
rlstore.Lock()
defer rlstore.Unlock()
if modified, err := rlstore.Modified(); modified || err != nil {
rlstore.Load()
}
var cimage *Image
for _, store := range append([]ROImageStore{istore}, istores...) {
store.Lock()
@@ -1117,11 +1138,7 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat
}
imageID = cimage.ID
lstores, err := s.ROLayerStores()
if err != nil {
return nil, err
}
ilayer, err := s.imageTopLayerForMapping(cimage, imageHomeStore, imageHomeStore == istore, rlstore, lstores, options.IDMappingOptions)
ilayer, err := s.imageTopLayerForMapping(cimage, imageHomeStore, imageHomeStore == istore, rlstore, lstores, idMappingsOptions)
if err != nil {
return nil, err
}
@@ -1133,6 +1150,11 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat
gidMap = ilayer.GIDMap
}
} else {
rlstore.Lock()
defer rlstore.Unlock()
if modified, err := rlstore.Modified(); modified || err != nil {
rlstore.Load()
}
if !options.HostUIDMapping && len(options.UIDMap) == 0 {
uidMap = s.uidMap
}
@@ -1140,13 +1162,18 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat
gidMap = s.gidMap
}
}
layerOptions := &LayerOptions{
IDMappingOptions: IDMappingOptions{
HostUIDMapping: options.HostUIDMapping,
HostGIDMapping: options.HostGIDMapping,
UIDMap: copyIDMap(uidMap),
GIDMap: copyIDMap(gidMap),
},
var layerOptions *LayerOptions
if s.graphDriver.SupportsShifting() {
layerOptions = &LayerOptions{IDMappingOptions: IDMappingOptions{HostUIDMapping: true, HostGIDMapping: true, UIDMap: nil, GIDMap: nil}}
} else {
layerOptions = &LayerOptions{
IDMappingOptions: IDMappingOptions{
HostUIDMapping: idMappingsOptions.HostUIDMapping,
HostGIDMapping: idMappingsOptions.HostGIDMapping,
UIDMap: copyIDMap(uidMap),
GIDMap: copyIDMap(gidMap),
},
}
}
clayer, err := rlstore.Create(layer, imageTopLayer, nil, "", nil, layerOptions, true)
if err != nil {
@@ -1164,10 +1191,10 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat
}
options = &ContainerOptions{
IDMappingOptions: IDMappingOptions{
HostUIDMapping: len(clayer.UIDMap) == 0,
HostGIDMapping: len(clayer.GIDMap) == 0,
UIDMap: copyIDMap(clayer.UIDMap),
GIDMap: copyIDMap(clayer.GIDMap),
HostUIDMapping: len(options.UIDMap) == 0,
HostGIDMapping: len(options.GIDMap) == 0,
UIDMap: copyIDMap(options.UIDMap),
GIDMap: copyIDMap(options.GIDMap),
},
}
container, err := rcstore.Create(id, names, imageID, layer, metadata, options)
@@ -2230,8 +2257,11 @@ func (s *store) Version() ([][2]string, error) {
}
func (s *store) Mount(id, mountLabel string) (string, error) {
if layerID, err := s.ContainerLayerID(id); err == nil {
id = layerID
container, err := s.Container(id)
var uidMap, gidMap []idtools.IDMap
if err == nil {
uidMap, gidMap = container.UIDMap, container.GIDMap
id = container.LayerID
}
rlstore, err := s.LayerStore()
if err != nil {
@@ -2243,18 +2273,18 @@ func (s *store) Mount(id, mountLabel string) (string, error) {
rlstore.Load()
}
if rlstore.Exists(id) {
return rlstore.Mount(id, mountLabel)
return rlstore.Mount(id, mountLabel, uidMap, gidMap)
}
return "", ErrLayerUnknown
}
func (s *store) Mounted(id string) (bool, error) {
func (s *store) Mounted(id string) (int, error) {
if layerID, err := s.ContainerLayerID(id); err == nil {
id = layerID
}
rlstore, err := s.LayerStore()
if err != nil {
return false, err
return 0, err
}
rlstore.Lock()
defer rlstore.Unlock()
@@ -2339,13 +2369,23 @@ func (s *store) Diff(from, to string, options *DiffOptions) (io.ReadCloser, erro
}
for _, store := range append([]ROLayerStore{lstore}, lstores...) {
store.Lock()
defer store.Unlock()
if modified, err := store.Modified(); modified || err != nil {
store.Load()
}
if store.Exists(to) {
return store.Diff(from, to, options)
rc, err := store.Diff(from, to, options)
if rc != nil && err == nil {
wrapped := ioutils.NewReadCloserWrapper(rc, func() error {
err := rc.Close()
store.Unlock()
return err
})
return wrapped, nil
}
store.Unlock()
return rc, err
}
store.Unlock()
}
return nil, ErrLayerUnknown
}
@@ -3015,6 +3055,9 @@ type OptionsConfig struct {
// Alternative program to use for the mount of the file system
MountProgram string `toml:"mount_program"`
// MountOpt specifies extra mount options used when mounting
MountOpt string `toml:"mountopt"`
}
// TOML-friendly explicit tables used for conversions.
@@ -3086,7 +3129,7 @@ func ReloadConfigurationFile(configFile string, storeOptions *StoreOptions) {
storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.mkfsarg=%s", config.Storage.Options.Thinpool.MkfsArg))
}
if config.Storage.Options.Thinpool.MountOpt != "" {
storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.mountopt=%s", config.Storage.Options.Thinpool.MountOpt))
storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("%s.mountopt=%s", config.Storage.Driver, config.Storage.Options.Thinpool.MountOpt))
}
if config.Storage.Options.Thinpool.UseDeferredDeletion != "" {
storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.use_deferred_deletion=%s", config.Storage.Options.Thinpool.UseDeferredDeletion))
@@ -3112,6 +3155,9 @@ func ReloadConfigurationFile(configFile string, storeOptions *StoreOptions) {
if config.Storage.Options.MountProgram != "" {
storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("%s.mount_program=%s", config.Storage.Driver, config.Storage.Options.MountProgram))
}
if config.Storage.Options.MountOpt != "" {
storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("%s.mountopt=%s", config.Storage.Driver, config.Storage.Options.MountOpt))
}
if config.Storage.Options.OverrideKernelCheck != "" {
storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("%s.override_kernel_check=%s", config.Storage.Driver, config.Storage.Options.OverrideKernelCheck))
}