mirror of
https://github.com/containers/podman.git
synced 2025-06-17 06:57:43 +08:00
Vendor in latest containers/storage and containers/image
Containers/storage brings in support for UserNS ID Mappings This means we can start experimenting with User NS Support in podman Signed-off-by: Daniel J Walsh <dwalsh@redhat.com> Closes: #596 Approved by: TomSweeneyRedHat
This commit is contained in:

committed by
Atomic Bot

parent
fbc9d189b1
commit
c3e2b00333
155
vendor/github.com/containers/storage/layers.go
generated
vendored
155
vendor/github.com/containers/storage/layers.go
generated
vendored
@ -8,12 +8,16 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
drivers "github.com/containers/storage/drivers"
|
||||
"github.com/containers/storage/pkg/archive"
|
||||
"github.com/containers/storage/pkg/idtools"
|
||||
"github.com/containers/storage/pkg/ioutils"
|
||||
"github.com/containers/storage/pkg/stringid"
|
||||
"github.com/containers/storage/pkg/system"
|
||||
"github.com/containers/storage/pkg/truncindex"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
"github.com/pkg/errors"
|
||||
@ -93,6 +97,11 @@ type Layer struct {
|
||||
|
||||
// Flags is arbitrary data about the layer.
|
||||
Flags map[string]interface{} `json:"flags,omitempty"`
|
||||
|
||||
// UIDMap and GIDMap are used for setting up a layer's contents
|
||||
// for use inside of a user namespace where UID mapping is being used.
|
||||
UIDMap []idtools.IDMap `json:"uidmap,omitempty"`
|
||||
GIDMap []idtools.IDMap `json:"gidmap,omitempty"`
|
||||
}
|
||||
|
||||
type layerMountPoint struct {
|
||||
@ -178,13 +187,13 @@ type LayerStore interface {
|
||||
// underlying drivers can accept a "size" option. At this time, most
|
||||
// underlying drivers do not themselves distinguish between writeable
|
||||
// and read-only layers.
|
||||
Create(id, parent string, names []string, mountLabel string, options map[string]string, writeable bool) (*Layer, error)
|
||||
Create(id string, parent *Layer, names []string, mountLabel string, options map[string]string, moreOptions *LayerOptions, writeable bool) (*Layer, error)
|
||||
|
||||
// CreateWithFlags combines the functions of Create and SetFlag.
|
||||
CreateWithFlags(id, parent string, names []string, mountLabel string, options map[string]string, writeable bool, flags map[string]interface{}) (layer *Layer, err error)
|
||||
CreateWithFlags(id string, parent *Layer, names []string, mountLabel string, options map[string]string, moreOptions *LayerOptions, writeable bool, flags map[string]interface{}) (layer *Layer, err error)
|
||||
|
||||
// Put combines the functions of CreateWithFlags and ApplyDiff.
|
||||
Put(id, parent string, names []string, mountLabel string, options map[string]string, writeable bool, flags map[string]interface{}, diff io.Reader) (*Layer, int64, error)
|
||||
Put(id string, parent *Layer, names []string, mountLabel string, options map[string]string, moreOptions *LayerOptions, writeable bool, flags map[string]interface{}, diff io.Reader) (*Layer, int64, error)
|
||||
|
||||
// SetNames replaces the list of names associated with a layer with the
|
||||
// supplied values.
|
||||
@ -204,6 +213,10 @@ type LayerStore interface {
|
||||
// Unmount unmounts a layer when it is no longer in use.
|
||||
Unmount(id string) 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.
|
||||
ParentOwners(id string) (uids, gids []int, err error)
|
||||
|
||||
// ApplyDiff reads a tarstream which was created by a previous call to Diff and
|
||||
// applies its changes to a specified layer.
|
||||
ApplyDiff(to string, diff io.Reader) (int64, error)
|
||||
@ -221,6 +234,8 @@ type layerStore struct {
|
||||
bymount map[string]*Layer
|
||||
bycompressedsum map[digest.Digest][]string
|
||||
byuncompressedsum map[digest.Digest][]string
|
||||
uidMap []idtools.IDMap
|
||||
gidMap []idtools.IDMap
|
||||
}
|
||||
|
||||
func copyLayer(l *Layer) *Layer {
|
||||
@ -239,6 +254,8 @@ func copyLayer(l *Layer) *Layer {
|
||||
UncompressedSize: l.UncompressedSize,
|
||||
CompressionType: l.CompressionType,
|
||||
Flags: copyStringInterfaceMap(l.Flags),
|
||||
UIDMap: copyIDMap(l.UIDMap),
|
||||
GIDMap: copyIDMap(l.GIDMap),
|
||||
}
|
||||
}
|
||||
|
||||
@ -382,7 +399,7 @@ func (r *layerStore) Save() error {
|
||||
return ioutils.AtomicWriteFile(mpath, jmdata, 0600)
|
||||
}
|
||||
|
||||
func newLayerStore(rundir string, layerdir string, driver drivers.Driver) (LayerStore, error) {
|
||||
func newLayerStore(rundir string, layerdir string, driver drivers.Driver, uidMap, gidMap []idtools.IDMap) (LayerStore, error) {
|
||||
if err := os.MkdirAll(rundir, 0700); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -403,6 +420,8 @@ func newLayerStore(rundir string, layerdir string, driver drivers.Driver) (Layer
|
||||
byid: make(map[string]*Layer),
|
||||
bymount: make(map[string]*Layer),
|
||||
byname: make(map[string]*Layer),
|
||||
uidMap: copyIDMap(uidMap),
|
||||
gidMap: copyIDMap(gidMap),
|
||||
}
|
||||
if err := rlstore.Load(); err != nil {
|
||||
return nil, err
|
||||
@ -489,7 +508,7 @@ func (r *layerStore) Status() ([][2]string, error) {
|
||||
return r.driver.Status(), nil
|
||||
}
|
||||
|
||||
func (r *layerStore) Put(id, parent string, names []string, mountLabel string, options map[string]string, writeable bool, flags map[string]interface{}, diff io.Reader) (layer *Layer, size int64, err error) {
|
||||
func (r *layerStore) Put(id string, parentLayer *Layer, names []string, mountLabel string, options map[string]string, moreOptions *LayerOptions, writeable bool, flags map[string]interface{}, diff io.Reader) (layer *Layer, size int64, err error) {
|
||||
if !r.IsReadWrite() {
|
||||
return nil, -1, errors.Wrapf(ErrStoreIsReadOnly, "not allowed to create new layers at %q", r.layerspath())
|
||||
}
|
||||
@ -500,11 +519,6 @@ func (r *layerStore) Put(id, parent string, names []string, mountLabel string, o
|
||||
if err := os.MkdirAll(r.layerdir, 0700); err != nil {
|
||||
return nil, -1, err
|
||||
}
|
||||
if parent != "" {
|
||||
if parentLayer, ok := r.lookup(parent); ok {
|
||||
parent = parentLayer.ID
|
||||
}
|
||||
}
|
||||
if id == "" {
|
||||
id = stringid.GenerateRandomID()
|
||||
_, idInUse := r.byid[id]
|
||||
@ -522,6 +536,15 @@ func (r *layerStore) Put(id, parent string, names []string, mountLabel string, o
|
||||
return nil, -1, ErrDuplicateName
|
||||
}
|
||||
}
|
||||
parent := ""
|
||||
var parentMappings *idtools.IDMappings
|
||||
if parentLayer != nil {
|
||||
parent = parentLayer.ID
|
||||
parentMappings = idtools.NewIDMappingsFromMaps(parentLayer.UIDMap, parentLayer.GIDMap)
|
||||
} else {
|
||||
parentMappings = &idtools.IDMappings{}
|
||||
}
|
||||
idMappings := idtools.NewIDMappingsFromMaps(moreOptions.UIDMap, moreOptions.GIDMap)
|
||||
opts := drivers.CreateOpts{
|
||||
MountLabel: mountLabel,
|
||||
StorageOpt: options,
|
||||
@ -531,6 +554,15 @@ func (r *layerStore) Put(id, parent string, names []string, mountLabel string, o
|
||||
} else {
|
||||
err = r.driver.Create(id, parent, &opts)
|
||||
}
|
||||
if !reflect.DeepEqual(parentMappings.UIDs(), idMappings.UIDs()) || !reflect.DeepEqual(parentMappings.GIDs(), idMappings.GIDs()) {
|
||||
err = r.driver.UpdateLayerIDMap(id, parentMappings, idMappings, mountLabel)
|
||||
if err != nil {
|
||||
// We don't have a record of this layer, but at least
|
||||
// try to clean it up underneath us.
|
||||
r.driver.Remove(id)
|
||||
return nil, -1, err
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
layer = &Layer{
|
||||
ID: id,
|
||||
@ -539,6 +571,8 @@ func (r *layerStore) Put(id, parent string, names []string, mountLabel string, o
|
||||
MountLabel: mountLabel,
|
||||
Created: time.Now().UTC(),
|
||||
Flags: make(map[string]interface{}),
|
||||
UIDMap: copyIDMap(moreOptions.UIDMap),
|
||||
GIDMap: copyIDMap(moreOptions.GIDMap),
|
||||
}
|
||||
r.layers = append(r.layers, layer)
|
||||
r.idindex.Add(id)
|
||||
@ -580,13 +614,13 @@ func (r *layerStore) Put(id, parent string, names []string, mountLabel string, o
|
||||
return copyLayer(layer), size, err
|
||||
}
|
||||
|
||||
func (r *layerStore) CreateWithFlags(id, parent string, names []string, mountLabel string, options map[string]string, writeable bool, flags map[string]interface{}) (layer *Layer, err error) {
|
||||
layer, _, err = r.Put(id, parent, names, mountLabel, options, writeable, flags, nil)
|
||||
func (r *layerStore) CreateWithFlags(id string, parent *Layer, names []string, mountLabel string, options map[string]string, moreOptions *LayerOptions, writeable bool, flags map[string]interface{}) (layer *Layer, err error) {
|
||||
layer, _, err = r.Put(id, parent, names, mountLabel, options, moreOptions, writeable, flags, nil)
|
||||
return layer, err
|
||||
}
|
||||
|
||||
func (r *layerStore) Create(id, parent string, names []string, mountLabel string, options map[string]string, writeable bool) (layer *Layer, err error) {
|
||||
return r.CreateWithFlags(id, parent, names, mountLabel, options, writeable, nil)
|
||||
func (r *layerStore) Create(id string, parent *Layer, names []string, mountLabel string, options map[string]string, moreOptions *LayerOptions, writeable bool) (layer *Layer, err error) {
|
||||
return r.CreateWithFlags(id, parent, names, mountLabel, options, moreOptions, writeable, nil)
|
||||
}
|
||||
|
||||
func (r *layerStore) Mount(id, mountLabel string) (string, error) {
|
||||
@ -645,6 +679,67 @@ func (r *layerStore) Unmount(id string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *layerStore) ParentOwners(id string) (uids, gids []int, err error) {
|
||||
layer, ok := r.lookup(id)
|
||||
if !ok {
|
||||
return nil, nil, ErrLayerUnknown
|
||||
}
|
||||
if len(layer.UIDMap) == 0 && len(layer.GIDMap) == 0 {
|
||||
// We're not using any mappings, so there aren't any unmapped IDs on parent directories.
|
||||
return nil, nil, nil
|
||||
}
|
||||
if layer.MountPoint == "" {
|
||||
// We don't know which directories to examine.
|
||||
return nil, nil, ErrLayerNotMounted
|
||||
}
|
||||
rootuid, rootgid, err := idtools.GetRootUIDGID(layer.UIDMap, layer.GIDMap)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrapf(err, "error reading root ID values for layer %q", layer.ID)
|
||||
}
|
||||
m := idtools.NewIDMappingsFromMaps(layer.UIDMap, layer.GIDMap)
|
||||
fsuids := make(map[int]struct{})
|
||||
fsgids := make(map[int]struct{})
|
||||
for dir := filepath.Dir(layer.MountPoint); dir != "" && dir != string(os.PathSeparator); dir = filepath.Dir(dir) {
|
||||
st, err := system.Stat(dir)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrapf(err, "error reading ownership of directory %q", dir)
|
||||
}
|
||||
lst, err := system.Lstat(dir)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrapf(err, "error reading ownership of directory-in-case-it's-a-symlink %q", dir)
|
||||
}
|
||||
fsuid := int(st.UID())
|
||||
fsgid := int(st.GID())
|
||||
if _, _, err := m.ToContainer(idtools.IDPair{UID: fsuid, GID: rootgid}); err != nil {
|
||||
fsuids[fsuid] = struct{}{}
|
||||
}
|
||||
if _, _, err := m.ToContainer(idtools.IDPair{UID: rootuid, GID: fsgid}); err != nil {
|
||||
fsgids[fsgid] = struct{}{}
|
||||
}
|
||||
fsuid = int(lst.UID())
|
||||
fsgid = int(lst.GID())
|
||||
if _, _, err := m.ToContainer(idtools.IDPair{UID: fsuid, GID: rootgid}); err != nil {
|
||||
fsuids[fsuid] = struct{}{}
|
||||
}
|
||||
if _, _, err := m.ToContainer(idtools.IDPair{UID: rootuid, GID: fsgid}); err != nil {
|
||||
fsgids[fsgid] = struct{}{}
|
||||
}
|
||||
}
|
||||
for uid := range fsuids {
|
||||
uids = append(uids, uid)
|
||||
}
|
||||
for gid := range fsgids {
|
||||
gids = append(gids, gid)
|
||||
}
|
||||
if len(uids) > 1 {
|
||||
sort.Ints(uids)
|
||||
}
|
||||
if len(gids) > 1 {
|
||||
sort.Ints(gids)
|
||||
}
|
||||
return uids, gids, nil
|
||||
}
|
||||
|
||||
func (r *layerStore) removeName(layer *Layer, name string) {
|
||||
layer.Names = stringSliceWithoutValue(layer.Names, name)
|
||||
}
|
||||
@ -771,12 +866,11 @@ func (r *layerStore) Wipe() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *layerStore) findParentAndLayer(from, to string) (fromID string, toID string, toLayer *Layer, err error) {
|
||||
func (r *layerStore) findParentAndLayer(from, to string) (fromID string, toID string, fromLayer, toLayer *Layer, err error) {
|
||||
var ok bool
|
||||
var fromLayer *Layer
|
||||
toLayer, ok = r.lookup(to)
|
||||
if !ok {
|
||||
return "", "", nil, ErrLayerUnknown
|
||||
return "", "", nil, nil, ErrLayerUnknown
|
||||
}
|
||||
to = toLayer.ID
|
||||
if from == "" {
|
||||
@ -793,15 +887,22 @@ func (r *layerStore) findParentAndLayer(from, to string) (fromID string, toID st
|
||||
}
|
||||
}
|
||||
}
|
||||
return from, to, toLayer, nil
|
||||
return from, to, fromLayer, toLayer, nil
|
||||
}
|
||||
|
||||
func (r *layerStore) layerMappings(layer *Layer) *idtools.IDMappings {
|
||||
if layer == nil {
|
||||
return &idtools.IDMappings{}
|
||||
}
|
||||
return idtools.NewIDMappingsFromMaps(layer.UIDMap, layer.GIDMap)
|
||||
}
|
||||
|
||||
func (r *layerStore) Changes(from, to string) ([]archive.Change, error) {
|
||||
from, to, toLayer, err := r.findParentAndLayer(from, to)
|
||||
from, to, fromLayer, toLayer, err := r.findParentAndLayer(from, to)
|
||||
if err != nil {
|
||||
return nil, ErrLayerUnknown
|
||||
}
|
||||
return r.driver.Changes(to, from, toLayer.MountLabel)
|
||||
return r.driver.Changes(to, r.layerMappings(toLayer), from, r.layerMappings(fromLayer), toLayer.MountLabel)
|
||||
}
|
||||
|
||||
type simpleGetCloser struct {
|
||||
@ -836,7 +937,7 @@ func (r *layerStore) newFileGetter(id string) (drivers.FileGetCloser, error) {
|
||||
func (r *layerStore) Diff(from, to string, options *DiffOptions) (io.ReadCloser, error) {
|
||||
var metadata storage.Unpacker
|
||||
|
||||
from, to, toLayer, err := r.findParentAndLayer(from, to)
|
||||
from, to, fromLayer, toLayer, err := r.findParentAndLayer(from, to)
|
||||
if err != nil {
|
||||
return nil, ErrLayerUnknown
|
||||
}
|
||||
@ -874,7 +975,7 @@ func (r *layerStore) Diff(from, to string, options *DiffOptions) (io.ReadCloser,
|
||||
}
|
||||
|
||||
if from != toLayer.Parent {
|
||||
diff, err := r.driver.Diff(to, from, toLayer.MountLabel)
|
||||
diff, err := r.driver.Diff(to, r.layerMappings(toLayer), from, r.layerMappings(fromLayer), toLayer.MountLabel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -886,7 +987,7 @@ func (r *layerStore) Diff(from, to string, options *DiffOptions) (io.ReadCloser,
|
||||
if !os.IsNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
diff, err := r.driver.Diff(to, from, toLayer.MountLabel)
|
||||
diff, err := r.driver.Diff(to, r.layerMappings(toLayer), from, r.layerMappings(fromLayer), toLayer.MountLabel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -925,12 +1026,12 @@ func (r *layerStore) Diff(from, to string, options *DiffOptions) (io.ReadCloser,
|
||||
}
|
||||
|
||||
func (r *layerStore) DiffSize(from, to string) (size int64, err error) {
|
||||
var toLayer *Layer
|
||||
from, to, toLayer, err = r.findParentAndLayer(from, to)
|
||||
var fromLayer, toLayer *Layer
|
||||
from, to, fromLayer, toLayer, err = r.findParentAndLayer(from, to)
|
||||
if err != nil {
|
||||
return -1, ErrLayerUnknown
|
||||
}
|
||||
return r.driver.DiffSize(to, from, toLayer.MountLabel)
|
||||
return r.driver.DiffSize(to, r.layerMappings(toLayer), from, r.layerMappings(fromLayer), toLayer.MountLabel)
|
||||
}
|
||||
|
||||
func (r *layerStore) ApplyDiff(to string, diff io.Reader) (size int64, err error) {
|
||||
@ -970,7 +1071,7 @@ func (r *layerStore) ApplyDiff(to string, diff io.Reader) (size int64, err error
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
size, err = r.driver.ApplyDiff(layer.ID, layer.Parent, layer.MountLabel, payload)
|
||||
size, err = r.driver.ApplyDiff(layer.ID, r.layerMappings(layer), layer.Parent, layer.MountLabel, payload)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
Reference in New Issue
Block a user