mirror of
https://github.com/containers/skopeo.git
synced 2025-09-21 09:57:19 +00:00
Update module github.com/containers/storage to v1.46.1
Signed-off-by: Renovate Bot <bot@renovateapp.com>
This commit is contained in:
2
vendor/github.com/containers/storage/.cirrus.yml
generated
vendored
2
vendor/github.com/containers/storage/.cirrus.yml
generated
vendored
@@ -23,7 +23,7 @@ env:
|
||||
# GCE project where images live
|
||||
IMAGE_PROJECT: "libpod-218412"
|
||||
# VM Image built in containers/automation_images
|
||||
IMAGE_SUFFIX: "c20230330t153101z-f37f36d12"
|
||||
IMAGE_SUFFIX: "c20230405t152256z-f37f36d12"
|
||||
FEDORA_CACHE_IMAGE_NAME: "fedora-${IMAGE_SUFFIX}"
|
||||
DEBIAN_CACHE_IMAGE_NAME: "debian-${IMAGE_SUFFIX}"
|
||||
|
||||
|
2
vendor/github.com/containers/storage/VERSION
generated
vendored
2
vendor/github.com/containers/storage/VERSION
generated
vendored
@@ -1 +1 @@
|
||||
1.46.0
|
||||
1.46.1
|
||||
|
2
vendor/github.com/containers/storage/containers.go
generated
vendored
2
vendor/github.com/containers/storage/containers.go
generated
vendored
@@ -666,7 +666,7 @@ func (r *containerStore) create(id string, names []string, image, layer string,
|
||||
if _, idInUse := r.byid[id]; idInUse {
|
||||
return nil, ErrDuplicateID
|
||||
}
|
||||
names = dedupeNames(names)
|
||||
names = dedupeStrings(names)
|
||||
for _, name := range names {
|
||||
if _, nameInUse := r.byname[name]; nameInUse {
|
||||
return nil, fmt.Errorf("the container name %q is already in use by %s. You have to remove that container to be able to reuse that name: %w", name, r.byname[name].ID, ErrDuplicateName)
|
||||
|
6
vendor/github.com/containers/storage/images.go
generated
vendored
6
vendor/github.com/containers/storage/images.go
generated
vendored
@@ -703,7 +703,7 @@ func (r *imageStore) create(id string, names []string, layer string, options Ima
|
||||
if _, idInUse := r.byid[id]; idInUse {
|
||||
return nil, fmt.Errorf("an image with ID %q already exists: %w", id, ErrDuplicateID)
|
||||
}
|
||||
names = dedupeNames(names)
|
||||
names = dedupeStrings(names)
|
||||
for _, name := range names {
|
||||
if image, nameInUse := r.byname[name]; nameInUse {
|
||||
return nil, fmt.Errorf("image name %q is already associated with image %q: %w", name, image.ID, ErrDuplicateName)
|
||||
@@ -712,7 +712,7 @@ func (r *imageStore) create(id string, names []string, layer string, options Ima
|
||||
image = &Image{
|
||||
ID: id,
|
||||
Digest: options.Digest,
|
||||
Digests: copyDigestSlice(options.Digests),
|
||||
Digests: dedupeDigests(options.Digests),
|
||||
Names: names,
|
||||
NamesHistory: copyStringSlice(options.NamesHistory),
|
||||
TopLayer: layer,
|
||||
@@ -820,7 +820,7 @@ func (r *imageStore) removeName(image *Image, name string) {
|
||||
|
||||
// The caller must hold r.inProcessLock for writing.
|
||||
func (i *Image) addNameToHistory(name string) {
|
||||
i.NamesHistory = dedupeNames(append([]string{name}, i.NamesHistory...))
|
||||
i.NamesHistory = dedupeStrings(append([]string{name}, i.NamesHistory...))
|
||||
}
|
||||
|
||||
// Requires startWriting.
|
||||
|
2
vendor/github.com/containers/storage/layers.go
generated
vendored
2
vendor/github.com/containers/storage/layers.go
generated
vendored
@@ -1230,7 +1230,7 @@ func (r *layerStore) create(id string, parentLayer *Layer, names []string, mount
|
||||
if duplicateLayer, idInUse := r.byid[id]; idInUse {
|
||||
return duplicateLayer, -1, ErrDuplicateID
|
||||
}
|
||||
names = dedupeNames(names)
|
||||
names = dedupeStrings(names)
|
||||
for _, name := range names {
|
||||
if _, nameInUse := r.byname[name]; nameInUse {
|
||||
return nil, -1, ErrDuplicateName
|
||||
|
136
vendor/github.com/containers/storage/pkg/ioutils/fswriters.go
generated
vendored
136
vendor/github.com/containers/storage/pkg/ioutils/fswriters.go
generated
vendored
@@ -17,6 +17,20 @@ type AtomicFileWriterOptions struct {
|
||||
// On successful return from Close() this is set to the mtime of the
|
||||
// newly written file.
|
||||
ModTime time.Time
|
||||
// Specifies whether Commit() must be explicitly called to write state
|
||||
// to the destination. This allows an application to preserve the original
|
||||
// file when an error occurs during processing (and not just during write)
|
||||
// The default is false, which will auto-commit on Close
|
||||
ExplicitCommit bool
|
||||
}
|
||||
|
||||
type CommittableWriter interface {
|
||||
io.WriteCloser
|
||||
|
||||
// Commit closes the temporary file associated with this writer, and
|
||||
// provided no errors (during commit or previously during write operations),
|
||||
// will publish the completed file under the intended destination.
|
||||
Commit() error
|
||||
}
|
||||
|
||||
var defaultWriterOptions = AtomicFileWriterOptions{}
|
||||
@@ -27,16 +41,19 @@ func SetDefaultOptions(opts AtomicFileWriterOptions) {
|
||||
defaultWriterOptions = opts
|
||||
}
|
||||
|
||||
// NewAtomicFileWriterWithOpts 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 NewAtomicFileWriterWithOpts(filename string, perm os.FileMode, opts *AtomicFileWriterOptions) (io.WriteCloser, error) {
|
||||
// NewAtomicFileWriterWithOpts returns a CommittableWriter so that writing to it
|
||||
// writes to a temporary file, which can later be committed to a destination path,
|
||||
// either by Closing in the case of auto-commit, or manually calling commit if the
|
||||
// ExplicitCommit option is enabled. Writing and closing concurrently is not
|
||||
// allowed.
|
||||
func NewAtomicFileWriterWithOpts(filename string, perm os.FileMode, opts *AtomicFileWriterOptions) (CommittableWriter, 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.
|
||||
// newAtomicFileWriter returns a CommittableWriter so that writing to it writes to
|
||||
// a temporary file, which can later be committed to a destination path, either by
|
||||
// Closing in the case of auto-commit, or manually calling commit if the
|
||||
// ExplicitCommit option is enabled. 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))
|
||||
if err != nil {
|
||||
@@ -50,17 +67,18 @@ func newAtomicFileWriter(filename string, perm os.FileMode, opts *AtomicFileWrit
|
||||
return nil, err
|
||||
}
|
||||
return &atomicFileWriter{
|
||||
f: f,
|
||||
fn: abspath,
|
||||
perm: perm,
|
||||
noSync: opts.NoSync,
|
||||
f: f,
|
||||
fn: abspath,
|
||||
perm: perm,
|
||||
noSync: opts.NoSync,
|
||||
explicitCommit: opts.ExplicitCommit,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 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) (io.WriteCloser, error) {
|
||||
// NewAtomicFileWriterWithOpts returns a CommittableWriter, with auto-commit enabled.
|
||||
// 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) (CommittableWriter, error) {
|
||||
return NewAtomicFileWriterWithOpts(filename, perm, nil)
|
||||
}
|
||||
|
||||
@@ -91,12 +109,14 @@ func AtomicWriteFile(filename string, data []byte, perm os.FileMode) error {
|
||||
}
|
||||
|
||||
type atomicFileWriter struct {
|
||||
f *os.File
|
||||
fn string
|
||||
writeErr error
|
||||
perm os.FileMode
|
||||
noSync bool
|
||||
modTime time.Time
|
||||
f *os.File
|
||||
fn string
|
||||
writeErr error
|
||||
perm os.FileMode
|
||||
noSync bool
|
||||
modTime time.Time
|
||||
closed bool
|
||||
explicitCommit bool
|
||||
}
|
||||
|
||||
func (w *atomicFileWriter) Write(dt []byte) (int, error) {
|
||||
@@ -107,43 +127,73 @@ func (w *atomicFileWriter) Write(dt []byte) (int, error) {
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (w *atomicFileWriter) Close() (retErr error) {
|
||||
func (w *atomicFileWriter) closeTempFile() error {
|
||||
if w.closed {
|
||||
return nil
|
||||
}
|
||||
|
||||
w.closed = true
|
||||
return w.f.Close()
|
||||
}
|
||||
|
||||
func (w *atomicFileWriter) Close() error {
|
||||
return w.complete(!w.explicitCommit)
|
||||
}
|
||||
|
||||
func (w *atomicFileWriter) Commit() error {
|
||||
return w.complete(true)
|
||||
}
|
||||
|
||||
func (w *atomicFileWriter) complete(commit bool) (retErr error) {
|
||||
if w == nil || w.closed {
|
||||
return nil
|
||||
}
|
||||
|
||||
defer func() {
|
||||
w.closeTempFile()
|
||||
if retErr != nil || w.writeErr != nil {
|
||||
os.Remove(w.f.Name())
|
||||
}
|
||||
}()
|
||||
if !w.noSync {
|
||||
if err := fdatasync(w.f); err != nil {
|
||||
w.f.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
if commit {
|
||||
return w.commitState()
|
||||
}
|
||||
|
||||
// fstat before closing the fd
|
||||
info, statErr := w.f.Stat()
|
||||
if statErr == nil {
|
||||
w.modTime = info.ModTime()
|
||||
}
|
||||
// We delay error reporting until after the real call to close()
|
||||
// to match the traditional linux close() behaviour that an fd
|
||||
// is invalid (closed) even if close returns failure. While
|
||||
// weird, this allows a well defined way to not leak open fds.
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := w.f.Close(); err != nil {
|
||||
func (w *atomicFileWriter) commitState() error {
|
||||
// Perform a data only sync (fdatasync()) if supported
|
||||
if err := w.postDataWrittenSync(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if statErr != nil {
|
||||
return statErr
|
||||
}
|
||||
|
||||
if err := os.Chmod(w.f.Name(), w.perm); err != nil {
|
||||
// Capture fstat before closing the fd
|
||||
info, err := w.f.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
w.modTime = info.ModTime()
|
||||
|
||||
if err := w.f.Chmod(w.perm); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Perform full sync on platforms that need it
|
||||
if err := w.preRenameSync(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Some platforms require closing before rename (Windows)
|
||||
if err := w.closeTempFile(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if w.writeErr == nil {
|
||||
return os.Rename(w.f.Name(), w.fn)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -195,7 +245,7 @@ func (w syncFileCloser) Close() error {
|
||||
if !defaultWriterOptions.NoSync {
|
||||
return w.File.Close()
|
||||
}
|
||||
err := fdatasync(w.File)
|
||||
err := dataOrFullSync(w.File)
|
||||
if err1 := w.File.Close(); err == nil {
|
||||
err = err1
|
||||
}
|
||||
|
14
vendor/github.com/containers/storage/pkg/ioutils/fswriters_linux.go
generated
vendored
14
vendor/github.com/containers/storage/pkg/ioutils/fswriters_linux.go
generated
vendored
@@ -6,6 +6,18 @@ import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func fdatasync(f *os.File) error {
|
||||
func dataOrFullSync(f *os.File) error {
|
||||
return unix.Fdatasync(int(f.Fd()))
|
||||
}
|
||||
|
||||
func (w *atomicFileWriter) postDataWrittenSync() error {
|
||||
if w.noSync {
|
||||
return nil
|
||||
}
|
||||
return unix.Fdatasync(int(w.f.Fd()))
|
||||
}
|
||||
|
||||
func (w *atomicFileWriter) preRenameSync() error {
|
||||
// On Linux data can be reliably flushed to media without metadata, so defer
|
||||
return nil
|
||||
}
|
||||
|
26
vendor/github.com/containers/storage/pkg/ioutils/fswriters_other.go
generated
vendored
Normal file
26
vendor/github.com/containers/storage/pkg/ioutils/fswriters_other.go
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
//go:build !linux
|
||||
// +build !linux
|
||||
|
||||
package ioutils
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
func dataOrFullSync(f *os.File) error {
|
||||
return f.Sync()
|
||||
}
|
||||
|
||||
func (w *atomicFileWriter) postDataWrittenSync() error {
|
||||
// many platforms (Mac, Windows) require a full sync to reliably flush to media
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *atomicFileWriter) preRenameSync() error {
|
||||
if w.noSync {
|
||||
return nil
|
||||
}
|
||||
|
||||
// fsync() on Non-linux Unix, FlushFileBuffers (Windows), F_FULLFSYNC (Mac)
|
||||
return w.f.Sync()
|
||||
}
|
12
vendor/github.com/containers/storage/pkg/ioutils/fswriters_unsupported.go
generated
vendored
12
vendor/github.com/containers/storage/pkg/ioutils/fswriters_unsupported.go
generated
vendored
@@ -1,12 +0,0 @@
|
||||
//go:build !linux
|
||||
// +build !linux
|
||||
|
||||
package ioutils
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
func fdatasync(f *os.File) error {
|
||||
return f.Sync()
|
||||
}
|
117
vendor/github.com/containers/storage/store.go
generated
vendored
117
vendor/github.com/containers/storage/store.go
generated
vendored
@@ -1384,26 +1384,90 @@ func (s *store) CreateImage(id string, names []string, layer, metadata string, i
|
||||
layer = ilayer.ID
|
||||
}
|
||||
|
||||
var res *Image
|
||||
err := s.writeToImageStore(func() error {
|
||||
var options ImageOptions
|
||||
var options ImageOptions
|
||||
var namesToAddAfterCreating []string
|
||||
|
||||
if iOptions != nil {
|
||||
options = *iOptions
|
||||
options.Digests = copyDigestSlice(iOptions.Digests)
|
||||
options.BigData = copyImageBigDataOptionSlice(iOptions.BigData)
|
||||
options.NamesHistory = copyStringSlice(iOptions.NamesHistory)
|
||||
options.Flags = copyStringInterfaceMap(iOptions.Flags)
|
||||
if err := s.imageStore.startWriting(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer s.imageStore.stopWriting()
|
||||
|
||||
// Check if the ID refers to an image in a read-only store -- we want
|
||||
// to allow images in read-only stores to have their names changed, so
|
||||
// if we find one, merge the new values in with what we know about the
|
||||
// image that's already there.
|
||||
if id != "" {
|
||||
for _, is := range s.roImageStores {
|
||||
store := is
|
||||
if err := store.startReading(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer store.stopReading()
|
||||
if i, err := store.Get(id); err == nil {
|
||||
// set information about this image in "options"
|
||||
options = ImageOptions{
|
||||
Metadata: i.Metadata,
|
||||
CreationDate: i.Created,
|
||||
Digest: i.Digest,
|
||||
Digests: copyDigestSlice(i.Digests),
|
||||
NamesHistory: copyStringSlice(i.NamesHistory),
|
||||
}
|
||||
for _, key := range i.BigDataNames {
|
||||
data, err := store.BigData(id, key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dataDigest, err := store.BigDataDigest(id, key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
options.BigData = append(options.BigData, ImageBigDataOption{
|
||||
Key: key,
|
||||
Data: data,
|
||||
Digest: dataDigest,
|
||||
})
|
||||
}
|
||||
namesToAddAfterCreating = dedupeStrings(append(append([]string{}, i.Names...), names...))
|
||||
break
|
||||
}
|
||||
}
|
||||
if options.CreationDate.IsZero() {
|
||||
options.CreationDate = time.Now().UTC()
|
||||
}
|
||||
|
||||
// merge any passed-in options into "options" as best we can
|
||||
if iOptions != nil {
|
||||
if !iOptions.CreationDate.IsZero() {
|
||||
options.CreationDate = iOptions.CreationDate
|
||||
}
|
||||
if iOptions.Digest != "" {
|
||||
options.Digest = iOptions.Digest
|
||||
}
|
||||
options.Digests = append(options.Digests, copyDigestSlice(iOptions.Digests)...)
|
||||
if iOptions.Metadata != "" {
|
||||
options.Metadata = iOptions.Metadata
|
||||
}
|
||||
options.BigData = append(options.BigData, copyImageBigDataOptionSlice(iOptions.BigData)...)
|
||||
options.NamesHistory = append(options.NamesHistory, copyStringSlice(iOptions.NamesHistory)...)
|
||||
if options.Flags == nil {
|
||||
options.Flags = make(map[string]interface{})
|
||||
}
|
||||
for k, v := range iOptions.Flags {
|
||||
options.Flags[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
if options.CreationDate.IsZero() {
|
||||
options.CreationDate = time.Now().UTC()
|
||||
}
|
||||
if metadata != "" {
|
||||
options.Metadata = metadata
|
||||
}
|
||||
|
||||
var err error
|
||||
res, err = s.imageStore.create(id, names, layer, options)
|
||||
return err
|
||||
})
|
||||
res, err := s.imageStore.create(id, names, layer, options)
|
||||
if err == nil && len(namesToAddAfterCreating) > 0 {
|
||||
// set any names we pulled up from an additional image store, now that we won't be
|
||||
// triggering a duplicate names error
|
||||
err = s.imageStore.updateNames(res.ID, namesToAddAfterCreating, addNames)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -2130,18 +2194,30 @@ func (s *store) Exists(id string) bool {
|
||||
return s.containerStore.Exists(id)
|
||||
}
|
||||
|
||||
func dedupeNames(names []string) []string {
|
||||
seen := make(map[string]bool)
|
||||
func dedupeStrings(names []string) []string {
|
||||
seen := make(map[string]struct{})
|
||||
deduped := make([]string, 0, len(names))
|
||||
for _, name := range names {
|
||||
if _, wasSeen := seen[name]; !wasSeen {
|
||||
seen[name] = true
|
||||
seen[name] = struct{}{}
|
||||
deduped = append(deduped, name)
|
||||
}
|
||||
}
|
||||
return deduped
|
||||
}
|
||||
|
||||
func dedupeDigests(digests []digest.Digest) []digest.Digest {
|
||||
seen := make(map[digest.Digest]struct{})
|
||||
deduped := make([]digest.Digest, 0, len(digests))
|
||||
for _, d := range digests {
|
||||
if _, wasSeen := seen[d]; !wasSeen {
|
||||
seen[d] = struct{}{}
|
||||
deduped = append(deduped, d)
|
||||
}
|
||||
}
|
||||
return deduped
|
||||
}
|
||||
|
||||
// Deprecated: Prone to race conditions, suggested alternatives are `AddNames` and `RemoveNames`.
|
||||
func (s *store) SetNames(id string, names []string) error {
|
||||
return s.updateNames(id, names, setNames)
|
||||
@@ -2156,7 +2232,7 @@ func (s *store) RemoveNames(id string, names []string) error {
|
||||
}
|
||||
|
||||
func (s *store) updateNames(id string, names []string, op updateNameOperation) error {
|
||||
deduped := dedupeNames(names)
|
||||
deduped := dedupeStrings(names)
|
||||
|
||||
layerFound := false
|
||||
if err := s.writeToLayerStore(func(rlstore rwLayerStore) error {
|
||||
@@ -2188,11 +2264,12 @@ func (s *store) updateNames(id string, names []string, op updateNameOperation) e
|
||||
if i, err := store.Get(id); err == nil {
|
||||
// "pull up" the image so that we can change its names list
|
||||
options := ImageOptions{
|
||||
Metadata: i.Metadata,
|
||||
CreationDate: i.Created,
|
||||
Digest: i.Digest,
|
||||
Digests: copyDigestSlice(i.Digests),
|
||||
Metadata: i.Metadata,
|
||||
NamesHistory: copyStringSlice(i.NamesHistory),
|
||||
Flags: copyStringInterfaceMap(i.Flags),
|
||||
}
|
||||
for _, key := range i.BigDataNames {
|
||||
data, err := store.BigData(id, key)
|
||||
|
2
vendor/github.com/containers/storage/utils.go
generated
vendored
2
vendor/github.com/containers/storage/utils.go
generated
vendored
@@ -70,5 +70,5 @@ func applyNameOperation(oldNames []string, opParameters []string, op updateNameO
|
||||
default:
|
||||
return result, errInvalidUpdateNameOperation
|
||||
}
|
||||
return dedupeNames(result), nil
|
||||
return dedupeStrings(result), nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user