github.com/containers/storage v1.12.13

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
Daniel J Walsh
2019-08-01 03:46:14 -04:00
parent 39de184b8b
commit 9d6dce1199
191 changed files with 15069 additions and 59037 deletions

View File

@@ -550,13 +550,13 @@ func (a *Driver) DiffSize(id string, idMappings *idtools.IDMappings, parent stri
// ApplyDiff extracts the changeset from the given diff into the
// layer with the specified id and parent, returning the size of the
// new layer in bytes.
func (a *Driver) ApplyDiff(id string, idMappings *idtools.IDMappings, parent, mountLabel string, diff io.Reader) (size int64, err error) {
func (a *Driver) ApplyDiff(id, parent string, options graphdriver.ApplyDiffOpts) (size int64, err error) {
if !a.isParent(id, parent) {
return a.naiveDiff.ApplyDiff(id, idMappings, parent, mountLabel, diff)
return a.naiveDiff.ApplyDiff(id, parent, options)
}
// AUFS doesn't need the parent id to apply the diff if it is the direct parent.
if err = a.applyDiff(id, idMappings, diff); err != nil {
if err = a.applyDiff(id, options.Mappings, options.Diff); err != nil {
return
}

View File

@@ -41,6 +41,7 @@ type CreateOpts struct {
MountLabel string
StorageOpt map[string]string
*idtools.IDMappings
ignoreChownErrors bool
}
// MountOpts contains optional arguments for LayerStope.Mount() methods.
@@ -53,6 +54,14 @@ type MountOpts struct {
Options []string
}
// ApplyDiffOpts contains optional arguments for ApplyDiff methods.
type ApplyDiffOpts struct {
Diff io.Reader
Mappings *idtools.IDMappings
MountLabel string
IgnoreChownErrors bool
}
// InitFunc initializes the storage driver.
type InitFunc func(homedir string, options Options) (Driver, error)
@@ -115,7 +124,7 @@ type DiffDriver interface {
// layer with the specified id and parent, returning the size of the
// new layer in bytes.
// The io.Reader must be an uncompressed stream.
ApplyDiff(id string, idMappings *idtools.IDMappings, parent string, mountLabel string, diff io.Reader) (size int64, err error)
ApplyDiff(id string, parent string, options ApplyDiffOpts) (size int64, err error)
// DiffSize calculates the changes between the specified id
// and its parent and returns the size in bytes of the changes
// relative to its base filesystem directory.

View File

@@ -33,7 +33,7 @@ type NaiveDiffDriver struct {
// it may or may not support on its own:
// Diff(id string, idMappings *idtools.IDMappings, parent string, parentMappings *idtools.IDMappings, mountLabel string) (io.ReadCloser, error)
// Changes(id string, idMappings *idtools.IDMappings, parent string, parentMappings *idtools.IDMappings, mountLabel string) ([]archive.Change, error)
// ApplyDiff(id string, idMappings *idtools.IDMappings, parent, mountLabel string, diff io.Reader) (size int64, err error)
// ApplyDiff(id, parent string, options ApplyDiffOpts) (size int64, err error)
// DiffSize(id string, idMappings *idtools.IDMappings, parent, parentMappings *idtools.IDMappings, mountLabel string) (size int64, err error)
func NewNaiveDiffDriver(driver ProtoDriver, updater LayerIDMapUpdater) Driver {
return &NaiveDiffDriver{ProtoDriver: driver, LayerIDMapUpdater: updater}
@@ -151,16 +151,16 @@ func (gdw *NaiveDiffDriver) Changes(id string, idMappings *idtools.IDMappings, p
// ApplyDiff extracts the changeset from the given diff into the
// layer with the specified id and parent, returning the size of the
// new layer in bytes.
func (gdw *NaiveDiffDriver) ApplyDiff(id string, applyMappings *idtools.IDMappings, parent, mountLabel string, diff io.Reader) (size int64, err error) {
func (gdw *NaiveDiffDriver) ApplyDiff(id, parent string, options ApplyDiffOpts) (size int64, err error) {
driver := gdw.ProtoDriver
if applyMappings == nil {
applyMappings = &idtools.IDMappings{}
if options.Mappings == nil {
options.Mappings = &idtools.IDMappings{}
}
// Mount the root filesystem so we can apply the diff/layer.
mountOpts := MountOpts{
MountLabel: mountLabel,
MountLabel: options.MountLabel,
}
layerFs, err := driver.Get(id, mountOpts)
if err != nil {
@@ -168,16 +168,17 @@ func (gdw *NaiveDiffDriver) ApplyDiff(id string, applyMappings *idtools.IDMappin
}
defer driver.Put(id)
options := &archive.TarOptions{
InUserNS: rsystem.RunningInUserNS(),
tarOptions := &archive.TarOptions{
InUserNS: rsystem.RunningInUserNS(),
IgnoreChownErrors: options.IgnoreChownErrors,
}
if applyMappings != nil {
options.UIDMaps = applyMappings.UIDs()
options.GIDMaps = applyMappings.GIDs()
if options.Mappings != nil {
tarOptions.UIDMaps = options.Mappings.UIDs()
tarOptions.GIDMaps = options.Mappings.GIDs()
}
start := time.Now().UTC()
logrus.Debug("Start untar layer")
if size, err = ApplyUncompressedLayer(layerFs, diff, options); err != nil {
if size, err = ApplyUncompressedLayer(layerFs, options.Diff, tarOptions); err != nil {
logrus.Errorf("Error while applying layer: %s", err)
return
}

View File

@@ -85,12 +85,13 @@ const (
)
type overlayOptions struct {
imageStores []string
quota quota.Quota
mountProgram string
ostreeRepo string
skipMountHome bool
mountOptions string
imageStores []string
quota quota.Quota
mountProgram string
ostreeRepo string
skipMountHome bool
mountOptions string
ignoreChownErrors bool
}
// Driver contains information about the home directory and the list of active mounts that are created using this driver.
@@ -253,8 +254,7 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error)
convert: make(map[string]bool),
}
d.naiveDiff = graphdriver.NewNaiveDiffDriver(d, d)
d.naiveDiff = graphdriver.NewNaiveDiffDriver(d, graphdriver.NewNaiveLayerIDMapUpdater(d))
if backingFs == "xfs" {
// Try to enable project quota support over xfs.
if d.quotaCtl, err = quota.NewControl(home); err == nil {
@@ -322,6 +322,12 @@ func parseOptions(options []string) (*overlayOptions, error) {
return nil, fmt.Errorf("overlay: ostree_repo specified but support for ostree is missing")
}
o.ostreeRepo = val
case "overlay2.ignore_chown_errors", "overlay.ignore_chown_errors":
logrus.Debugf("overlay: ignore_chown_errors=%s", val)
o.ignoreChownErrors, err = strconv.ParseBool(val)
if err != nil {
return nil, err
}
case "overlay2.skip_mount_home", "overlay.skip_mount_home", ".skip_mount_home":
logrus.Debugf("overlay: skip_mount_home=%s", val)
o.skipMountHome, err = strconv.ParseBool(val)
@@ -910,7 +916,17 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
relLowers = append(relLowers, path.Join(id, "empty"))
}
// 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
}
mergedDir := path.Join(dir, "merged")
// Create the driver merged dir
if err := idtools.MkdirAs(mergedDir, 0700, rootUID, rootGID); err != nil && !os.IsExist(err) {
return "", err
}
if count := d.ctr.Increment(mergedDir); count > 1 {
return mergedDir, nil
}
@@ -980,12 +996,6 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
}
// 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
}
@@ -1001,7 +1011,7 @@ func (d *Driver) Put(id string) error {
if _, err := os.Stat(dir); err != nil {
return err
}
mountpoint := path.Join(d.dir(id), "merged")
mountpoint := path.Join(dir, "merged")
if count := d.ctr.Decrement(mountpoint); count > 0 {
return nil
}
@@ -1011,6 +1021,11 @@ func (d *Driver) Put(id string) error {
if err := unix.Unmount(mountpoint, unix.MNT_DETACH); err != nil {
logrus.Debugf("Failed to unmount %s overlay: %s - %v", id, mountpoint, err)
}
if err := unix.Rmdir(mountpoint); err != nil && !os.IsNotExist(err) {
logrus.Debugf("Failed to remove mountpoint %s overlay: %s - %v", id, mountpoint, err)
}
return nil
}
@@ -1053,11 +1068,16 @@ func (d *Driver) getWhiteoutFormat() archive.WhiteoutFormat {
}
// ApplyDiff applies the new layer into a root
func (d *Driver) ApplyDiff(id string, idMappings *idtools.IDMappings, parent string, mountLabel string, diff io.Reader) (size int64, err error) {
func (d *Driver) ApplyDiff(id, parent string, options graphdriver.ApplyDiffOpts) (size int64, err error) {
if !d.isParent(id, parent) {
return d.naiveDiff.ApplyDiff(id, idMappings, parent, mountLabel, diff)
if d.options.ignoreChownErrors {
options.IgnoreChownErrors = d.options.ignoreChownErrors
}
return d.naiveDiff.ApplyDiff(id, parent, options)
}
idMappings := options.Mappings
if idMappings == nil {
idMappings = &idtools.IDMappings{}
}
@@ -1066,11 +1086,12 @@ func (d *Driver) ApplyDiff(id string, idMappings *idtools.IDMappings, parent str
logrus.Debugf("Applying tar in %s", applyDir)
// Overlay doesn't need the parent id to apply the diff
if err := untar(diff, applyDir, &archive.TarOptions{
UIDMaps: idMappings.UIDs(),
GIDMaps: idMappings.GIDs(),
WhiteoutFormat: d.getWhiteoutFormat(),
InUserNS: rsystem.RunningInUserNS(),
if err := untar(options.Diff, applyDir, &archive.TarOptions{
UIDMaps: idMappings.UIDs(),
GIDMaps: idMappings.GIDs(),
IgnoreChownErrors: d.options.ignoreChownErrors,
WhiteoutFormat: d.getWhiteoutFormat(),
InUserNS: rsystem.RunningInUserNS(),
}); err != nil {
return 0, err
}

View File

@@ -35,7 +35,14 @@ func NaiveCreateFromTemplate(d TemplateDriver, id, template string, templateIDMa
}
return err
}
if _, err = d.ApplyDiff(id, templateIDMappings, parent, opts.MountLabel, diff); err != nil {
applyOptions := ApplyDiffOpts{
Diff: diff,
Mappings: templateIDMappings,
MountLabel: opts.MountLabel,
IgnoreChownErrors: opts.ignoreChownErrors,
}
if _, err = d.ApplyDiff(id, parent, applyOptions); err != nil {
if err2 := d.Remove(id); err2 != nil {
logrus.Errorf("error removing layer %q: %v", id, err2)
}

View File

@@ -2,15 +2,20 @@ package vfs
import (
"fmt"
"io"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/containers/storage/drivers"
"github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/ostree"
"github.com/containers/storage/pkg/parsers"
"github.com/containers/storage/pkg/system"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/sirupsen/logrus"
)
var (
@@ -26,36 +31,42 @@ func init() {
// This sets the home directory for the driver and returns NaiveDiffDriver.
func Init(home string, options graphdriver.Options) (graphdriver.Driver, error) {
d := &Driver{
name: "vfs",
homes: []string{home},
idMappings: idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps),
}
rootIDs := d.idMappings.RootPair()
if err := idtools.MkdirAllAndChown(home, 0700, rootIDs); err != nil {
return nil, err
}
for _, option := range options.DriverOptions {
if strings.HasPrefix(option, "vfs.imagestore=") {
d.homes = append(d.homes, strings.Split(option[15:], ",")...)
continue
key, val, err := parsers.ParseKeyValueOpt(option)
if err != nil {
return nil, err
}
if strings.HasPrefix(option, ".imagestore=") {
d.homes = append(d.homes, strings.Split(option[12:], ",")...)
key = strings.ToLower(key)
switch key {
case "vfs.imagestore", ".imagestore":
d.homes = append(d.homes, strings.Split(val, ",")...)
continue
}
if strings.HasPrefix(option, "vfs.ostree_repo=") {
case "vfs.ostree_repo", ".ostree_repo":
if !ostree.OstreeSupport() {
return nil, fmt.Errorf("vfs: ostree_repo specified but support for ostree is missing")
}
d.ostreeRepo = option[16:]
}
if strings.HasPrefix(option, ".ostree_repo=") {
if !ostree.OstreeSupport() {
return nil, fmt.Errorf("vfs: ostree_repo specified but support for ostree is missing")
}
d.ostreeRepo = option[13:]
}
if strings.HasPrefix(option, "vfs.mountopt=") {
d.ostreeRepo = val
case "vfs.mountopt":
return nil, fmt.Errorf("vfs driver does not support mount options")
case "vfs.ignore_chown_errors":
logrus.Debugf("vfs: ignore_chown_errors=%s", val)
var err error
d.ignoreChownErrors, err = strconv.ParseBool(val)
if err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("vfs driver does not support %s options", key)
}
}
if d.ostreeRepo != "" {
@@ -67,7 +78,10 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error)
return nil, err
}
}
return graphdriver.NewNaiveDiffDriver(d, graphdriver.NewNaiveLayerIDMapUpdater(d)), nil
d.updater = graphdriver.NewNaiveLayerIDMapUpdater(d)
d.naiveDiff = graphdriver.NewNaiveDiffDriver(d, d.updater)
return d, nil
}
// Driver holds information about the driver, home directory of the driver.
@@ -75,9 +89,13 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error)
// In order to support layering, files are copied from the parent layer into the new layer. There is no copy-on-write support.
// Driver must be wrapped in NaiveDiffDriver to be used as a graphdriver.Driver
type Driver struct {
homes []string
idMappings *idtools.IDMappings
ostreeRepo string
name string
homes []string
idMappings *idtools.IDMappings
ostreeRepo string
ignoreChownErrors bool
naiveDiff graphdriver.DiffDriver
updater graphdriver.LayerIDMapUpdater
}
func (d *Driver) String() string {
@@ -107,6 +125,14 @@ func (d *Driver) CreateFromTemplate(id, template string, templateIDMappings *idt
return d.Create(id, template, opts)
}
// ApplyDiff applies the new layer into a root
func (d *Driver) ApplyDiff(id, parent string, options graphdriver.ApplyDiffOpts) (size int64, err error) {
if d.ignoreChownErrors {
options.IgnoreChownErrors = d.ignoreChownErrors
}
return d.naiveDiff.ApplyDiff(id, parent, options)
}
// CreateReadWrite creates a layer that is writable for use as a container
// file system.
func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error {
@@ -118,7 +144,7 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
return d.create(id, parent, opts, true)
}
func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, ro bool) error {
func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, ro bool) (retErr error) {
if opts != nil && len(opts.StorageOpt) != 0 {
return fmt.Errorf("--storage-opt is not supported for vfs")
}
@@ -133,6 +159,13 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, ro bool
if err := idtools.MkdirAllAndChown(filepath.Dir(dir), 0700, rootIDs); err != nil {
return err
}
defer func() {
if retErr != nil {
os.RemoveAll(dir)
}
}()
if parent != "" {
st, err := system.Stat(d.dir(parent))
if err != nil {
@@ -224,3 +257,33 @@ func (d *Driver) AdditionalImageStores() []string {
}
return nil
}
// SupportsShifting tells whether the driver support shifting of the UIDs/GIDs in an userNS
func (d *Driver) SupportsShifting() bool {
return d.updater.SupportsShifting()
}
// UpdateLayerIDMap updates ID mappings in a from matching the ones specified
// by toContainer to those specified by toHost.
func (d *Driver) UpdateLayerIDMap(id string, toContainer, toHost *idtools.IDMappings, mountLabel string) error {
return d.updater.UpdateLayerIDMap(id, toContainer, toHost, mountLabel)
}
// Changes produces a list of changes between the specified layer
// and its parent layer. If parent is "", then all changes will be ADD changes.
func (d *Driver) Changes(id string, idMappings *idtools.IDMappings, parent string, parentMappings *idtools.IDMappings, mountLabel string) ([]archive.Change, error) {
return d.naiveDiff.Changes(id, idMappings, parent, parentMappings, mountLabel)
}
// Diff produces an archive of the changes between the specified
// layer and its parent layer which may be "".
func (d *Driver) Diff(id string, idMappings *idtools.IDMappings, parent string, parentMappings *idtools.IDMappings, mountLabel string) (io.ReadCloser, error) {
return d.naiveDiff.Diff(id, idMappings, parent, parentMappings, mountLabel)
}
// DiffSize calculates the changes between the specified id
// and its parent and returns the size in bytes of the changes
// relative to its base filesystem directory.
func (d *Driver) DiffSize(id string, idMappings *idtools.IDMappings, parent string, parentMappings *idtools.IDMappings, mountLabel string) (size int64, err error) {
return d.naiveDiff.DiffSize(id, idMappings, parent, parentMappings, mountLabel)
}

View File

@@ -581,7 +581,7 @@ func (d *Driver) Changes(id string, idMappings *idtools.IDMappings, parent strin
// layer with the specified id and parent, returning the size of the
// new layer in bytes.
// The layer should not be mounted when calling this function
func (d *Driver) ApplyDiff(id string, idMappings *idtools.IDMappings, parent, mountLabel string, diff io.Reader) (int64, error) {
func (d *Driver) ApplyDiff(id, parent string, options graphdriver.ApplyDiffOpts) (int64, error) {
panicIfUsedByLcow()
var layerChain []string
if parent != "" {
@@ -601,7 +601,7 @@ func (d *Driver) ApplyDiff(id string, idMappings *idtools.IDMappings, parent, mo
layerChain = append(layerChain, parentChain...)
}
size, err := d.importLayer(id, diff, layerChain)
size, err := d.importLayer(id, options.Diff, layerChain)
if err != nil {
return 0, err
}