mirror of
https://github.com/containers/podman.git
synced 2025-07-04 10:10:32 +08:00
Merge pull request #16159 from vrothberg/ebusy-mcflakeface
vendor containers/storage@main
This commit is contained in:
2
go.mod
2
go.mod
@ -17,7 +17,7 @@ require (
|
|||||||
github.com/containers/image/v5 v5.23.0
|
github.com/containers/image/v5 v5.23.0
|
||||||
github.com/containers/ocicrypt v1.1.6
|
github.com/containers/ocicrypt v1.1.6
|
||||||
github.com/containers/psgo v1.7.3
|
github.com/containers/psgo v1.7.3
|
||||||
github.com/containers/storage v1.43.0
|
github.com/containers/storage v1.43.1-0.20221013143630-714f4fc6e80e
|
||||||
github.com/coreos/go-systemd/v22 v22.4.0
|
github.com/coreos/go-systemd/v22 v22.4.0
|
||||||
github.com/coreos/stream-metadata-go v0.0.0-20210225230131-70edb9eb47b3
|
github.com/coreos/stream-metadata-go v0.0.0-20210225230131-70edb9eb47b3
|
||||||
github.com/cyphar/filepath-securejoin v0.2.3
|
github.com/cyphar/filepath-securejoin v0.2.3
|
||||||
|
3
go.sum
3
go.sum
@ -429,8 +429,9 @@ github.com/containers/psgo v1.7.3 h1:KTNurTMXpZjDJHWmlieVO7k7jgKJ4CR/HpPeSaAKtgc
|
|||||||
github.com/containers/psgo v1.7.3/go.mod h1:PfaNzzHmMb8M9/blPgyD4BB3ZEj/0ApZIxN6nNtA+t4=
|
github.com/containers/psgo v1.7.3/go.mod h1:PfaNzzHmMb8M9/blPgyD4BB3ZEj/0ApZIxN6nNtA+t4=
|
||||||
github.com/containers/storage v1.37.0/go.mod h1:kqeJeS0b7DO2ZT1nVWs0XufrmPFbgV3c+Q/45RlH6r4=
|
github.com/containers/storage v1.37.0/go.mod h1:kqeJeS0b7DO2ZT1nVWs0XufrmPFbgV3c+Q/45RlH6r4=
|
||||||
github.com/containers/storage v1.42.0/go.mod h1:JiUJwOgOo1dr2DdOUc1MRe2GCAXABYoYmOdPF8yvH78=
|
github.com/containers/storage v1.42.0/go.mod h1:JiUJwOgOo1dr2DdOUc1MRe2GCAXABYoYmOdPF8yvH78=
|
||||||
github.com/containers/storage v1.43.0 h1:P+zulGXA3mqe2GnYmZU0xu87Wy1M0PVHM2ucrgmvTdU=
|
|
||||||
github.com/containers/storage v1.43.0/go.mod h1:uZ147thiIFGdVTjMmIw19knttQnUCl3y9zjreHrg11s=
|
github.com/containers/storage v1.43.0/go.mod h1:uZ147thiIFGdVTjMmIw19knttQnUCl3y9zjreHrg11s=
|
||||||
|
github.com/containers/storage v1.43.1-0.20221013143630-714f4fc6e80e h1:uBtZPqpZetk6RYw115Rr+35UTvM93qltpdDLw7zFgvM=
|
||||||
|
github.com/containers/storage v1.43.1-0.20221013143630-714f4fc6e80e/go.mod h1:K2qol6lCT/LRqZ3TMNRBU22tCTC6/Mb4G23K5SHhrYw=
|
||||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
|
2
vendor/github.com/containers/storage/VERSION
generated
vendored
2
vendor/github.com/containers/storage/VERSION
generated
vendored
@ -1 +1 @@
|
|||||||
1.43.0
|
1.43.1-dev
|
||||||
|
38
vendor/github.com/containers/storage/containers.go
generated
vendored
38
vendor/github.com/containers/storage/containers.go
generated
vendored
@ -66,12 +66,12 @@ type Container struct {
|
|||||||
Flags map[string]interface{} `json:"flags,omitempty"`
|
Flags map[string]interface{} `json:"flags,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerStore provides bookkeeping for information about Containers.
|
// rwContainerStore provides bookkeeping for information about Containers.
|
||||||
type ContainerStore interface {
|
type rwContainerStore interface {
|
||||||
FileBasedStore
|
fileBasedStore
|
||||||
MetadataStore
|
metadataStore
|
||||||
ContainerBigDataStore
|
containerBigDataStore
|
||||||
FlaggableStore
|
flaggableStore
|
||||||
|
|
||||||
// Create creates a container that has a specified ID (or generates a
|
// Create creates a container that has a specified ID (or generates a
|
||||||
// random one if an empty value is supplied) and optional names,
|
// random one if an empty value is supplied) and optional names,
|
||||||
@ -221,7 +221,7 @@ func (r *containerStore) Load() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
r.containers = containers
|
r.containers = containers
|
||||||
r.idindex = truncindex.NewTruncIndex(idlist)
|
r.idindex = truncindex.NewTruncIndex(idlist) // Invalid values in idlist are ignored: they are not a reason to refuse processing the whole store.
|
||||||
r.byid = ids
|
r.byid = ids
|
||||||
r.bylayer = layers
|
r.bylayer = layers
|
||||||
r.byname = names
|
r.byname = names
|
||||||
@ -243,11 +243,13 @@ func (r *containerStore) Save() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer r.Touch()
|
if err := ioutils.AtomicWriteFile(rpath, jdata, 0600); err != nil {
|
||||||
return ioutils.AtomicWriteFile(rpath, jdata, 0600)
|
return err
|
||||||
|
}
|
||||||
|
return r.Touch()
|
||||||
}
|
}
|
||||||
|
|
||||||
func newContainerStore(dir string) (ContainerStore, error) {
|
func newContainerStore(dir string) (rwContainerStore, error) {
|
||||||
if err := os.MkdirAll(dir, 0700); err != nil {
|
if err := os.MkdirAll(dir, 0700); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -255,8 +257,6 @@ func newContainerStore(dir string) (ContainerStore, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
lockfile.Lock()
|
|
||||||
defer lockfile.Unlock()
|
|
||||||
cstore := containerStore{
|
cstore := containerStore{
|
||||||
lockfile: lockfile,
|
lockfile: lockfile,
|
||||||
dir: dir,
|
dir: dir,
|
||||||
@ -265,6 +265,8 @@ func newContainerStore(dir string) (ContainerStore, error) {
|
|||||||
bylayer: make(map[string]*Container),
|
bylayer: make(map[string]*Container),
|
||||||
byname: make(map[string]*Container),
|
byname: make(map[string]*Container),
|
||||||
}
|
}
|
||||||
|
cstore.Lock()
|
||||||
|
defer cstore.Unlock()
|
||||||
if err := cstore.Load(); err != nil {
|
if err := cstore.Load(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -354,7 +356,9 @@ func (r *containerStore) Create(id string, names []string, image, layer, metadat
|
|||||||
}
|
}
|
||||||
r.containers = append(r.containers, container)
|
r.containers = append(r.containers, container)
|
||||||
r.byid[id] = container
|
r.byid[id] = container
|
||||||
r.idindex.Add(id)
|
// This can only fail on duplicate IDs, which shouldn’t happen — and in that case the index is already in the desired state anyway.
|
||||||
|
// Implementing recovery from an unlikely and unimportant failure here would be too risky.
|
||||||
|
_ = r.idindex.Add(id)
|
||||||
r.bylayer[layer] = container
|
r.bylayer[layer] = container
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
r.byname[name] = container
|
r.byname[name] = container
|
||||||
@ -434,7 +438,9 @@ func (r *containerStore) Delete(id string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete(r.byid, id)
|
delete(r.byid, id)
|
||||||
r.idindex.Delete(id)
|
// This can only fail if the ID is already missing, which shouldn’t happen — and in that case the index is already in the desired state anyway.
|
||||||
|
// The store’s Delete method is used on various paths to recover from failures, so this should be robust against partially missing data.
|
||||||
|
_ = r.idindex.Delete(id)
|
||||||
delete(r.bylayer, container.LayerID)
|
delete(r.bylayer, container.LayerID)
|
||||||
for _, name := range container.Names {
|
for _, name := range container.Names {
|
||||||
delete(r.byname, name)
|
delete(r.byname, name)
|
||||||
@ -617,10 +623,6 @@ func (r *containerStore) Lock() {
|
|||||||
r.lockfile.Lock()
|
r.lockfile.Lock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *containerStore) RecursiveLock() {
|
|
||||||
r.lockfile.RecursiveLock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *containerStore) RLock() {
|
func (r *containerStore) RLock() {
|
||||||
r.lockfile.RLock()
|
r.lockfile.RLock()
|
||||||
}
|
}
|
||||||
|
216
vendor/github.com/containers/storage/deprecated.go
generated
vendored
Normal file
216
vendor/github.com/containers/storage/deprecated.go
generated
vendored
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
package storage
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
drivers "github.com/containers/storage/drivers"
|
||||||
|
"github.com/containers/storage/pkg/archive"
|
||||||
|
digest "github.com/opencontainers/go-digest"
|
||||||
|
)
|
||||||
|
|
||||||
|
// The type definitions in this file exist ONLY to maintain formal API compatibility.
|
||||||
|
// DO NOT ADD ANY NEW METHODS TO THESE INTERFACES.
|
||||||
|
|
||||||
|
// ROFileBasedStore is a deprecated interface with no documented way to use it from callers outside of c/storage.
|
||||||
|
//
|
||||||
|
// Deprecated: There is no way to use this from any external user of c/storage to invoke c/storage functionality.
|
||||||
|
type ROFileBasedStore interface {
|
||||||
|
Locker
|
||||||
|
Load() error
|
||||||
|
ReloadIfChanged() error
|
||||||
|
}
|
||||||
|
|
||||||
|
// RWFileBasedStore is a deprecated interface with no documented way to use it from callers outside of c/storage.
|
||||||
|
//
|
||||||
|
// Deprecated: There is no way to use this from any external user of c/storage to invoke c/storage functionality.
|
||||||
|
type RWFileBasedStore interface {
|
||||||
|
Save() error
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileBasedStore is a deprecated interface with no documented way to use it from callers outside of c/storage.
|
||||||
|
//
|
||||||
|
// Deprecated: There is no way to use this from any external user of c/storage to invoke c/storage functionality.
|
||||||
|
type FileBasedStore interface {
|
||||||
|
ROFileBasedStore
|
||||||
|
RWFileBasedStore
|
||||||
|
}
|
||||||
|
|
||||||
|
// ROMetadataStore is a deprecated interface with no documented way to use it from callers outside of c/storage.
|
||||||
|
//
|
||||||
|
// Deprecated: There is no way to use this from any external user of c/storage to invoke c/storage functionality.
|
||||||
|
type ROMetadataStore interface {
|
||||||
|
Metadata(id string) (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RWMetadataStore is a deprecated interface with no documented way to use it from callers outside of c/storage.
|
||||||
|
//
|
||||||
|
// Deprecated: There is no way to use this from any external user of c/storage to invoke c/storage functionality.
|
||||||
|
type RWMetadataStore interface {
|
||||||
|
SetMetadata(id, metadata string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// MetadataStore is a deprecated interface with no documented way to use it from callers outside of c/storage.
|
||||||
|
//
|
||||||
|
// Deprecated: There is no way to use this from any external user of c/storage to invoke c/storage functionality.
|
||||||
|
type MetadataStore interface {
|
||||||
|
ROMetadataStore
|
||||||
|
RWMetadataStore
|
||||||
|
}
|
||||||
|
|
||||||
|
// ROBigDataStore is a deprecated interface with no documented way to use it from callers outside of c/storage.
|
||||||
|
//
|
||||||
|
// Deprecated: There is no way to use this from any external user of c/storage to invoke c/storage functionality.
|
||||||
|
type ROBigDataStore interface {
|
||||||
|
BigData(id, key string) ([]byte, error)
|
||||||
|
BigDataSize(id, key string) (int64, error)
|
||||||
|
BigDataDigest(id, key string) (digest.Digest, error)
|
||||||
|
BigDataNames(id string) ([]string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RWImageBigDataStore is a deprecated interface with no documented way to use it from callers outside of c/storage.
|
||||||
|
//
|
||||||
|
// Deprecated: There is no way to use this from any external user of c/storage to invoke c/storage functionality.
|
||||||
|
type RWImageBigDataStore interface {
|
||||||
|
SetBigData(id, key string, data []byte, digestManifest func([]byte) (digest.Digest, error)) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContainerBigDataStore is a deprecated interface with no documented way to use it from callers outside of c/storage.
|
||||||
|
//
|
||||||
|
// Deprecated: There is no way to use this from any external user of c/storage to invoke c/storage functionality.
|
||||||
|
type ContainerBigDataStore interface {
|
||||||
|
ROBigDataStore
|
||||||
|
SetBigData(id, key string, data []byte) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// ROLayerBigDataStore is a deprecated interface with no documented way to use it from callers outside of c/storage.
|
||||||
|
//
|
||||||
|
// Deprecated: There is no way to use this from any external user of c/storage to invoke c/storage functionality.
|
||||||
|
type ROLayerBigDataStore interface {
|
||||||
|
BigData(id, key string) (io.ReadCloser, error)
|
||||||
|
BigDataNames(id string) ([]string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RWLayerBigDataStore is a deprecated interface with no documented way to use it from callers outside of c/storage.
|
||||||
|
//
|
||||||
|
// Deprecated: There is no way to use this from any external user of c/storage to invoke c/storage functionality.
|
||||||
|
type RWLayerBigDataStore interface {
|
||||||
|
SetBigData(id, key string, data io.Reader) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerBigDataStore is a deprecated interface with no documented way to use it from callers outside of c/storage.
|
||||||
|
//
|
||||||
|
// Deprecated: There is no way to use this from any external user of c/storage to invoke c/storage functionality.
|
||||||
|
type LayerBigDataStore interface {
|
||||||
|
ROLayerBigDataStore
|
||||||
|
RWLayerBigDataStore
|
||||||
|
}
|
||||||
|
|
||||||
|
// FlaggableStore is a deprecated interface with no documented way to use it from callers outside of c/storage.
|
||||||
|
//
|
||||||
|
// Deprecated: There is no way to use this from any external user of c/storage to invoke c/storage functionality.
|
||||||
|
type FlaggableStore interface {
|
||||||
|
ClearFlag(id string, flag string) error
|
||||||
|
SetFlag(id string, flag string, value interface{}) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContainerStore is a deprecated interface with no documented way to use it from callers outside of c/storage.
|
||||||
|
//
|
||||||
|
// Deprecated: There is no way to use this from any external user of c/storage to invoke c/storage functionality.
|
||||||
|
type ContainerStore interface {
|
||||||
|
FileBasedStore
|
||||||
|
MetadataStore
|
||||||
|
ContainerBigDataStore
|
||||||
|
FlaggableStore
|
||||||
|
Create(id string, names []string, image, layer, metadata string, options *ContainerOptions) (*Container, error)
|
||||||
|
SetNames(id string, names []string) error
|
||||||
|
AddNames(id string, names []string) error
|
||||||
|
RemoveNames(id string, names []string) error
|
||||||
|
Get(id string) (*Container, error)
|
||||||
|
Exists(id string) bool
|
||||||
|
Delete(id string) error
|
||||||
|
Wipe() error
|
||||||
|
Lookup(name string) (string, error)
|
||||||
|
Containers() ([]Container, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ROImageStore is a deprecated interface with no documented way to use it from callers outside of c/storage.
|
||||||
|
//
|
||||||
|
// Deprecated: There is no way to use this from any external user of c/storage to invoke c/storage functionality.
|
||||||
|
type ROImageStore interface {
|
||||||
|
ROFileBasedStore
|
||||||
|
ROMetadataStore
|
||||||
|
ROBigDataStore
|
||||||
|
Exists(id string) bool
|
||||||
|
Get(id string) (*Image, error)
|
||||||
|
Lookup(name string) (string, error)
|
||||||
|
Images() ([]Image, error)
|
||||||
|
ByDigest(d digest.Digest) ([]*Image, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageStore is a deprecated interface with no documented way to use it from callers outside of c/storage.
|
||||||
|
//
|
||||||
|
// Deprecated: There is no way to use this from any external user of c/storage to invoke c/storage functionality.
|
||||||
|
type ImageStore interface {
|
||||||
|
ROImageStore
|
||||||
|
RWFileBasedStore
|
||||||
|
RWMetadataStore
|
||||||
|
RWImageBigDataStore
|
||||||
|
FlaggableStore
|
||||||
|
Create(id string, names []string, layer, metadata string, created time.Time, searchableDigest digest.Digest) (*Image, error)
|
||||||
|
SetNames(id string, names []string) error
|
||||||
|
AddNames(id string, names []string) error
|
||||||
|
RemoveNames(id string, names []string) error
|
||||||
|
Delete(id string) error
|
||||||
|
Wipe() error
|
||||||
|
}
|
||||||
|
|
||||||
|
// ROLayerStore is a deprecated interface with no documented way to use it from callers outside of c/storage.
|
||||||
|
//
|
||||||
|
// Deprecated: There is no way to use this from any external user of c/storage to invoke c/storage functionality.
|
||||||
|
type ROLayerStore interface {
|
||||||
|
ROFileBasedStore
|
||||||
|
ROMetadataStore
|
||||||
|
ROLayerBigDataStore
|
||||||
|
Exists(id string) bool
|
||||||
|
Get(id string) (*Layer, error)
|
||||||
|
Status() ([][2]string, error)
|
||||||
|
Changes(from, to string) ([]archive.Change, error)
|
||||||
|
Diff(from, to string, options *DiffOptions) (io.ReadCloser, error)
|
||||||
|
DiffSize(from, to string) (int64, error)
|
||||||
|
Size(name string) (int64, error)
|
||||||
|
Lookup(name string) (string, error)
|
||||||
|
LayersByCompressedDigest(d digest.Digest) ([]Layer, error)
|
||||||
|
LayersByUncompressedDigest(d digest.Digest) ([]Layer, error)
|
||||||
|
Layers() ([]Layer, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerStore is a deprecated interface with no documented way to use it from callers outside of c/storage.
|
||||||
|
//
|
||||||
|
// Deprecated: There is no way to use this from any external user of c/storage to invoke c/storage functionality.
|
||||||
|
type LayerStore interface {
|
||||||
|
ROLayerStore
|
||||||
|
RWFileBasedStore
|
||||||
|
RWMetadataStore
|
||||||
|
FlaggableStore
|
||||||
|
RWLayerBigDataStore
|
||||||
|
Create(id string, parent *Layer, names []string, mountLabel string, options map[string]string, moreOptions *LayerOptions, writeable bool) (*Layer, 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(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(id string, names []string) error
|
||||||
|
AddNames(id string, names []string) error
|
||||||
|
RemoveNames(id string, names []string) error
|
||||||
|
Delete(id string) error
|
||||||
|
Wipe() error
|
||||||
|
Mount(id string, options drivers.MountOpts) (string, error)
|
||||||
|
Unmount(id string, force bool) (bool, error)
|
||||||
|
Mounted(id string) (int, error)
|
||||||
|
ParentOwners(id string) (uids, gids []int, err error)
|
||||||
|
ApplyDiff(to string, diff io.Reader) (int64, error)
|
||||||
|
ApplyDiffWithDiffer(to string, options *drivers.ApplyDiffOpts, differ drivers.Differ) (*drivers.DriverWithDifferOutput, error)
|
||||||
|
CleanupStagingDirectory(stagingDirectory string) error
|
||||||
|
ApplyDiffFromStagingDirectory(id, stagingDirectory string, diffOutput *drivers.DriverWithDifferOutput, options *drivers.ApplyDiffOpts) error
|
||||||
|
DifferTarget(id string) (string, error)
|
||||||
|
LoadLocked() error
|
||||||
|
PutAdditionalLayer(id string, parentLayer *Layer, names []string, aLayer drivers.AdditionalLayer) (layer *Layer, err error)
|
||||||
|
}
|
2
vendor/github.com/containers/storage/drivers/aufs/aufs.go
generated
vendored
2
vendor/github.com/containers/storage/drivers/aufs/aufs.go
generated
vendored
@ -67,7 +67,7 @@ var (
|
|||||||
const defaultPerms = os.FileMode(0555)
|
const defaultPerms = os.FileMode(0555)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
graphdriver.Register("aufs", Init)
|
graphdriver.MustRegister("aufs", Init)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Driver contains information about the filesystem mounted.
|
// Driver contains information about the filesystem mounted.
|
||||||
|
2
vendor/github.com/containers/storage/drivers/btrfs/btrfs.go
generated
vendored
2
vendor/github.com/containers/storage/drivers/btrfs/btrfs.go
generated
vendored
@ -42,7 +42,7 @@ import (
|
|||||||
const defaultPerms = os.FileMode(0555)
|
const defaultPerms = os.FileMode(0555)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
graphdriver.Register("btrfs", Init)
|
graphdriver.MustRegister("btrfs", Init)
|
||||||
}
|
}
|
||||||
|
|
||||||
type btrfsOptions struct {
|
type btrfsOptions struct {
|
||||||
|
6
vendor/github.com/containers/storage/drivers/chown.go
generated
vendored
6
vendor/github.com/containers/storage/drivers/chown.go
generated
vendored
@ -115,7 +115,7 @@ func NewNaiveLayerIDMapUpdater(driver ProtoDriver) LayerIDMapUpdater {
|
|||||||
// on-disk owner UIDs and GIDs which are "host" values in the first map with
|
// on-disk owner UIDs and GIDs which are "host" values in the first map with
|
||||||
// UIDs and GIDs for "host" values from the second map which correspond to the
|
// UIDs and GIDs for "host" values from the second map which correspond to the
|
||||||
// same "container" IDs.
|
// same "container" IDs.
|
||||||
func (n *naiveLayerIDMapUpdater) UpdateLayerIDMap(id string, toContainer, toHost *idtools.IDMappings, mountLabel string) error {
|
func (n *naiveLayerIDMapUpdater) UpdateLayerIDMap(id string, toContainer, toHost *idtools.IDMappings, mountLabel string) (retErr error) {
|
||||||
driver := n.ProtoDriver
|
driver := n.ProtoDriver
|
||||||
options := MountOpts{
|
options := MountOpts{
|
||||||
MountLabel: mountLabel,
|
MountLabel: mountLabel,
|
||||||
@ -124,9 +124,7 @@ func (n *naiveLayerIDMapUpdater) UpdateLayerIDMap(id string, toContainer, toHost
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer func() {
|
defer driverPut(driver, id, &retErr)
|
||||||
driver.Put(id)
|
|
||||||
}()
|
|
||||||
|
|
||||||
return ChownPathByMaps(layerFs, toContainer, toHost)
|
return ChownPathByMaps(layerFs, toContainer, toHost)
|
||||||
}
|
}
|
||||||
|
6
vendor/github.com/containers/storage/drivers/chown_darwin.go
generated
vendored
6
vendor/github.com/containers/storage/drivers/chown_darwin.go
generated
vendored
@ -83,7 +83,7 @@ func (c *platformChowner) LChown(path string, info os.FileInfo, toHost, toContai
|
|||||||
uid, gid = mappedPair.UID, mappedPair.GID
|
uid, gid = mappedPair.UID, mappedPair.GID
|
||||||
}
|
}
|
||||||
if uid != int(st.Uid) || gid != int(st.Gid) {
|
if uid != int(st.Uid) || gid != int(st.Gid) {
|
||||||
cap, err := system.Lgetxattr(path, "security.capability")
|
capability, err := system.Lgetxattr(path, "security.capability")
|
||||||
if err != nil && !errors.Is(err, system.EOPNOTSUPP) && err != system.ErrNotSupportedPlatform {
|
if err != nil && !errors.Is(err, system.EOPNOTSUPP) && err != system.ErrNotSupportedPlatform {
|
||||||
return fmt.Errorf("%s: %w", os.Args[0], err)
|
return fmt.Errorf("%s: %w", os.Args[0], err)
|
||||||
}
|
}
|
||||||
@ -98,8 +98,8 @@ func (c *platformChowner) LChown(path string, info os.FileInfo, toHost, toContai
|
|||||||
return fmt.Errorf("%s: %w", os.Args[0], err)
|
return fmt.Errorf("%s: %w", os.Args[0], err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if cap != nil {
|
if capability != nil {
|
||||||
if err := system.Lsetxattr(path, "security.capability", cap, 0); err != nil {
|
if err := system.Lsetxattr(path, "security.capability", capability, 0); err != nil {
|
||||||
return fmt.Errorf("%s: %w", os.Args[0], err)
|
return fmt.Errorf("%s: %w", os.Args[0], err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
7
vendor/github.com/containers/storage/drivers/copy/copy_unsupported.go
generated
vendored
7
vendor/github.com/containers/storage/drivers/copy/copy_unsupported.go
generated
vendored
@ -1,6 +1,7 @@
|
|||||||
|
//go:build !linux || !cgo
|
||||||
// +build !linux !cgo
|
// +build !linux !cgo
|
||||||
|
|
||||||
package copy
|
package copy //nolint: predeclared
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
@ -24,7 +25,7 @@ func DirCopy(srcDir, dstDir string, _ Mode, _ bool) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CopyRegularToFile copies the content of a file to another
|
// CopyRegularToFile copies the content of a file to another
|
||||||
func CopyRegularToFile(srcPath string, dstFile *os.File, fileinfo os.FileInfo, copyWithFileRange, copyWithFileClone *bool) error {
|
func CopyRegularToFile(srcPath string, dstFile *os.File, fileinfo os.FileInfo, copyWithFileRange, copyWithFileClone *bool) error { //nolint: revive // "func name will be used as copy.CopyRegularToFile by other packages, and that stutters"
|
||||||
f, err := os.Open(srcPath)
|
f, err := os.Open(srcPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -35,6 +36,6 @@ func CopyRegularToFile(srcPath string, dstFile *os.File, fileinfo os.FileInfo, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CopyRegular copies the content of a file to another
|
// CopyRegular copies the content of a file to another
|
||||||
func CopyRegular(srcPath, dstPath string, fileinfo os.FileInfo, copyWithFileRange, copyWithFileClone *bool) error {
|
func CopyRegular(srcPath, dstPath string, fileinfo os.FileInfo, copyWithFileRange, copyWithFileClone *bool) error { //nolint:revive // "func name will be used as copy.CopyRegular by other packages, and that stutters"
|
||||||
return chrootarchive.NewArchiver(nil).CopyWithTar(srcPath, dstPath)
|
return chrootarchive.NewArchiver(nil).CopyWithTar(srcPath, dstPath)
|
||||||
}
|
}
|
||||||
|
2
vendor/github.com/containers/storage/drivers/devmapper/driver.go
generated
vendored
2
vendor/github.com/containers/storage/drivers/devmapper/driver.go
generated
vendored
@ -23,7 +23,7 @@ import (
|
|||||||
const defaultPerms = os.FileMode(0555)
|
const defaultPerms = os.FileMode(0555)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
graphdriver.Register("devicemapper", Init)
|
graphdriver.MustRegister("devicemapper", Init)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Driver contains the device set mounted and the home directory
|
// Driver contains the device set mounted and the home directory
|
||||||
|
32
vendor/github.com/containers/storage/drivers/driver.go
generated
vendored
32
vendor/github.com/containers/storage/drivers/driver.go
generated
vendored
@ -39,7 +39,7 @@ var (
|
|||||||
ErrLayerUnknown = errors.New("unknown layer")
|
ErrLayerUnknown = errors.New("unknown layer")
|
||||||
)
|
)
|
||||||
|
|
||||||
//CreateOpts contains optional arguments for Create() and CreateReadWrite()
|
// CreateOpts contains optional arguments for Create() and CreateReadWrite()
|
||||||
// methods.
|
// methods.
|
||||||
type CreateOpts struct {
|
type CreateOpts struct {
|
||||||
MountLabel string
|
MountLabel string
|
||||||
@ -53,8 +53,8 @@ type MountOpts struct {
|
|||||||
// Mount label is the MAC Labels to assign to mount point (SELINUX)
|
// Mount label is the MAC Labels to assign to mount point (SELINUX)
|
||||||
MountLabel string
|
MountLabel string
|
||||||
// UidMaps & GidMaps are the User Namespace mappings to be assigned to content in the mount point
|
// UidMaps & GidMaps are the User Namespace mappings to be assigned to content in the mount point
|
||||||
UidMaps []idtools.IDMap // nolint: golint
|
UidMaps []idtools.IDMap //nolint: golint,revive
|
||||||
GidMaps []idtools.IDMap // nolint: golint
|
GidMaps []idtools.IDMap //nolint: golint
|
||||||
Options []string
|
Options []string
|
||||||
|
|
||||||
// Volatile specifies whether the container storage can be optimized
|
// Volatile specifies whether the container storage can be optimized
|
||||||
@ -279,6 +279,14 @@ func init() {
|
|||||||
drivers = make(map[string]InitFunc)
|
drivers = make(map[string]InitFunc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MustRegister registers an InitFunc for the driver, or panics.
|
||||||
|
// It is suitable for package’s init() sections.
|
||||||
|
func MustRegister(name string, initFunc InitFunc) {
|
||||||
|
if err := Register(name, initFunc); err != nil {
|
||||||
|
panic(fmt.Sprintf("failed to register containers/storage graph driver %q: %v", name, err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Register registers an InitFunc for the driver.
|
// Register registers an InitFunc for the driver.
|
||||||
func Register(name string, initFunc InitFunc) error {
|
func Register(name string, initFunc InitFunc) error {
|
||||||
if _, exists := drivers[name]; exists {
|
if _, exists := drivers[name]; exists {
|
||||||
@ -405,3 +413,21 @@ func scanPriorDrivers(root string) map[string]bool {
|
|||||||
}
|
}
|
||||||
return driversMap
|
return driversMap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// driverPut is driver.Put, but errors are handled either by updating mainErr or just logging.
|
||||||
|
// Typical usage:
|
||||||
|
//
|
||||||
|
// func …(…) (err error) {
|
||||||
|
// …
|
||||||
|
// defer driverPut(driver, id, &err)
|
||||||
|
// }
|
||||||
|
func driverPut(driver ProtoDriver, id string, mainErr *error) {
|
||||||
|
if err := driver.Put(id); err != nil {
|
||||||
|
err = fmt.Errorf("unmounting layer %s: %w", id, err)
|
||||||
|
if *mainErr == nil {
|
||||||
|
*mainErr = err
|
||||||
|
} else {
|
||||||
|
logrus.Errorf(err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
18
vendor/github.com/containers/storage/drivers/fsdiff.go
generated
vendored
18
vendor/github.com/containers/storage/drivers/fsdiff.go
generated
vendored
@ -65,7 +65,7 @@ func (gdw *NaiveDiffDriver) Diff(id string, idMappings *idtools.IDMappings, pare
|
|||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
driver.Put(id)
|
driverPut(driver, id, &err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ func (gdw *NaiveDiffDriver) Diff(id string, idMappings *idtools.IDMappings, pare
|
|||||||
}
|
}
|
||||||
return ioutils.NewReadCloserWrapper(archive, func() error {
|
return ioutils.NewReadCloserWrapper(archive, func() error {
|
||||||
err := archive.Close()
|
err := archive.Close()
|
||||||
driver.Put(id)
|
driverPut(driver, id, &err)
|
||||||
return err
|
return err
|
||||||
}), nil
|
}), nil
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ func (gdw *NaiveDiffDriver) Diff(id string, idMappings *idtools.IDMappings, pare
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer driver.Put(parent)
|
defer driverPut(driver, parent, &err)
|
||||||
|
|
||||||
changes, err := archive.ChangesDirs(layerFs, idMappings, parentFs, parentMappings)
|
changes, err := archive.ChangesDirs(layerFs, idMappings, parentFs, parentMappings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -104,7 +104,7 @@ func (gdw *NaiveDiffDriver) Diff(id string, idMappings *idtools.IDMappings, pare
|
|||||||
|
|
||||||
return ioutils.NewReadCloserWrapper(archive, func() error {
|
return ioutils.NewReadCloserWrapper(archive, func() error {
|
||||||
err := archive.Close()
|
err := archive.Close()
|
||||||
driver.Put(id)
|
driverPut(driver, id, &err)
|
||||||
|
|
||||||
// NaiveDiffDriver compares file metadata with parent layers. Parent layers
|
// NaiveDiffDriver compares file metadata with parent layers. Parent layers
|
||||||
// are extracted from tar's with full second precision on modified time.
|
// are extracted from tar's with full second precision on modified time.
|
||||||
@ -117,7 +117,7 @@ func (gdw *NaiveDiffDriver) Diff(id string, idMappings *idtools.IDMappings, pare
|
|||||||
|
|
||||||
// Changes produces a list of changes between the specified layer
|
// Changes produces a list of changes between the specified layer
|
||||||
// and its parent layer. If parent is "", then all changes will be ADD changes.
|
// and its parent layer. If parent is "", then all changes will be ADD changes.
|
||||||
func (gdw *NaiveDiffDriver) Changes(id string, idMappings *idtools.IDMappings, parent string, parentMappings *idtools.IDMappings, mountLabel string) ([]archive.Change, error) {
|
func (gdw *NaiveDiffDriver) Changes(id string, idMappings *idtools.IDMappings, parent string, parentMappings *idtools.IDMappings, mountLabel string) (_ []archive.Change, retErr error) {
|
||||||
driver := gdw.ProtoDriver
|
driver := gdw.ProtoDriver
|
||||||
|
|
||||||
if idMappings == nil {
|
if idMappings == nil {
|
||||||
@ -134,7 +134,7 @@ func (gdw *NaiveDiffDriver) Changes(id string, idMappings *idtools.IDMappings, p
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer driver.Put(id)
|
defer driverPut(driver, id, &retErr)
|
||||||
|
|
||||||
parentFs := ""
|
parentFs := ""
|
||||||
|
|
||||||
@ -147,7 +147,7 @@ func (gdw *NaiveDiffDriver) Changes(id string, idMappings *idtools.IDMappings, p
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer driver.Put(parent)
|
defer driverPut(driver, parent, &retErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
return archive.ChangesDirs(layerFs, idMappings, parentFs, parentMappings)
|
return archive.ChangesDirs(layerFs, idMappings, parentFs, parentMappings)
|
||||||
@ -171,7 +171,7 @@ func (gdw *NaiveDiffDriver) ApplyDiff(id, parent string, options ApplyDiffOpts)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer driver.Put(id)
|
defer driverPut(driver, id, &err)
|
||||||
|
|
||||||
defaultForceMask := os.FileMode(0700)
|
defaultForceMask := os.FileMode(0700)
|
||||||
var forceMask *os.FileMode = nil
|
var forceMask *os.FileMode = nil
|
||||||
@ -224,7 +224,7 @@ func (gdw *NaiveDiffDriver) DiffSize(id string, idMappings *idtools.IDMappings,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer driver.Put(id)
|
defer driverPut(driver, id, &err)
|
||||||
|
|
||||||
return archive.ChangesSize(layerFs, changes), nil
|
return archive.ChangesSize(layerFs, changes), nil
|
||||||
}
|
}
|
||||||
|
10
vendor/github.com/containers/storage/drivers/overlay/overlay.go
generated
vendored
10
vendor/github.com/containers/storage/drivers/overlay/overlay.go
generated
vendored
@ -140,8 +140,8 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
graphdriver.Register("overlay", Init)
|
graphdriver.MustRegister("overlay", Init)
|
||||||
graphdriver.Register("overlay2", Init)
|
graphdriver.MustRegister("overlay2", Init)
|
||||||
}
|
}
|
||||||
|
|
||||||
func hasMetacopyOption(opts []string) bool {
|
func hasMetacopyOption(opts []string) bool {
|
||||||
@ -309,9 +309,11 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if fsName, ok := graphdriver.FsNames[fsMagic]; ok {
|
fsName, ok := graphdriver.FsNames[fsMagic]
|
||||||
backingFs = fsName
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("filesystem type %#x reported for %s is not supported with 'overlay': %w", fsMagic, filepath.Dir(home), graphdriver.ErrIncompatibleFS)
|
||||||
}
|
}
|
||||||
|
backingFs = fsName
|
||||||
|
|
||||||
runhome := filepath.Join(options.RunRoot, filepath.Base(home))
|
runhome := filepath.Join(options.RunRoot, filepath.Base(home))
|
||||||
rootUID, rootGID, err := idtools.GetRootUIDGID(options.UIDMaps, options.GIDMaps)
|
rootUID, rootGID, err := idtools.GetRootUIDGID(options.UIDMaps, options.GIDMaps)
|
||||||
|
4
vendor/github.com/containers/storage/drivers/vfs/driver.go
generated
vendored
4
vendor/github.com/containers/storage/drivers/vfs/driver.go
generated
vendored
@ -28,7 +28,7 @@ var (
|
|||||||
const defaultPerms = os.FileMode(0555)
|
const defaultPerms = os.FileMode(0555)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
graphdriver.Register("vfs", Init)
|
graphdriver.MustRegister("vfs", Init)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init returns a new VFS driver.
|
// Init returns a new VFS driver.
|
||||||
@ -98,7 +98,7 @@ func (d *Driver) Status() [][2]string {
|
|||||||
|
|
||||||
// Metadata is used for implementing the graphdriver.ProtoDriver interface. VFS does not currently have any meta data.
|
// Metadata is used for implementing the graphdriver.ProtoDriver interface. VFS does not currently have any meta data.
|
||||||
func (d *Driver) Metadata(id string) (map[string]string, error) {
|
func (d *Driver) Metadata(id string) (map[string]string, error) {
|
||||||
return nil, nil
|
return nil, nil //nolint: nilnil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cleanup is used to implement graphdriver.ProtoDriver. There is no cleanup required for this driver.
|
// Cleanup is used to implement graphdriver.ProtoDriver. There is no cleanup required for this driver.
|
||||||
|
2
vendor/github.com/containers/storage/drivers/windows/windows.go
generated
vendored
2
vendor/github.com/containers/storage/drivers/windows/windows.go
generated
vendored
@ -53,7 +53,7 @@ var (
|
|||||||
|
|
||||||
// init registers the windows graph drivers to the register.
|
// init registers the windows graph drivers to the register.
|
||||||
func init() {
|
func init() {
|
||||||
graphdriver.Register("windowsfilter", InitFilter)
|
graphdriver.MustRegister("windowsfilter", InitFilter)
|
||||||
// DOCKER_WINDOWSFILTER_NOREEXEC allows for inline processing which makes
|
// DOCKER_WINDOWSFILTER_NOREEXEC allows for inline processing which makes
|
||||||
// debugging issues in the re-exec codepath significantly easier.
|
// debugging issues in the re-exec codepath significantly easier.
|
||||||
if os.Getenv("DOCKER_WINDOWSFILTER_NOREEXEC") != "" {
|
if os.Getenv("DOCKER_WINDOWSFILTER_NOREEXEC") != "" {
|
||||||
|
2
vendor/github.com/containers/storage/drivers/zfs/zfs.go
generated
vendored
2
vendor/github.com/containers/storage/drivers/zfs/zfs.go
generated
vendored
@ -33,7 +33,7 @@ type zfsOptions struct {
|
|||||||
const defaultPerms = os.FileMode(0555)
|
const defaultPerms = os.FileMode(0555)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
graphdriver.Register("zfs", Init)
|
graphdriver.MustRegister("zfs", Init)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logger returns a zfs logger implementation.
|
// Logger returns a zfs logger implementation.
|
||||||
|
67
vendor/github.com/containers/storage/images.go
generated
vendored
67
vendor/github.com/containers/storage/images.go
generated
vendored
@ -94,11 +94,11 @@ type Image struct {
|
|||||||
Flags map[string]interface{} `json:"flags,omitempty"`
|
Flags map[string]interface{} `json:"flags,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ROImageStore provides bookkeeping for information about Images.
|
// roImageStore provides bookkeeping for information about Images.
|
||||||
type ROImageStore interface {
|
type roImageStore interface {
|
||||||
ROFileBasedStore
|
roFileBasedStore
|
||||||
ROMetadataStore
|
roMetadataStore
|
||||||
ROBigDataStore
|
roBigDataStore
|
||||||
|
|
||||||
// Exists checks if there is an image with the given ID or name.
|
// Exists checks if there is an image with the given ID or name.
|
||||||
Exists(id string) bool
|
Exists(id string) bool
|
||||||
@ -106,10 +106,6 @@ type ROImageStore interface {
|
|||||||
// Get retrieves information about an image given an ID or name.
|
// Get retrieves information about an image given an ID or name.
|
||||||
Get(id string) (*Image, error)
|
Get(id string) (*Image, error)
|
||||||
|
|
||||||
// Lookup attempts to translate a name to an ID. Most methods do this
|
|
||||||
// implicitly.
|
|
||||||
Lookup(name string) (string, error)
|
|
||||||
|
|
||||||
// Images returns a slice enumerating the known images.
|
// Images returns a slice enumerating the known images.
|
||||||
Images() ([]Image, error)
|
Images() ([]Image, error)
|
||||||
|
|
||||||
@ -120,13 +116,13 @@ type ROImageStore interface {
|
|||||||
ByDigest(d digest.Digest) ([]*Image, error)
|
ByDigest(d digest.Digest) ([]*Image, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImageStore provides bookkeeping for information about Images.
|
// rwImageStore provides bookkeeping for information about Images.
|
||||||
type ImageStore interface {
|
type rwImageStore interface {
|
||||||
ROImageStore
|
roImageStore
|
||||||
RWFileBasedStore
|
rwFileBasedStore
|
||||||
RWMetadataStore
|
rwMetadataStore
|
||||||
RWImageBigDataStore
|
rwImageBigDataStore
|
||||||
FlaggableStore
|
flaggableStore
|
||||||
|
|
||||||
// Create creates an image that has a specified ID (or a random one) and
|
// Create creates an image that has a specified ID (or a random one) and
|
||||||
// optional names, using the specified layer as its topmost (hopefully
|
// optional names, using the specified layer as its topmost (hopefully
|
||||||
@ -299,7 +295,7 @@ func (r *imageStore) Load() error {
|
|||||||
return ErrDuplicateImageNames
|
return ErrDuplicateImageNames
|
||||||
}
|
}
|
||||||
r.images = images
|
r.images = images
|
||||||
r.idindex = truncindex.NewTruncIndex(idlist)
|
r.idindex = truncindex.NewTruncIndex(idlist) // Invalid values in idlist are ignored: they are not a reason to refuse processing the whole store.
|
||||||
r.byid = ids
|
r.byid = ids
|
||||||
r.byname = names
|
r.byname = names
|
||||||
r.bydigest = digests
|
r.bydigest = digests
|
||||||
@ -324,11 +320,13 @@ func (r *imageStore) Save() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer r.Touch()
|
if err := ioutils.AtomicWriteFile(rpath, jdata, 0600); err != nil {
|
||||||
return ioutils.AtomicWriteFile(rpath, jdata, 0600)
|
return err
|
||||||
|
}
|
||||||
|
return r.Touch()
|
||||||
}
|
}
|
||||||
|
|
||||||
func newImageStore(dir string) (ImageStore, error) {
|
func newImageStore(dir string) (rwImageStore, error) {
|
||||||
if err := os.MkdirAll(dir, 0700); err != nil {
|
if err := os.MkdirAll(dir, 0700); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -336,8 +334,6 @@ func newImageStore(dir string) (ImageStore, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
lockfile.Lock()
|
|
||||||
defer lockfile.Unlock()
|
|
||||||
istore := imageStore{
|
istore := imageStore{
|
||||||
lockfile: lockfile,
|
lockfile: lockfile,
|
||||||
dir: dir,
|
dir: dir,
|
||||||
@ -346,19 +342,19 @@ func newImageStore(dir string) (ImageStore, error) {
|
|||||||
byname: make(map[string]*Image),
|
byname: make(map[string]*Image),
|
||||||
bydigest: make(map[digest.Digest][]*Image),
|
bydigest: make(map[digest.Digest][]*Image),
|
||||||
}
|
}
|
||||||
|
istore.Lock()
|
||||||
|
defer istore.Unlock()
|
||||||
if err := istore.Load(); err != nil {
|
if err := istore.Load(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &istore, nil
|
return &istore, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newROImageStore(dir string) (ROImageStore, error) {
|
func newROImageStore(dir string) (roImageStore, error) {
|
||||||
lockfile, err := GetROLockfile(filepath.Join(dir, "images.lock"))
|
lockfile, err := GetROLockfile(filepath.Join(dir, "images.lock"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
lockfile.RLock()
|
|
||||||
defer lockfile.Unlock()
|
|
||||||
istore := imageStore{
|
istore := imageStore{
|
||||||
lockfile: lockfile,
|
lockfile: lockfile,
|
||||||
dir: dir,
|
dir: dir,
|
||||||
@ -367,6 +363,8 @@ func newROImageStore(dir string) (ROImageStore, error) {
|
|||||||
byname: make(map[string]*Image),
|
byname: make(map[string]*Image),
|
||||||
bydigest: make(map[digest.Digest][]*Image),
|
bydigest: make(map[digest.Digest][]*Image),
|
||||||
}
|
}
|
||||||
|
istore.RLock()
|
||||||
|
defer istore.Unlock()
|
||||||
if err := istore.Load(); err != nil {
|
if err := istore.Load(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -455,7 +453,9 @@ func (r *imageStore) Create(id string, names []string, layer, metadata string, c
|
|||||||
return nil, fmt.Errorf("validating digests for new image: %w", err)
|
return nil, fmt.Errorf("validating digests for new image: %w", err)
|
||||||
}
|
}
|
||||||
r.images = append(r.images, image)
|
r.images = append(r.images, image)
|
||||||
r.idindex.Add(id)
|
// This can only fail on duplicate IDs, which shouldn’t happen — and in that case the index is already in the desired state anyway.
|
||||||
|
// Implementing recovery from an unlikely and unimportant failure here would be too risky.
|
||||||
|
_ = r.idindex.Add(id)
|
||||||
r.byid[id] = image
|
r.byid[id] = image
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
r.byname[name] = image
|
r.byname[name] = image
|
||||||
@ -572,7 +572,9 @@ func (r *imageStore) Delete(id string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete(r.byid, id)
|
delete(r.byid, id)
|
||||||
r.idindex.Delete(id)
|
// This can only fail if the ID is already missing, which shouldn’t happen — and in that case the index is already in the desired state anyway.
|
||||||
|
// The store’s Delete method is used on various paths to recover from failures, so this should be robust against partially missing data.
|
||||||
|
_ = r.idindex.Delete(id)
|
||||||
for _, name := range image.Names {
|
for _, name := range image.Names {
|
||||||
delete(r.byname, name)
|
delete(r.byname, name)
|
||||||
}
|
}
|
||||||
@ -608,13 +610,6 @@ func (r *imageStore) Get(id string) (*Image, error) {
|
|||||||
return nil, fmt.Errorf("locating image with ID %q: %w", id, ErrImageUnknown)
|
return nil, fmt.Errorf("locating image with ID %q: %w", id, ErrImageUnknown)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *imageStore) Lookup(name string) (id string, err error) {
|
|
||||||
if image, ok := r.lookup(name); ok {
|
|
||||||
return image.ID, nil
|
|
||||||
}
|
|
||||||
return "", fmt.Errorf("locating image with ID %q: %w", id, ErrImageUnknown)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *imageStore) Exists(id string) bool {
|
func (r *imageStore) Exists(id string) bool {
|
||||||
_, ok := r.lookup(id)
|
_, ok := r.lookup(id)
|
||||||
return ok
|
return ok
|
||||||
@ -798,10 +793,6 @@ func (r *imageStore) Lock() {
|
|||||||
r.lockfile.Lock()
|
r.lockfile.Lock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *imageStore) RecursiveLock() {
|
|
||||||
r.lockfile.RecursiveLock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *imageStore) RLock() {
|
func (r *imageStore) RLock() {
|
||||||
r.lockfile.RLock()
|
r.lockfile.RLock()
|
||||||
}
|
}
|
||||||
|
126
vendor/github.com/containers/storage/layers.go
generated
vendored
126
vendor/github.com/containers/storage/layers.go
generated
vendored
@ -26,7 +26,7 @@ import (
|
|||||||
multierror "github.com/hashicorp/go-multierror"
|
multierror "github.com/hashicorp/go-multierror"
|
||||||
"github.com/klauspost/pgzip"
|
"github.com/klauspost/pgzip"
|
||||||
digest "github.com/opencontainers/go-digest"
|
digest "github.com/opencontainers/go-digest"
|
||||||
"github.com/opencontainers/selinux/go-selinux/label"
|
"github.com/opencontainers/selinux/go-selinux"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/vbatts/tar-split/archive/tar"
|
"github.com/vbatts/tar-split/archive/tar"
|
||||||
"github.com/vbatts/tar-split/tar/asm"
|
"github.com/vbatts/tar-split/tar/asm"
|
||||||
@ -137,13 +137,13 @@ type DiffOptions struct {
|
|||||||
Compression *archive.Compression
|
Compression *archive.Compression
|
||||||
}
|
}
|
||||||
|
|
||||||
// ROLayerStore wraps a graph driver, adding the ability to refer to layers by
|
// roLayerStore wraps a graph driver, adding the ability to refer to layers by
|
||||||
// name, and keeping track of parent-child relationships, along with a list of
|
// name, and keeping track of parent-child relationships, along with a list of
|
||||||
// all known layers.
|
// all known layers.
|
||||||
type ROLayerStore interface {
|
type roLayerStore interface {
|
||||||
ROFileBasedStore
|
roFileBasedStore
|
||||||
ROMetadataStore
|
roMetadataStore
|
||||||
ROLayerBigDataStore
|
roLayerBigDataStore
|
||||||
|
|
||||||
// Exists checks if a layer with the specified name or ID is known.
|
// Exists checks if a layer with the specified name or ID is known.
|
||||||
Exists(id string) bool
|
Exists(id string) bool
|
||||||
@ -177,10 +177,6 @@ type ROLayerStore interface {
|
|||||||
// found, it returns an error.
|
// found, it returns an error.
|
||||||
Size(name string) (int64, error)
|
Size(name string) (int64, error)
|
||||||
|
|
||||||
// Lookup attempts to translate a name to an ID. Most methods do this
|
|
||||||
// implicitly.
|
|
||||||
Lookup(name string) (string, error)
|
|
||||||
|
|
||||||
// LayersByCompressedDigest returns a slice of the layers with the
|
// LayersByCompressedDigest returns a slice of the layers with the
|
||||||
// specified compressed digest value recorded for them.
|
// specified compressed digest value recorded for them.
|
||||||
LayersByCompressedDigest(d digest.Digest) ([]Layer, error)
|
LayersByCompressedDigest(d digest.Digest) ([]Layer, error)
|
||||||
@ -193,15 +189,15 @@ type ROLayerStore interface {
|
|||||||
Layers() ([]Layer, error)
|
Layers() ([]Layer, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LayerStore wraps a graph driver, adding the ability to refer to layers by
|
// rwLayerStore wraps a graph driver, adding the ability to refer to layers by
|
||||||
// name, and keeping track of parent-child relationships, along with a list of
|
// name, and keeping track of parent-child relationships, along with a list of
|
||||||
// all known layers.
|
// all known layers.
|
||||||
type LayerStore interface {
|
type rwLayerStore interface {
|
||||||
ROLayerStore
|
roLayerStore
|
||||||
RWFileBasedStore
|
rwFileBasedStore
|
||||||
RWMetadataStore
|
rwMetadataStore
|
||||||
FlaggableStore
|
flaggableStore
|
||||||
RWLayerBigDataStore
|
rwLayerBigDataStore
|
||||||
|
|
||||||
// Create creates a new layer, optionally giving it a specified ID rather than
|
// Create creates a new layer, optionally giving it a specified ID rather than
|
||||||
// a randomly-generated one, either inheriting data from another specified
|
// a randomly-generated one, either inheriting data from another specified
|
||||||
@ -270,10 +266,6 @@ type LayerStore interface {
|
|||||||
// DifferTarget gets the location where files are stored for the layer.
|
// DifferTarget gets the location where files are stored for the layer.
|
||||||
DifferTarget(id string) (string, error)
|
DifferTarget(id string) (string, error)
|
||||||
|
|
||||||
// LoadLocked wraps Load in a locked state. This means it loads the store
|
|
||||||
// and cleans-up invalid layers if needed.
|
|
||||||
LoadLocked() error
|
|
||||||
|
|
||||||
// PutAdditionalLayer creates a layer using the diff contained in the additional layer
|
// PutAdditionalLayer creates a layer using the diff contained in the additional layer
|
||||||
// store.
|
// store.
|
||||||
// This API is experimental and can be changed without bumping the major version number.
|
// This API is experimental and can be changed without bumping the major version number.
|
||||||
@ -293,8 +285,6 @@ type layerStore struct {
|
|||||||
bymount map[string]*Layer
|
bymount map[string]*Layer
|
||||||
bycompressedsum map[digest.Digest][]string
|
bycompressedsum map[digest.Digest][]string
|
||||||
byuncompressedsum map[digest.Digest][]string
|
byuncompressedsum map[digest.Digest][]string
|
||||||
uidMap []idtools.IDMap
|
|
||||||
gidMap []idtools.IDMap
|
|
||||||
loadMut sync.Mutex
|
loadMut sync.Mutex
|
||||||
layerspathModified time.Time
|
layerspathModified time.Time
|
||||||
}
|
}
|
||||||
@ -362,7 +352,7 @@ func (r *layerStore) Load() error {
|
|||||||
compressedsums := make(map[digest.Digest][]string)
|
compressedsums := make(map[digest.Digest][]string)
|
||||||
uncompressedsums := make(map[digest.Digest][]string)
|
uncompressedsums := make(map[digest.Digest][]string)
|
||||||
if r.IsReadWrite() {
|
if r.IsReadWrite() {
|
||||||
label.ClearLabels()
|
selinux.ClearLabels()
|
||||||
}
|
}
|
||||||
if err = json.Unmarshal(data, &layers); len(data) == 0 || err == nil {
|
if err = json.Unmarshal(data, &layers); len(data) == 0 || err == nil {
|
||||||
idlist = make([]string, 0, len(layers))
|
idlist = make([]string, 0, len(layers))
|
||||||
@ -383,7 +373,7 @@ func (r *layerStore) Load() error {
|
|||||||
uncompressedsums[layer.UncompressedDigest] = append(uncompressedsums[layer.UncompressedDigest], layer.ID)
|
uncompressedsums[layer.UncompressedDigest] = append(uncompressedsums[layer.UncompressedDigest], layer.ID)
|
||||||
}
|
}
|
||||||
if layer.MountLabel != "" {
|
if layer.MountLabel != "" {
|
||||||
label.ReserveLabel(layer.MountLabel)
|
selinux.ReserveLabel(layer.MountLabel)
|
||||||
}
|
}
|
||||||
layer.ReadOnly = !r.IsReadWrite()
|
layer.ReadOnly = !r.IsReadWrite()
|
||||||
}
|
}
|
||||||
@ -393,7 +383,7 @@ func (r *layerStore) Load() error {
|
|||||||
return ErrDuplicateLayerNames
|
return ErrDuplicateLayerNames
|
||||||
}
|
}
|
||||||
r.layers = layers
|
r.layers = layers
|
||||||
r.idindex = truncindex.NewTruncIndex(idlist)
|
r.idindex = truncindex.NewTruncIndex(idlist) // Invalid values in idlist are ignored: they are not a reason to refuse processing the whole store.
|
||||||
r.byid = ids
|
r.byid = ids
|
||||||
r.byname = names
|
r.byname = names
|
||||||
r.bycompressedsum = compressedsums
|
r.bycompressedsum = compressedsums
|
||||||
@ -433,12 +423,6 @@ func (r *layerStore) Load() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *layerStore) LoadLocked() error {
|
|
||||||
r.lockfile.Lock()
|
|
||||||
defer r.lockfile.Unlock()
|
|
||||||
return r.Load()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *layerStore) loadMounts() error {
|
func (r *layerStore) loadMounts() error {
|
||||||
mounts := make(map[string]*Layer)
|
mounts := make(map[string]*Layer)
|
||||||
mpath := r.mountspath()
|
mpath := r.mountspath()
|
||||||
@ -479,7 +463,6 @@ func (r *layerStore) loadMounts() error {
|
|||||||
func (r *layerStore) Save() error {
|
func (r *layerStore) Save() error {
|
||||||
r.mountsLockfile.Lock()
|
r.mountsLockfile.Lock()
|
||||||
defer r.mountsLockfile.Unlock()
|
defer r.mountsLockfile.Unlock()
|
||||||
defer r.mountsLockfile.Touch()
|
|
||||||
if err := r.saveLayers(); err != nil {
|
if err := r.saveLayers(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -501,8 +484,10 @@ func (r *layerStore) saveLayers() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer r.Touch()
|
if err := ioutils.AtomicWriteFile(rpath, jldata, 0600); err != nil {
|
||||||
return ioutils.AtomicWriteFile(rpath, jldata, 0600)
|
return err
|
||||||
|
}
|
||||||
|
return r.Touch()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *layerStore) saveMounts() error {
|
func (r *layerStore) saveMounts() error {
|
||||||
@ -533,10 +518,13 @@ func (r *layerStore) saveMounts() error {
|
|||||||
if err = ioutils.AtomicWriteFile(mpath, jmdata, 0600); err != nil {
|
if err = ioutils.AtomicWriteFile(mpath, jmdata, 0600); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := r.mountsLockfile.Touch(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return r.loadMounts()
|
return r.loadMounts()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *store) newLayerStore(rundir string, layerdir string, driver drivers.Driver) (LayerStore, error) {
|
func (s *store) newLayerStore(rundir string, layerdir string, driver drivers.Driver) (rwLayerStore, error) {
|
||||||
if err := os.MkdirAll(rundir, 0700); err != nil {
|
if err := os.MkdirAll(rundir, 0700); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -560,8 +548,6 @@ func (s *store) newLayerStore(rundir string, layerdir string, driver drivers.Dri
|
|||||||
byid: make(map[string]*Layer),
|
byid: make(map[string]*Layer),
|
||||||
bymount: make(map[string]*Layer),
|
bymount: make(map[string]*Layer),
|
||||||
byname: make(map[string]*Layer),
|
byname: make(map[string]*Layer),
|
||||||
uidMap: copyIDMap(s.uidMap),
|
|
||||||
gidMap: copyIDMap(s.gidMap),
|
|
||||||
}
|
}
|
||||||
rlstore.Lock()
|
rlstore.Lock()
|
||||||
defer rlstore.Unlock()
|
defer rlstore.Unlock()
|
||||||
@ -571,7 +557,7 @@ func (s *store) newLayerStore(rundir string, layerdir string, driver drivers.Dri
|
|||||||
return &rlstore, nil
|
return &rlstore, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newROLayerStore(rundir string, layerdir string, driver drivers.Driver) (ROLayerStore, error) {
|
func newROLayerStore(rundir string, layerdir string, driver drivers.Driver) (roLayerStore, error) {
|
||||||
lockfile, err := GetROLockfile(filepath.Join(layerdir, "layers.lock"))
|
lockfile, err := GetROLockfile(filepath.Join(layerdir, "layers.lock"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -685,7 +671,9 @@ func (r *layerStore) PutAdditionalLayer(id string, parentLayer *Layer, names []s
|
|||||||
|
|
||||||
// TODO: check if necessary fields are filled
|
// TODO: check if necessary fields are filled
|
||||||
r.layers = append(r.layers, layer)
|
r.layers = append(r.layers, layer)
|
||||||
r.idindex.Add(id)
|
// This can only fail on duplicate IDs, which shouldn’t happen — and in that case the index is already in the desired state anyway.
|
||||||
|
// Implementing recovery from an unlikely and unimportant failure here would be too risky.
|
||||||
|
_ = r.idindex.Add(id)
|
||||||
r.byid[id] = layer
|
r.byid[id] = layer
|
||||||
for _, name := range names { // names got from the additional layer store won't be used
|
for _, name := range names { // names got from the additional layer store won't be used
|
||||||
r.byname[name] = layer
|
r.byname[name] = layer
|
||||||
@ -697,7 +685,9 @@ func (r *layerStore) PutAdditionalLayer(id string, parentLayer *Layer, names []s
|
|||||||
r.byuncompressedsum[layer.UncompressedDigest] = append(r.byuncompressedsum[layer.UncompressedDigest], layer.ID)
|
r.byuncompressedsum[layer.UncompressedDigest] = append(r.byuncompressedsum[layer.UncompressedDigest], layer.ID)
|
||||||
}
|
}
|
||||||
if err := r.Save(); err != nil {
|
if err := r.Save(); err != nil {
|
||||||
r.driver.Remove(id)
|
if err2 := r.driver.Remove(id); err2 != nil {
|
||||||
|
logrus.Errorf("While recovering from a failure to save layers, error deleting layer %#v: %v", id, err2)
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return copyLayer(layer), nil
|
return copyLayer(layer), nil
|
||||||
@ -770,7 +760,7 @@ func (r *layerStore) Put(id string, parentLayer *Layer, names []string, mountLab
|
|||||||
parentMappings = &idtools.IDMappings{}
|
parentMappings = &idtools.IDMappings{}
|
||||||
}
|
}
|
||||||
if mountLabel != "" {
|
if mountLabel != "" {
|
||||||
label.ReserveLabel(mountLabel)
|
selinux.ReserveLabel(mountLabel)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Before actually creating the layer, make a persistent record of it with incompleteFlag,
|
// Before actually creating the layer, make a persistent record of it with incompleteFlag,
|
||||||
@ -795,7 +785,9 @@ func (r *layerStore) Put(id string, parentLayer *Layer, names []string, mountLab
|
|||||||
BigDataNames: []string{},
|
BigDataNames: []string{},
|
||||||
}
|
}
|
||||||
r.layers = append(r.layers, layer)
|
r.layers = append(r.layers, layer)
|
||||||
r.idindex.Add(id)
|
// This can only fail if the ID is already missing, which shouldn’t happen — and in that case the index is already in the desired state anyway.
|
||||||
|
// This is on various paths to recover from failures, so this should be robust against partially missing data.
|
||||||
|
_ = r.idindex.Add(id)
|
||||||
r.byid[id] = layer
|
r.byid[id] = layer
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
r.byname[name] = layer
|
r.byname[name] = layer
|
||||||
@ -947,7 +939,6 @@ func (r *layerStore) Mount(id string, options drivers.MountOpts) (string, error)
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
defer r.mountsLockfile.Touch()
|
|
||||||
layer, ok := r.lookup(id)
|
layer, ok := r.lookup(id)
|
||||||
if !ok {
|
if !ok {
|
||||||
return "", ErrLayerUnknown
|
return "", ErrLayerUnknown
|
||||||
@ -998,7 +989,6 @@ func (r *layerStore) Unmount(id string, force bool) (bool, error) {
|
|||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
defer r.mountsLockfile.Touch()
|
|
||||||
layer, ok := r.lookup(id)
|
layer, ok := r.lookup(id)
|
||||||
if !ok {
|
if !ok {
|
||||||
layerByMount, ok := r.bymount[filepath.Clean(id)]
|
layerByMount, ok := r.bymount[filepath.Clean(id)]
|
||||||
@ -1279,7 +1269,9 @@ func (r *layerStore) deleteInternal(id string) error {
|
|||||||
for _, name := range layer.Names {
|
for _, name := range layer.Names {
|
||||||
delete(r.byname, name)
|
delete(r.byname, name)
|
||||||
}
|
}
|
||||||
r.idindex.Delete(id)
|
// This can only fail if the ID is already missing, which shouldn’t happen — and in that case the index is already in the desired state anyway.
|
||||||
|
// The store’s Delete method is used on various paths to recover from failures, so this should be robust against partially missing data.
|
||||||
|
_ = r.idindex.Delete(id)
|
||||||
mountLabel := layer.MountLabel
|
mountLabel := layer.MountLabel
|
||||||
if layer.MountPoint != "" {
|
if layer.MountPoint != "" {
|
||||||
delete(r.bymount, layer.MountPoint)
|
delete(r.bymount, layer.MountPoint)
|
||||||
@ -1309,7 +1301,7 @@ func (r *layerStore) deleteInternal(id string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !found {
|
if !found {
|
||||||
label.ReleaseLabel(mountLabel)
|
selinux.ReleaseLabel(mountLabel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1365,13 +1357,6 @@ func (r *layerStore) Delete(id string) error {
|
|||||||
return r.Save()
|
return r.Save()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *layerStore) Lookup(name string) (id string, err error) {
|
|
||||||
if layer, ok := r.lookup(name); ok {
|
|
||||||
return layer.ID, nil
|
|
||||||
}
|
|
||||||
return "", ErrLayerUnknown
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *layerStore) Exists(id string) bool {
|
func (r *layerStore) Exists(id string) bool {
|
||||||
_, ok := r.lookup(id)
|
_, ok := r.lookup(id)
|
||||||
return ok
|
return ok
|
||||||
@ -1472,6 +1457,24 @@ func (r *layerStore) newFileGetter(id string) (drivers.FileGetCloser, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// writeCompressedData copies data from source to compressor, which is on top of pwriter.
|
||||||
|
func writeCompressedData(compressor io.WriteCloser, source io.ReadCloser) error {
|
||||||
|
defer compressor.Close()
|
||||||
|
defer source.Close()
|
||||||
|
_, err := io.Copy(compressor, source)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// writeCompressedDataGoroutine copies data from source to compressor, which is on top of pwriter.
|
||||||
|
// All error must be reported by updating pwriter.
|
||||||
|
func writeCompressedDataGoroutine(pwriter *io.PipeWriter, compressor io.WriteCloser, source io.ReadCloser) {
|
||||||
|
err := errors.New("internal error: unexpected panic in writeCompressedDataGoroutine")
|
||||||
|
defer func() { // Note that this is not the same as {defer dest.CloseWithError(err)}; we need err to be evaluated lazily.
|
||||||
|
_ = pwriter.CloseWithError(err) // CloseWithError(nil) is equivalent to Close(), always returns nil
|
||||||
|
}()
|
||||||
|
err = writeCompressedData(compressor, source)
|
||||||
|
}
|
||||||
|
|
||||||
func (r *layerStore) Diff(from, to string, options *DiffOptions) (io.ReadCloser, error) {
|
func (r *layerStore) Diff(from, to string, options *DiffOptions) (io.ReadCloser, error) {
|
||||||
var metadata storage.Unpacker
|
var metadata storage.Unpacker
|
||||||
|
|
||||||
@ -1503,12 +1506,7 @@ func (r *layerStore) Diff(from, to string, options *DiffOptions) (io.ReadCloser,
|
|||||||
preader.Close()
|
preader.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
go func() {
|
go writeCompressedDataGoroutine(pwriter, compressor, rc)
|
||||||
defer pwriter.Close()
|
|
||||||
defer compressor.Close()
|
|
||||||
defer rc.Close()
|
|
||||||
io.Copy(compressor, rc)
|
|
||||||
}()
|
|
||||||
return preader, nil
|
return preader, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1825,7 +1823,9 @@ func (r *layerStore) ApplyDiffFromStagingDirectory(id, stagingDirectory string,
|
|||||||
}
|
}
|
||||||
for k, v := range diffOutput.BigData {
|
for k, v := range diffOutput.BigData {
|
||||||
if err := r.SetBigData(id, k, bytes.NewReader(v)); err != nil {
|
if err := r.SetBigData(id, k, bytes.NewReader(v)); err != nil {
|
||||||
r.Delete(id)
|
if err2 := r.Delete(id); err2 != nil {
|
||||||
|
logrus.Errorf("While recovering from a failure to set big data, error deleting layer %#v: %v", id, err2)
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1895,10 +1895,6 @@ func (r *layerStore) Lock() {
|
|||||||
r.lockfile.Lock()
|
r.lockfile.Lock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *layerStore) RecursiveLock() {
|
|
||||||
r.lockfile.RecursiveLock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *layerStore) RLock() {
|
func (r *layerStore) RLock() {
|
||||||
r.lockfile.RLock()
|
r.lockfile.RLock()
|
||||||
}
|
}
|
||||||
|
2
vendor/github.com/containers/storage/pkg/archive/archive.go
generated
vendored
2
vendor/github.com/containers/storage/pkg/archive/archive.go
generated
vendored
@ -874,7 +874,7 @@ func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error)
|
|||||||
if err != nil || (!options.IncludeSourceDir && relFilePath == "." && d.IsDir()) {
|
if err != nil || (!options.IncludeSourceDir && relFilePath == "." && d.IsDir()) {
|
||||||
// Error getting relative path OR we are looking
|
// Error getting relative path OR we are looking
|
||||||
// at the source directory path. Skip in both situations.
|
// at the source directory path. Skip in both situations.
|
||||||
return nil
|
return nil //nolint: nilerr
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.IncludeSourceDir && include == "." && relFilePath != "." {
|
if options.IncludeSourceDir && include == "." && relFilePath != "." {
|
||||||
|
19
vendor/github.com/containers/storage/pkg/archive/archive_bsd.go
generated
vendored
Normal file
19
vendor/github.com/containers/storage/pkg/archive/archive_bsd.go
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
//go:build freebsd || darwin
|
||||||
|
// +build freebsd darwin
|
||||||
|
|
||||||
|
package archive
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/tar"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo, forceMask *os.FileMode) error {
|
||||||
|
permissionsMask := hdrInfo.Mode()
|
||||||
|
if forceMask != nil {
|
||||||
|
permissionsMask = *forceMask
|
||||||
|
}
|
||||||
|
return unix.Fchmodat(unix.AT_FDCWD, path, uint32(permissionsMask), unix.AT_SYMLINK_NOFOLLOW)
|
||||||
|
}
|
129
vendor/github.com/containers/storage/pkg/archive/archive_freebsd.go
generated
vendored
129
vendor/github.com/containers/storage/pkg/archive/archive_freebsd.go
generated
vendored
@ -1,129 +0,0 @@
|
|||||||
//go:build freebsd
|
|
||||||
// +build freebsd
|
|
||||||
|
|
||||||
package archive
|
|
||||||
|
|
||||||
import (
|
|
||||||
"archive/tar"
|
|
||||||
"errors"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/containers/storage/pkg/idtools"
|
|
||||||
"github.com/containers/storage/pkg/system"
|
|
||||||
"github.com/containers/storage/pkg/unshare"
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
|
||||||
|
|
||||||
// fixVolumePathPrefix does platform specific processing to ensure that if
|
|
||||||
// the path being passed in is not in a volume path format, convert it to one.
|
|
||||||
func fixVolumePathPrefix(srcPath string) string {
|
|
||||||
return srcPath
|
|
||||||
}
|
|
||||||
|
|
||||||
// getWalkRoot calculates the root path when performing a TarWithOptions.
|
|
||||||
// We use a separate function as this is platform specific. On Linux, we
|
|
||||||
// can't use filepath.Join(srcPath,include) because this will clean away
|
|
||||||
// a trailing "." or "/" which may be important.
|
|
||||||
func getWalkRoot(srcPath string, include string) string {
|
|
||||||
return srcPath + string(filepath.Separator) + include
|
|
||||||
}
|
|
||||||
|
|
||||||
// CanonicalTarNameForPath returns platform-specific filepath
|
|
||||||
// to canonical posix-style path for tar archival. p is relative
|
|
||||||
// path.
|
|
||||||
func CanonicalTarNameForPath(p string) (string, error) {
|
|
||||||
return p, nil // already unix-style
|
|
||||||
}
|
|
||||||
|
|
||||||
// chmodTarEntry is used to adjust the file permissions used in tar header based
|
|
||||||
// on the platform the archival is done.
|
|
||||||
func chmodTarEntry(perm os.FileMode) os.FileMode {
|
|
||||||
return perm // noop for unix as golang APIs provide perm bits correctly
|
|
||||||
}
|
|
||||||
|
|
||||||
func setHeaderForSpecialDevice(hdr *tar.Header, name string, stat interface{}) (err error) {
|
|
||||||
s, ok := stat.(*syscall.Stat_t)
|
|
||||||
|
|
||||||
if ok {
|
|
||||||
// Currently go does not fill in the major/minors
|
|
||||||
if s.Mode&unix.S_IFBLK != 0 ||
|
|
||||||
s.Mode&unix.S_IFCHR != 0 {
|
|
||||||
hdr.Devmajor = int64(major(uint64(s.Rdev))) // nolint: unconvert
|
|
||||||
hdr.Devminor = int64(minor(uint64(s.Rdev))) // nolint: unconvert
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func getInodeFromStat(stat interface{}) (inode uint64, err error) {
|
|
||||||
s, ok := stat.(*syscall.Stat_t)
|
|
||||||
|
|
||||||
if ok {
|
|
||||||
inode = s.Ino
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func getFileUIDGID(stat interface{}) (idtools.IDPair, error) {
|
|
||||||
s, ok := stat.(*syscall.Stat_t)
|
|
||||||
|
|
||||||
if !ok {
|
|
||||||
return idtools.IDPair{}, errors.New("cannot convert stat value to syscall.Stat_t")
|
|
||||||
}
|
|
||||||
return idtools.IDPair{UID: int(s.Uid), GID: int(s.Gid)}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func major(device uint64) uint64 {
|
|
||||||
return (device >> 8) & 0xfff
|
|
||||||
}
|
|
||||||
|
|
||||||
func minor(device uint64) uint64 {
|
|
||||||
return (device & 0xff) | ((device >> 12) & 0xfff00)
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleTarTypeBlockCharFifo is an OS-specific helper function used by
|
|
||||||
// createTarFile to handle the following types of header: Block; Char; Fifo
|
|
||||||
func handleTarTypeBlockCharFifo(hdr *tar.Header, path string) error {
|
|
||||||
if unshare.IsRootless() {
|
|
||||||
// cannot create a device if running in user namespace
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
mode := uint32(hdr.Mode & 07777)
|
|
||||||
switch hdr.Typeflag {
|
|
||||||
case tar.TypeBlock:
|
|
||||||
mode |= unix.S_IFBLK
|
|
||||||
case tar.TypeChar:
|
|
||||||
mode |= unix.S_IFCHR
|
|
||||||
case tar.TypeFifo:
|
|
||||||
mode |= unix.S_IFIFO
|
|
||||||
}
|
|
||||||
|
|
||||||
return system.Mknod(path, mode, uint64(system.Mkdev(hdr.Devmajor, hdr.Devminor)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo, forceMask *os.FileMode) error {
|
|
||||||
permissionsMask := hdrInfo.Mode()
|
|
||||||
if forceMask != nil {
|
|
||||||
permissionsMask = *forceMask
|
|
||||||
}
|
|
||||||
p, err := unix.BytePtrFromString(path)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, _, e1 := unix.Syscall(unix.SYS_LCHMOD, uintptr(unsafe.Pointer(p)), uintptr(permissionsMask), 0)
|
|
||||||
if e1 != 0 {
|
|
||||||
return e1
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hardlink without following symlinks
|
|
||||||
func handleLLink(targetPath string, path string) error {
|
|
||||||
return unix.Linkat(unix.AT_FDCWD, targetPath, unix.AT_FDCWD, path, 0)
|
|
||||||
}
|
|
19
vendor/github.com/containers/storage/pkg/archive/archive_linux.go
generated
vendored
19
vendor/github.com/containers/storage/pkg/archive/archive_linux.go
generated
vendored
@ -189,3 +189,22 @@ func GetFileOwner(path string) (uint32, uint32, uint32, error) {
|
|||||||
}
|
}
|
||||||
return 0, 0, uint32(f.Mode()), nil
|
return 0, 0, uint32(f.Mode()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo, forceMask *os.FileMode) error {
|
||||||
|
permissionsMask := hdrInfo.Mode()
|
||||||
|
if forceMask != nil {
|
||||||
|
permissionsMask = *forceMask
|
||||||
|
}
|
||||||
|
if hdr.Typeflag == tar.TypeLink {
|
||||||
|
if fi, err := os.Lstat(hdr.Linkname); err == nil && (fi.Mode()&os.ModeSymlink == 0) {
|
||||||
|
if err := os.Chmod(path, permissionsMask); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if hdr.Typeflag != tar.TypeSymlink {
|
||||||
|
if err := os.Chmod(path, permissionsMask); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
23
vendor/github.com/containers/storage/pkg/archive/archive_unix.go
generated
vendored
23
vendor/github.com/containers/storage/pkg/archive/archive_unix.go
generated
vendored
@ -1,5 +1,5 @@
|
|||||||
//go:build !windows && !freebsd
|
//go:build !windows
|
||||||
// +build !windows,!freebsd
|
// +build !windows
|
||||||
|
|
||||||
package archive
|
package archive
|
||||||
|
|
||||||
@ -101,25 +101,6 @@ func handleTarTypeBlockCharFifo(hdr *tar.Header, path string) error {
|
|||||||
return system.Mknod(path, mode, system.Mkdev(hdr.Devmajor, hdr.Devminor))
|
return system.Mknod(path, mode, system.Mkdev(hdr.Devmajor, hdr.Devminor))
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo, forceMask *os.FileMode) error {
|
|
||||||
permissionsMask := hdrInfo.Mode()
|
|
||||||
if forceMask != nil {
|
|
||||||
permissionsMask = *forceMask
|
|
||||||
}
|
|
||||||
if hdr.Typeflag == tar.TypeLink {
|
|
||||||
if fi, err := os.Lstat(hdr.Linkname); err == nil && (fi.Mode()&os.ModeSymlink == 0) {
|
|
||||||
if err := os.Chmod(path, permissionsMask); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if hdr.Typeflag != tar.TypeSymlink {
|
|
||||||
if err := os.Chmod(path, permissionsMask); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hardlink without symlinks
|
// Hardlink without symlinks
|
||||||
func handleLLink(targetPath, path string) error {
|
func handleLLink(targetPath, path string) error {
|
||||||
// Note: on Linux, the link syscall will not follow symlinks.
|
// Note: on Linux, the link syscall will not follow symlinks.
|
||||||
|
2
vendor/github.com/containers/storage/pkg/archive/changes.go
generated
vendored
2
vendor/github.com/containers/storage/pkg/archive/changes.go
generated
vendored
@ -56,7 +56,7 @@ func (change *Change) String() string {
|
|||||||
return fmt.Sprintf("%s %s", change.Kind, change.Path)
|
return fmt.Sprintf("%s %s", change.Kind, change.Path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// for sort.Sort
|
// changesByPath implements sort.Interface.
|
||||||
type changesByPath []Change
|
type changesByPath []Change
|
||||||
|
|
||||||
func (c changesByPath) Less(i, j int) bool { return c[i].Path < c[j].Path }
|
func (c changesByPath) Less(i, j int) bool { return c[i].Path < c[j].Path }
|
||||||
|
4
vendor/github.com/containers/storage/pkg/archive/diff.go
generated
vendored
4
vendor/github.com/containers/storage/pkg/archive/diff.go
generated
vendored
@ -245,7 +245,9 @@ func applyLayerHandler(dest string, layer io.Reader, options *TarOptions, decomp
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
defer system.Umask(oldmask) // ignore err, ErrNotSupportedPlatform
|
defer func() {
|
||||||
|
_, _ = system.Umask(oldmask) // Ignore err. This can only fail with ErrNotSupportedPlatform, in which case we would have failed above.
|
||||||
|
}()
|
||||||
|
|
||||||
if decompress {
|
if decompress {
|
||||||
layer, err = DecompressStream(layer)
|
layer, err = DecompressStream(layer)
|
||||||
|
6
vendor/github.com/containers/storage/pkg/chunked/compressor/compressor.go
generated
vendored
6
vendor/github.com/containers/storage/pkg/chunked/compressor/compressor.go
generated
vendored
@ -78,7 +78,7 @@ func (f *holesFinder) ReadByte() (int64, byte, error) {
|
|||||||
f.state = holesFinderStateFound
|
f.state = holesFinderStateFound
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if f.reader.UnreadByte(); err != nil {
|
if err := f.reader.UnreadByte(); err != nil {
|
||||||
return 0, 0, err
|
return 0, 0, err
|
||||||
}
|
}
|
||||||
f.state = holesFinderStateRead
|
f.state = holesFinderStateRead
|
||||||
@ -95,7 +95,7 @@ func (f *holesFinder) ReadByte() (int64, byte, error) {
|
|||||||
return holeLen, 0, nil
|
return holeLen, 0, nil
|
||||||
}
|
}
|
||||||
if b != 0 {
|
if b != 0 {
|
||||||
if f.reader.UnreadByte(); err != nil {
|
if err := f.reader.UnreadByte(); err != nil {
|
||||||
return 0, 0, err
|
return 0, 0, err
|
||||||
}
|
}
|
||||||
f.state = holesFinderStateRead
|
f.state = holesFinderStateRead
|
||||||
@ -429,7 +429,7 @@ func zstdChunkedWriterWithLevel(out io.Writer, metadata map[string]string, level
|
|||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
ch <- writeZstdChunkedStream(out, metadata, r, level)
|
ch <- writeZstdChunkedStream(out, metadata, r, level)
|
||||||
io.Copy(io.Discard, r)
|
_, _ = io.Copy(io.Discard, r) // Ordinarily writeZstdChunkedStream consumes all of r. If it fails, ensure the write end never blocks and eventually terminates.
|
||||||
r.Close()
|
r.Close()
|
||||||
close(ch)
|
close(ch)
|
||||||
}()
|
}()
|
||||||
|
2
vendor/github.com/containers/storage/pkg/chunked/storage.go
generated
vendored
2
vendor/github.com/containers/storage/pkg/chunked/storage.go
generated
vendored
@ -17,7 +17,7 @@ type ImageSourceSeekable interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ErrBadRequest is returned when the request is not valid
|
// ErrBadRequest is returned when the request is not valid
|
||||||
type ErrBadRequest struct {
|
type ErrBadRequest struct { //nolint: errname
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e ErrBadRequest) Error() string {
|
func (e ErrBadRequest) Error() string {
|
||||||
|
2
vendor/github.com/containers/storage/pkg/homedir/homedir_unix.go
generated
vendored
2
vendor/github.com/containers/storage/pkg/homedir/homedir_unix.go
generated
vendored
@ -63,7 +63,7 @@ func StickRuntimeDirContents(files []string) ([]string, error) {
|
|||||||
runtimeDir, err := GetRuntimeDir()
|
runtimeDir, err := GetRuntimeDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// ignore error if runtimeDir is empty
|
// ignore error if runtimeDir is empty
|
||||||
return nil, nil
|
return nil, nil //nolint: nilerr
|
||||||
}
|
}
|
||||||
runtimeDir, err = filepath.Abs(runtimeDir)
|
runtimeDir, err = filepath.Abs(runtimeDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
11
vendor/github.com/containers/storage/pkg/ioutils/fswriters.go
generated
vendored
11
vendor/github.com/containers/storage/pkg/ioutils/fswriters.go
generated
vendored
@ -27,6 +27,13 @@ func SetDefaultOptions(opts AtomicFileWriterOptions) {
|
|||||||
// temporary file and closing it atomically changes the temporary file to
|
// temporary file and closing it atomically changes the temporary file to
|
||||||
// destination path. Writing and closing concurrently is not allowed.
|
// destination path. Writing and closing concurrently is not allowed.
|
||||||
func NewAtomicFileWriterWithOpts(filename string, perm os.FileMode, opts *AtomicFileWriterOptions) (io.WriteCloser, error) {
|
func NewAtomicFileWriterWithOpts(filename string, perm os.FileMode, opts *AtomicFileWriterOptions) (io.WriteCloser, error) {
|
||||||
|
return newAtomicFileWriter(filename, perm, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
// newAtomicFileWriter returns WriteCloser so that writing to it writes to a
|
||||||
|
// temporary file and closing it atomically changes the temporary file to
|
||||||
|
// destination path. Writing and closing concurrently is not allowed.
|
||||||
|
func newAtomicFileWriter(filename string, perm os.FileMode, opts *AtomicFileWriterOptions) (*atomicFileWriter, error) {
|
||||||
f, err := os.CreateTemp(filepath.Dir(filename), ".tmp-"+filepath.Base(filename))
|
f, err := os.CreateTemp(filepath.Dir(filename), ".tmp-"+filepath.Base(filename))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -55,14 +62,14 @@ func NewAtomicFileWriter(filename string, perm os.FileMode) (io.WriteCloser, err
|
|||||||
|
|
||||||
// AtomicWriteFile atomically writes data to a file named by filename.
|
// AtomicWriteFile atomically writes data to a file named by filename.
|
||||||
func AtomicWriteFile(filename string, data []byte, perm os.FileMode) error {
|
func AtomicWriteFile(filename string, data []byte, perm os.FileMode) error {
|
||||||
f, err := NewAtomicFileWriter(filename, perm)
|
f, err := newAtomicFileWriter(filename, perm, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
n, err := f.Write(data)
|
n, err := f.Write(data)
|
||||||
if err == nil && n < len(data) {
|
if err == nil && n < len(data) {
|
||||||
err = io.ErrShortWrite
|
err = io.ErrShortWrite
|
||||||
f.(*atomicFileWriter).writeErr = err
|
f.writeErr = err
|
||||||
}
|
}
|
||||||
if err1 := f.Close(); err == nil {
|
if err1 := f.Close(); err == nil {
|
||||||
err = err1
|
err = err1
|
||||||
|
4
vendor/github.com/containers/storage/pkg/lockfile/lockfile.go
generated
vendored
4
vendor/github.com/containers/storage/pkg/lockfile/lockfile.go
generated
vendored
@ -17,10 +17,6 @@ type Locker interface {
|
|||||||
// - tried to lock a read-only lock-file
|
// - tried to lock a read-only lock-file
|
||||||
Lock()
|
Lock()
|
||||||
|
|
||||||
// Acquire a writer lock recursively, allowing for recursive acquisitions
|
|
||||||
// within the same process space.
|
|
||||||
RecursiveLock()
|
|
||||||
|
|
||||||
// Unlock the lock.
|
// Unlock the lock.
|
||||||
// The default unix implementation panics if:
|
// The default unix implementation panics if:
|
||||||
// - unlocking an unlocked lock
|
// - unlocking an unlocked lock
|
||||||
|
29
vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go
generated
vendored
29
vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go
generated
vendored
@ -30,7 +30,6 @@ type lockfile struct {
|
|||||||
locktype int16
|
locktype int16
|
||||||
locked bool
|
locked bool
|
||||||
ro bool
|
ro bool
|
||||||
recursive bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const lastWriterIDSize = 64 // This must be the same as len(stringid.GenerateRandomID)
|
const lastWriterIDSize = 64 // This must be the same as len(stringid.GenerateRandomID)
|
||||||
@ -131,7 +130,7 @@ func createLockerForPath(path string, ro bool) (Locker, error) {
|
|||||||
|
|
||||||
// lock locks the lockfile via FCTNL(2) based on the specified type and
|
// lock locks the lockfile via FCTNL(2) based on the specified type and
|
||||||
// command.
|
// command.
|
||||||
func (l *lockfile) lock(lType int16, recursive bool) {
|
func (l *lockfile) lock(lType int16) {
|
||||||
lk := unix.Flock_t{
|
lk := unix.Flock_t{
|
||||||
Type: lType,
|
Type: lType,
|
||||||
Whence: int16(os.SEEK_SET),
|
Whence: int16(os.SEEK_SET),
|
||||||
@ -142,13 +141,7 @@ func (l *lockfile) lock(lType int16, recursive bool) {
|
|||||||
case unix.F_RDLCK:
|
case unix.F_RDLCK:
|
||||||
l.rwMutex.RLock()
|
l.rwMutex.RLock()
|
||||||
case unix.F_WRLCK:
|
case unix.F_WRLCK:
|
||||||
if recursive {
|
l.rwMutex.Lock()
|
||||||
// NOTE: that's okay as recursive is only set in RecursiveLock(), so
|
|
||||||
// there's no need to protect against hypothetical RDLCK cases.
|
|
||||||
l.rwMutex.RLock()
|
|
||||||
} else {
|
|
||||||
l.rwMutex.Lock()
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("attempted to acquire a file lock of unrecognized type %d", lType))
|
panic(fmt.Sprintf("attempted to acquire a file lock of unrecognized type %d", lType))
|
||||||
}
|
}
|
||||||
@ -171,7 +164,6 @@ func (l *lockfile) lock(lType int16, recursive bool) {
|
|||||||
}
|
}
|
||||||
l.locktype = lType
|
l.locktype = lType
|
||||||
l.locked = true
|
l.locked = true
|
||||||
l.recursive = recursive
|
|
||||||
l.counter++
|
l.counter++
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,24 +172,13 @@ func (l *lockfile) Lock() {
|
|||||||
if l.ro {
|
if l.ro {
|
||||||
panic("can't take write lock on read-only lock file")
|
panic("can't take write lock on read-only lock file")
|
||||||
} else {
|
} else {
|
||||||
l.lock(unix.F_WRLCK, false)
|
l.lock(unix.F_WRLCK)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RecursiveLock locks the lockfile as a writer but allows for recursive
|
|
||||||
// acquisitions within the same process space. Note that RLock() will be called
|
|
||||||
// if it's a lockTypReader lock.
|
|
||||||
func (l *lockfile) RecursiveLock() {
|
|
||||||
if l.ro {
|
|
||||||
l.RLock()
|
|
||||||
} else {
|
|
||||||
l.lock(unix.F_WRLCK, true)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// LockRead locks the lockfile as a reader.
|
// LockRead locks the lockfile as a reader.
|
||||||
func (l *lockfile) RLock() {
|
func (l *lockfile) RLock() {
|
||||||
l.lock(unix.F_RDLCK, false)
|
l.lock(unix.F_RDLCK)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unlock unlocks the lockfile.
|
// Unlock unlocks the lockfile.
|
||||||
@ -224,7 +205,7 @@ func (l *lockfile) Unlock() {
|
|||||||
// file lock.
|
// file lock.
|
||||||
unix.Close(int(l.fd))
|
unix.Close(int(l.fd))
|
||||||
}
|
}
|
||||||
if l.locktype == unix.F_RDLCK || l.recursive {
|
if l.locktype == unix.F_RDLCK {
|
||||||
l.rwMutex.RUnlock()
|
l.rwMutex.RUnlock()
|
||||||
} else {
|
} else {
|
||||||
l.rwMutex.Unlock()
|
l.rwMutex.Unlock()
|
||||||
|
7
vendor/github.com/containers/storage/pkg/lockfile/lockfile_windows.go
generated
vendored
7
vendor/github.com/containers/storage/pkg/lockfile/lockfile_windows.go
generated
vendored
@ -1,3 +1,4 @@
|
|||||||
|
//go:build windows
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
package lockfile
|
package lockfile
|
||||||
@ -36,12 +37,6 @@ func (l *lockfile) Lock() {
|
|||||||
l.locked = true
|
l.locked = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *lockfile) RecursiveLock() {
|
|
||||||
// We don't support Windows but a recursive writer-lock in one process-space
|
|
||||||
// is really a writer lock, so just panic.
|
|
||||||
panic("not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *lockfile) RLock() {
|
func (l *lockfile) RLock() {
|
||||||
l.mu.Lock()
|
l.mu.Lock()
|
||||||
l.locked = true
|
l.locked = true
|
||||||
|
28
vendor/github.com/containers/storage/pkg/mount/unmount_unix.go
generated
vendored
28
vendor/github.com/containers/storage/pkg/mount/unmount_unix.go
generated
vendored
@ -1,16 +1,30 @@
|
|||||||
|
//go:build !windows
|
||||||
// +build !windows
|
// +build !windows
|
||||||
|
|
||||||
package mount
|
package mount
|
||||||
|
|
||||||
import "golang.org/x/sys/unix"
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
func unmount(target string, flags int) error {
|
func unmount(target string, flags int) error {
|
||||||
err := unix.Unmount(target, flags)
|
var err error
|
||||||
if err == nil || err == unix.EINVAL {
|
for i := 0; i < 50; i++ {
|
||||||
// Ignore "not mounted" error here. Note the same error
|
err = unix.Unmount(target, flags)
|
||||||
// can be returned if flags are invalid, so this code
|
switch err {
|
||||||
// assumes that the flags value is always correct.
|
case unix.EBUSY:
|
||||||
return nil
|
time.Sleep(50 * time.Millisecond)
|
||||||
|
continue
|
||||||
|
case unix.EINVAL, nil:
|
||||||
|
// Ignore "not mounted" error here. Note the same error
|
||||||
|
// can be returned if flags are invalid, so this code
|
||||||
|
// assumes that the flags value is always correct.
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &mountError{
|
return &mountError{
|
||||||
|
2
vendor/github.com/containers/storage/pkg/parsers/kernel/kernel_darwin.go
generated
vendored
2
vendor/github.com/containers/storage/pkg/parsers/kernel/kernel_darwin.go
generated
vendored
@ -43,7 +43,7 @@ func getRelease() (string, error) {
|
|||||||
|
|
||||||
prettyNames, err := shellwords.Parse(content[1])
|
prettyNames, err := shellwords.Parse(content[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("kernel version is invalid: %s", err.Error())
|
return "", fmt.Errorf("kernel version is invalid: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(prettyNames) != 2 {
|
if len(prettyNames) != 2 {
|
||||||
|
2
vendor/github.com/containers/storage/pkg/system/init.go
generated
vendored
2
vendor/github.com/containers/storage/pkg/system/init.go
generated
vendored
@ -6,7 +6,7 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Used by chtimes
|
// maxTime is used by chtimes.
|
||||||
var maxTime time.Time
|
var maxTime time.Time
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
3
vendor/github.com/containers/storage/pkg/system/rm.go
generated
vendored
3
vendor/github.com/containers/storage/pkg/system/rm.go
generated
vendored
@ -3,7 +3,6 @@ package system
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"syscall"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containers/storage/pkg/mount"
|
"github.com/containers/storage/pkg/mount"
|
||||||
@ -65,7 +64,7 @@ func EnsureRemoveAll(dir string) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if pe.Err != syscall.EBUSY {
|
if !IsEBUSY(pe.Err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
8
vendor/github.com/containers/storage/pkg/truncindex/truncindex.go
generated
vendored
8
vendor/github.com/containers/storage/pkg/truncindex/truncindex.go
generated
vendored
@ -25,7 +25,7 @@ var (
|
|||||||
|
|
||||||
// ErrAmbiguousPrefix is returned if the prefix was ambiguous
|
// ErrAmbiguousPrefix is returned if the prefix was ambiguous
|
||||||
// (multiple ids for the prefix).
|
// (multiple ids for the prefix).
|
||||||
type ErrAmbiguousPrefix struct {
|
type ErrAmbiguousPrefix struct { //nolint: errname
|
||||||
prefix string
|
prefix string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,6 +42,7 @@ type TruncIndex struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewTruncIndex creates a new TruncIndex and initializes with a list of IDs.
|
// NewTruncIndex creates a new TruncIndex and initializes with a list of IDs.
|
||||||
|
// Invalid IDs are _silently_ ignored.
|
||||||
func NewTruncIndex(ids []string) (idx *TruncIndex) {
|
func NewTruncIndex(ids []string) (idx *TruncIndex) {
|
||||||
idx = &TruncIndex{
|
idx = &TruncIndex{
|
||||||
ids: make(map[string]struct{}),
|
ids: make(map[string]struct{}),
|
||||||
@ -51,7 +52,7 @@ func NewTruncIndex(ids []string) (idx *TruncIndex) {
|
|||||||
trie: patricia.NewTrie(patricia.MaxPrefixPerNode(64)),
|
trie: patricia.NewTrie(patricia.MaxPrefixPerNode(64)),
|
||||||
}
|
}
|
||||||
for _, id := range ids {
|
for _, id := range ids {
|
||||||
idx.addID(id)
|
_ = idx.addID(id) // Ignore invalid IDs. Duplicate IDs are not a problem.
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -132,7 +133,8 @@ func (idx *TruncIndex) Get(s string) (string, error) {
|
|||||||
func (idx *TruncIndex) Iterate(handler func(id string)) {
|
func (idx *TruncIndex) Iterate(handler func(id string)) {
|
||||||
idx.Lock()
|
idx.Lock()
|
||||||
defer idx.Unlock()
|
defer idx.Unlock()
|
||||||
idx.trie.Visit(func(prefix patricia.Prefix, item patricia.Item) error {
|
// Ignore the error from Visit: it can only fail if the provided visitor fails, and ours never does.
|
||||||
|
_ = idx.trie.Visit(func(prefix patricia.Prefix, item patricia.Item) error {
|
||||||
handler(string(prefix))
|
handler(string(prefix))
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
732
vendor/github.com/containers/storage/store.go
generated
vendored
732
vendor/github.com/containers/storage/store.go
generated
vendored
File diff suppressed because it is too large
Load Diff
4
vendor/github.com/containers/storage/types/options.go
generated
vendored
4
vendor/github.com/containers/storage/types/options.go
generated
vendored
@ -336,7 +336,7 @@ func ReloadConfigurationFile(configFile string, storeOptions *StoreOptions) erro
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if !os.IsNotExist(err) {
|
if !os.IsNotExist(err) {
|
||||||
fmt.Printf("Failed to read %s %v\n", configFile, err.Error())
|
logrus.Warningf("Failed to read %s %v\n", configFile, err.Error())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -399,7 +399,7 @@ func ReloadConfigurationFile(configFile string, storeOptions *StoreOptions) erro
|
|||||||
if config.Storage.Options.RemapUser != "" && config.Storage.Options.RemapGroup != "" {
|
if config.Storage.Options.RemapUser != "" && config.Storage.Options.RemapGroup != "" {
|
||||||
mappings, err := idtools.NewIDMappings(config.Storage.Options.RemapUser, config.Storage.Options.RemapGroup)
|
mappings, err := idtools.NewIDMappings(config.Storage.Options.RemapUser, config.Storage.Options.RemapGroup)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error initializing ID mappings for %s:%s %v\n", config.Storage.Options.RemapUser, config.Storage.Options.RemapGroup, err)
|
logrus.Warningf("Error initializing ID mappings for %s:%s %v\n", config.Storage.Options.RemapUser, config.Storage.Options.RemapGroup, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
storeOptions.UIDMap = mappings.UIDs()
|
storeOptions.UIDMap = mappings.UIDs()
|
||||||
|
2
vendor/github.com/containers/storage/types/utils.go
generated
vendored
2
vendor/github.com/containers/storage/types/utils.go
generated
vendored
@ -193,7 +193,7 @@ func reloadConfigurationFileIfNeeded(configFile string, storeOptions *StoreOptio
|
|||||||
fi, err := os.Stat(configFile)
|
fi, err := os.Stat(configFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !os.IsNotExist(err) {
|
if !os.IsNotExist(err) {
|
||||||
fmt.Printf("Failed to read %s %v\n", configFile, err.Error())
|
logrus.Warningf("Failed to read %s %v\n", configFile, err.Error())
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
32
vendor/github.com/containers/storage/userns.go
generated
vendored
32
vendor/github.com/containers/storage/userns.go
generated
vendored
@ -124,12 +124,8 @@ func parseMountedFiles(containerMount, passwdFile, groupFile string) uint32 {
|
|||||||
|
|
||||||
// getMaxSizeFromImage returns the maximum ID used by the specified image.
|
// getMaxSizeFromImage returns the maximum ID used by the specified image.
|
||||||
// The layer stores must be already locked.
|
// The layer stores must be already locked.
|
||||||
func (s *store) getMaxSizeFromImage(image *Image, passwdFile, groupFile string) (uint32, error) {
|
func (s *store) getMaxSizeFromImage(image *Image, passwdFile, groupFile string) (_ uint32, retErr error) {
|
||||||
lstore, err := s.LayerStore()
|
layerStores, err := s.allLayerStores()
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
lstores, err := s.ROLayerStores()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@ -140,7 +136,7 @@ func (s *store) getMaxSizeFromImage(image *Image, passwdFile, groupFile string)
|
|||||||
layerName := image.TopLayer
|
layerName := image.TopLayer
|
||||||
outer:
|
outer:
|
||||||
for {
|
for {
|
||||||
for _, ls := range append([]ROLayerStore{lstore}, lstores...) {
|
for _, ls := range layerStores {
|
||||||
layer, err := ls.Get(layerName)
|
layer, err := ls.Get(layerName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
@ -167,7 +163,7 @@ outer:
|
|||||||
return 0, fmt.Errorf("cannot find layer %q", layerName)
|
return 0, fmt.Errorf("cannot find layer %q", layerName)
|
||||||
}
|
}
|
||||||
|
|
||||||
rlstore, err := s.LayerStore()
|
rlstore, err := s.getLayerStore()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@ -187,7 +183,15 @@ outer:
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
defer rlstore.Delete(clayer.ID)
|
defer func() {
|
||||||
|
if err2 := rlstore.Delete(clayer.ID); err2 != nil {
|
||||||
|
if retErr == nil {
|
||||||
|
retErr = fmt.Errorf("deleting temporary layer %#v: %w", clayer.ID, err2)
|
||||||
|
} else {
|
||||||
|
logrus.Errorf("Error deleting temporary layer %#v: %v", clayer.ID, err2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
mountOptions := drivers.MountOpts{
|
mountOptions := drivers.MountOpts{
|
||||||
MountLabel: "",
|
MountLabel: "",
|
||||||
@ -200,7 +204,15 @@ outer:
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
defer rlstore.Unmount(clayer.ID, true)
|
defer func() {
|
||||||
|
if _, err2 := rlstore.Unmount(clayer.ID, true); err2 != nil {
|
||||||
|
if retErr == nil {
|
||||||
|
retErr = fmt.Errorf("unmounting temporary layer %#v: %w", clayer.ID, err2)
|
||||||
|
} else {
|
||||||
|
logrus.Errorf("Error unmounting temporary layer %#v: %v", clayer.ID, err2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
userFilesSize := parseMountedFiles(mountpoint, passwdFile, groupFile)
|
userFilesSize := parseMountedFiles(mountpoint, passwdFile, groupFile)
|
||||||
if userFilesSize > size {
|
if userFilesSize > size {
|
||||||
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@ -266,7 +266,7 @@ github.com/containers/psgo/internal/dev
|
|||||||
github.com/containers/psgo/internal/host
|
github.com/containers/psgo/internal/host
|
||||||
github.com/containers/psgo/internal/proc
|
github.com/containers/psgo/internal/proc
|
||||||
github.com/containers/psgo/internal/process
|
github.com/containers/psgo/internal/process
|
||||||
# github.com/containers/storage v1.43.0
|
# github.com/containers/storage v1.43.1-0.20221013143630-714f4fc6e80e
|
||||||
## explicit; go 1.16
|
## explicit; go 1.16
|
||||||
github.com/containers/storage
|
github.com/containers/storage
|
||||||
github.com/containers/storage/drivers
|
github.com/containers/storage/drivers
|
||||||
|
Reference in New Issue
Block a user