Bump github.com/containers/image/v5 from 5.12.0 to 5.13.1

Bumps [github.com/containers/image/v5](https://github.com/containers/image) from 5.12.0 to 5.13.1.
- [Release notes](https://github.com/containers/image/releases)
- [Commits](https://github.com/containers/image/compare/v5.12.0...v5.13.1)

---
updated-dependencies:
- dependency-name: github.com/containers/image/v5
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
dependabot[bot]
2021-06-16 15:34:27 +00:00
committed by GitHub
parent 513a524d7d
commit abdc4a7e42
173 changed files with 4109 additions and 12689 deletions

View File

@@ -29,10 +29,10 @@ import (
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/vbauerster/mpb/v6"
"github.com/vbauerster/mpb/v6/decor"
"golang.org/x/crypto/ssh/terminal"
"github.com/vbauerster/mpb/v7"
"github.com/vbauerster/mpb/v7/decor"
"golang.org/x/sync/semaphore"
"golang.org/x/term"
)
type digestingReader struct {
@@ -43,10 +43,6 @@ type digestingReader struct {
validationSucceeded bool
}
// FIXME: disable early layer commits temporarily until a solid solution to
// address #1205 has been found.
const enableEarlyCommit = false
var (
// ErrDecryptParamsMissing is returned if there is missing decryption parameters
ErrDecryptParamsMissing = errors.New("Necessary DecryptParameters not present")
@@ -864,7 +860,7 @@ func (ic *imageCopier) noPendingManifestUpdates() bool {
// isTTY returns true if the io.Writer is a file and a tty.
func isTTY(w io.Writer) bool {
if f, ok := w.(*os.File); ok {
return terminal.IsTerminal(int(f.Fd()))
return term.IsTerminal(int(f.Fd()))
}
return false
}
@@ -893,6 +889,18 @@ func (ic *imageCopier) copyLayers(ctx context.Context) error {
err error
}
// The manifest is used to extract the information whether a given
// layer is empty.
manifestBlob, manifestType, err := ic.src.Manifest(ctx)
if err != nil {
return err
}
man, err := manifest.FromBlob(manifestBlob, manifestType)
if err != nil {
return err
}
manifestLayerInfos := man.LayerInfos()
// copyGroup is used to determine if all layers are copied
copyGroup := sync.WaitGroup{}
@@ -925,7 +933,7 @@ func (ic *imageCopier) copyLayers(ctx context.Context) error {
logrus.Debugf("Skipping foreign layer %q copy to %s", cld.destInfo.Digest, ic.c.dest.Reference().Transport().Name())
}
} else {
cld.destInfo, cld.diffID, cld.err = ic.copyLayer(ctx, srcLayer, toEncrypt, pool, index, srcRef)
cld.destInfo, cld.diffID, cld.err = ic.copyLayer(ctx, srcLayer, toEncrypt, pool, index, srcRef, manifestLayerInfos[index].EmptyLayer)
}
data[index] = cld
}
@@ -1094,8 +1102,9 @@ func (c *copier) createProgressBar(pool *mpb.Progress, info types.BlobInfo, kind
),
)
} else {
sstyle := mpb.SpinnerStyle(".", "..", "...", "....", "").PositionLeft()
bar = pool.Add(0,
mpb.NewSpinnerFiller([]string{".", "..", "...", "....", ""}, mpb.SpinnerOnLeft),
sstyle.Build(),
mpb.BarFillerClearOnComplete(),
mpb.PrependDecorators(
decor.OnComplete(decor.Name(prefix), onComplete),
@@ -1121,7 +1130,7 @@ func (c *copier) copyConfig(ctx context.Context, src types.Image) error {
progressPool, progressCleanup := c.newProgressPool(ctx)
defer progressCleanup()
bar := c.createProgressBar(progressPool, srcInfo, "config", "done")
destInfo, err := c.copyBlobFromStream(ctx, bytes.NewReader(configBlob), srcInfo, nil, false, true, false, bar, -1)
destInfo, err := c.copyBlobFromStream(ctx, bytes.NewReader(configBlob), srcInfo, nil, false, true, false, bar, -1, false)
if err != nil {
return types.BlobInfo{}, err
}
@@ -1148,7 +1157,7 @@ type diffIDResult struct {
// copyLayer copies a layer with srcInfo (with known Digest and Annotations and possibly known Size) in src to dest, perhaps (de/re/)compressing it,
// and returns a complete blobInfo of the copied layer, and a value for LayerDiffIDs if diffIDIsNeeded
// srcRef can be used as an additional hint to the destination during checking whehter a layer can be reused but srcRef can be nil.
func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, toEncrypt bool, pool *mpb.Progress, layerIndex int, srcRef reference.Named) (types.BlobInfo, digest.Digest, error) {
func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, toEncrypt bool, pool *mpb.Progress, layerIndex int, srcRef reference.Named, emptyLayer bool) (types.BlobInfo, digest.Digest, error) {
// If the srcInfo doesn't contain compression information, try to compute it from the
// MediaType, which was either read from a manifest by way of LayerInfos() or constructed
// by LayerInfosForCopy(), if it was supplied at all. If we succeed in copying the blob,
@@ -1195,10 +1204,9 @@ func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, to
Cache: ic.c.blobInfoCache,
CanSubstitute: ic.canSubstituteBlobs,
SrcRef: srcRef,
EmptyLayer: emptyLayer,
}
if enableEarlyCommit {
options.LayerIndex = &layerIndex
}
options.LayerIndex = &layerIndex
reused, blobInfo, err = dest.TryReusingBlobWithOptions(ctx, srcInfo, options)
} else {
reused, blobInfo, err = ic.c.dest.TryReusingBlob(ctx, srcInfo, ic.c.blobInfoCache, ic.canSubstituteBlobs)
@@ -1245,7 +1253,7 @@ func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, to
bar := ic.c.createProgressBar(pool, srcInfo, "blob", "done")
blobInfo, diffIDChan, err := ic.copyLayerFromStream(ctx, srcStream, types.BlobInfo{Digest: srcInfo.Digest, Size: srcBlobSize, MediaType: srcInfo.MediaType, Annotations: srcInfo.Annotations}, diffIDIsNeeded, toEncrypt, bar, layerIndex)
blobInfo, diffIDChan, err := ic.copyLayerFromStream(ctx, srcStream, types.BlobInfo{Digest: srcInfo.Digest, Size: srcBlobSize, MediaType: srcInfo.MediaType, Annotations: srcInfo.Annotations}, diffIDIsNeeded, toEncrypt, bar, layerIndex, emptyLayer)
if err != nil {
return types.BlobInfo{}, "", err
}
@@ -1276,7 +1284,7 @@ func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, to
// perhaps (de/re/)compressing the stream,
// and returns a complete blobInfo of the copied blob and perhaps a <-chan diffIDResult if diffIDIsNeeded, to be read by the caller.
func (ic *imageCopier) copyLayerFromStream(ctx context.Context, srcStream io.Reader, srcInfo types.BlobInfo,
diffIDIsNeeded bool, toEncrypt bool, bar *mpb.Bar, layerIndex int) (types.BlobInfo, <-chan diffIDResult, error) {
diffIDIsNeeded bool, toEncrypt bool, bar *mpb.Bar, layerIndex int, emptyLayer bool) (types.BlobInfo, <-chan diffIDResult, error) {
var getDiffIDRecorder func(compression.DecompressorFunc) io.Writer // = nil
var diffIDChan chan diffIDResult
@@ -1301,7 +1309,7 @@ func (ic *imageCopier) copyLayerFromStream(ctx context.Context, srcStream io.Rea
}
}
blobInfo, err := ic.c.copyBlobFromStream(ctx, srcStream, srcInfo, getDiffIDRecorder, ic.canModifyManifest, false, toEncrypt, bar, layerIndex) // Sets err to nil on success
blobInfo, err := ic.c.copyBlobFromStream(ctx, srcStream, srcInfo, getDiffIDRecorder, ic.canModifyManifest, false, toEncrypt, bar, layerIndex, emptyLayer) // Sets err to nil on success
return blobInfo, diffIDChan, err
// We need the defer … pipeWriter.CloseWithError() to happen HERE so that the caller can block on reading from diffIDChan
}
@@ -1353,7 +1361,7 @@ func (r errorAnnotationReader) Read(b []byte) (n int, err error) {
// and returns a complete blobInfo of the copied blob.
func (c *copier) copyBlobFromStream(ctx context.Context, srcStream io.Reader, srcInfo types.BlobInfo,
getOriginalLayerCopyWriter func(decompressor compression.DecompressorFunc) io.Writer,
canModifyBlob bool, isConfig bool, toEncrypt bool, bar *mpb.Bar, layerIndex int) (types.BlobInfo, error) {
canModifyBlob bool, isConfig bool, toEncrypt bool, bar *mpb.Bar, layerIndex int, emptyLayer bool) (types.BlobInfo, error) {
if isConfig { // This is guaranteed by the caller, but set it here to be explicit.
canModifyBlob = false
}
@@ -1556,10 +1564,11 @@ func (c *copier) copyBlobFromStream(ctx context.Context, srcStream io.Reader, sr
dest, ok := c.dest.(internalTypes.ImageDestinationWithOptions)
if ok {
options := internalTypes.PutBlobOptions{
Cache: c.blobInfoCache,
IsConfig: isConfig,
Cache: c.blobInfoCache,
IsConfig: isConfig,
EmptyLayer: emptyLayer,
}
if !isConfig && enableEarlyCommit {
if !isConfig {
options.LayerIndex = &layerIndex
}
uploadedInfo, err = dest.PutBlobWithOptions(ctx, &errorAnnotationReader{destStream}, inputInfo, options)

View File

@@ -9,7 +9,7 @@ package platform
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// https://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

View File

@@ -39,6 +39,8 @@ type PutBlobOptions struct {
Cache publicTypes.BlobInfoCache
// Denotes whether the blob is a config or not.
IsConfig bool
// Indicates an empty layer.
EmptyLayer bool
// The corresponding index in the layer slice.
LayerIndex *int
}
@@ -49,6 +51,8 @@ type TryReusingBlobOptions struct {
Cache publicTypes.BlobInfoCache
// Use an equivalent of the desired blob.
CanSubstitute bool
// Indicates an empty layer.
EmptyLayer bool
// The corresponding index in the layer slice.
LayerIndex *int
// The reference of the image that contains the target blob.

View File

@@ -51,21 +51,26 @@ var (
ErrNotSupported = errors.New("not supported")
)
// SetAuthentication stores the username and password in the credential helper or file
func SetAuthentication(sys *types.SystemContext, registry, username, password string) error {
// SetCredentials stores the username and password in the credential helper or file
// and returns path to file or helper name in format (helper:%s).
// Returns a human-redable description of the location that was updated.
// NOTE: The return value is only intended to be read by humans; its form is not an API,
// it may change (or new forms can be added) any time.
func SetCredentials(sys *types.SystemContext, registry, username, password string) (string, error) {
helpers, err := sysregistriesv2.CredentialHelpers(sys)
if err != nil {
return err
return "", err
}
// Make sure to collect all errors.
var multiErr error
for _, helper := range helpers {
var desc string
var err error
switch helper {
// Special-case the built-in helpers for auth files.
case sysregistriesv2.AuthenticationFileHelper:
err = modifyJSON(sys, func(auths *dockerConfigFile) (bool, error) {
desc, err = modifyJSON(sys, func(auths *dockerConfigFile) (bool, error) {
if ch, exists := auths.CredHelpers[registry]; exists {
return false, setAuthToCredHelper(ch, registry, username, password)
}
@@ -76,6 +81,7 @@ func SetAuthentication(sys *types.SystemContext, registry, username, password st
})
// External helpers.
default:
desc = fmt.Sprintf("credential helper: %s", helper)
err = setAuthToCredHelper(helper, registry, username, password)
}
if err != nil {
@@ -84,9 +90,15 @@ func SetAuthentication(sys *types.SystemContext, registry, username, password st
continue
}
logrus.Debugf("Stored credentials for %s in credential helper %s", registry, helper)
return nil
return desc, nil
}
return multiErr
return "", multiErr
}
// SetAuthentication stores the username and password in the credential helper or file
func SetAuthentication(sys *types.SystemContext, registry, username, password string) error {
_, err := SetCredentials(sys, registry, username, password)
return err
}
// GetAllCredentials returns the registry credentials for all registries stored
@@ -322,7 +334,7 @@ func RemoveAuthentication(sys *types.SystemContext, registry string) error {
switch helper {
// Special-case the built-in helper for auth files.
case sysregistriesv2.AuthenticationFileHelper:
err = modifyJSON(sys, func(auths *dockerConfigFile) (bool, error) {
_, err = modifyJSON(sys, func(auths *dockerConfigFile) (bool, error) {
if innerHelper, exists := auths.CredHelpers[registry]; exists {
removeFromCredHelper(innerHelper)
}
@@ -368,7 +380,7 @@ func RemoveAllAuthentication(sys *types.SystemContext) error {
switch helper {
// Special-case the built-in helper for auth files.
case sysregistriesv2.AuthenticationFileHelper:
err = modifyJSON(sys, func(auths *dockerConfigFile) (bool, error) {
_, err = modifyJSON(sys, func(auths *dockerConfigFile) (bool, error) {
for registry, helper := range auths.CredHelpers {
// Helpers in auth files are expected
// to exist, so no special treatment
@@ -493,42 +505,44 @@ func readJSONFile(path string, legacyFormat bool) (dockerConfigFile, error) {
return auths, nil
}
// modifyJSON writes to auth.json if the dockerConfigFile has been updated
func modifyJSON(sys *types.SystemContext, editor func(auths *dockerConfigFile) (bool, error)) error {
// modifyJSON finds an auth.json file, calls editor on the contents, and
// writes it back if editor returns true.
// Returns a human-redable description of the file, to be returned by SetCredentials.
func modifyJSON(sys *types.SystemContext, editor func(auths *dockerConfigFile) (bool, error)) (string, error) {
path, legacyFormat, err := getPathToAuth(sys)
if err != nil {
return err
return "", err
}
if legacyFormat {
return fmt.Errorf("writes to %s using legacy format are not supported", path)
return "", fmt.Errorf("writes to %s using legacy format are not supported", path)
}
dir := filepath.Dir(path)
if err = os.MkdirAll(dir, 0700); err != nil {
return err
return "", err
}
auths, err := readJSONFile(path, false)
if err != nil {
return errors.Wrapf(err, "error reading JSON file %q", path)
return "", errors.Wrapf(err, "error reading JSON file %q", path)
}
updated, err := editor(&auths)
if err != nil {
return errors.Wrapf(err, "error updating %q", path)
return "", errors.Wrapf(err, "error updating %q", path)
}
if updated {
newData, err := json.MarshalIndent(auths, "", "\t")
if err != nil {
return errors.Wrapf(err, "error marshaling JSON %q", path)
return "", errors.Wrapf(err, "error marshaling JSON %q", path)
}
if err = ioutil.WriteFile(path, newData, 0600); err != nil {
return errors.Wrapf(err, "error writing to file %q", path)
return "", errors.Wrapf(err, "error writing to file %q", path)
}
}
return nil
return path, nil
}
func getAuthFromCredHelper(credHelper, registry string) (types.DockerAuthConfig, error) {

View File

@@ -13,9 +13,9 @@ import (
// reenable keyring support, we should introduce a similar built-in credential
// helpers as for `sysregistriesv2.AuthenticationFileHelper`.
const keyDescribePrefix = "container-registry-login:" // nolint
const keyDescribePrefix = "container-registry-login:" //nolint:deadcode,unused
func getAuthFromKernelKeyring(registry string) (string, string, error) { // nolint
func getAuthFromKernelKeyring(registry string) (string, string, error) { //nolint:deadcode,unused
userkeyring, err := keyctl.UserKeyring()
if err != nil {
return "", "", err
@@ -35,7 +35,7 @@ func getAuthFromKernelKeyring(registry string) (string, string, error) { // noli
return parts[0], parts[1], nil
}
func deleteAuthFromKernelKeyring(registry string) error { // nolint
func deleteAuthFromKernelKeyring(registry string) error { //nolint:deadcode,unused
userkeyring, err := keyctl.UserKeyring()
if err != nil {
@@ -48,7 +48,7 @@ func deleteAuthFromKernelKeyring(registry string) error { // nolint
return key.Unlink()
}
func removeAllAuthFromKernelKeyring() error { // nolint
func removeAllAuthFromKernelKeyring() error { //nolint:deadcode,unused
keys, err := keyctl.ReadUserKeyring()
if err != nil {
return err
@@ -81,7 +81,7 @@ func removeAllAuthFromKernelKeyring() error { // nolint
return nil
}
func setAuthToKernelKeyring(registry, username, password string) error { // nolint
func setAuthToKernelKeyring(registry, username, password string) error { //nolint:deadcode,unused
keyring, err := keyctl.SessionKeyring()
if err != nil {
return err
@@ -114,6 +114,6 @@ func setAuthToKernelKeyring(registry, username, password string) error { // noli
return nil
}
func genDescription(registry string) string { // nolint
func genDescription(registry string) string { //nolint:deadcode,unused
return fmt.Sprintf("%s%s", keyDescribePrefix, registry)
}

View File

@@ -3,18 +3,18 @@
package config
func getAuthFromKernelKeyring(registry string) (string, string, error) {
func getAuthFromKernelKeyring(registry string) (string, string, error) { //nolint:deadcode,unused
return "", "", ErrNotSupported
}
func deleteAuthFromKernelKeyring(registry string) error {
func deleteAuthFromKernelKeyring(registry string) error { //nolint:deadcode,unused
return ErrNotSupported
}
func setAuthToKernelKeyring(registry, username, password string) error {
func setAuthToKernelKeyring(registry, username, password string) error { //nolint:deadcode,unused
return ErrNotSupported
}
func removeAllAuthFromKernelKeyring() error {
func removeAllAuthFromKernelKeyring() error { //nolint:deadcode,unused
return ErrNotSupported
}

View File

@@ -449,7 +449,7 @@ func (s *storageImageDestination) PutBlobWithOptions(ctx context.Context, stream
return info, nil
}
return info, s.queueOrCommit(ctx, info, *options.LayerIndex)
return info, s.queueOrCommit(ctx, info, *options.LayerIndex, options.EmptyLayer)
}
// HasThreadSafePutBlob indicates whether PutBlob can be executed concurrently.
@@ -542,7 +542,7 @@ func (s *storageImageDestination) TryReusingBlobWithOptions(ctx context.Context,
return reused, info, err
}
return reused, info, s.queueOrCommit(ctx, info, *options.LayerIndex)
return reused, info, s.queueOrCommit(ctx, info, *options.LayerIndex, options.EmptyLayer)
}
// tryReusingBlobWithSrcRef is a wrapper around TryReusingBlob.
@@ -731,7 +731,7 @@ func (s *storageImageDestination) getConfigBlob(info types.BlobInfo) ([]byte, er
// queueOrCommit queues in the specified blob to be committed to the storage.
// If no other goroutine is already committing layers, the layer and all
// subsequent layers (if already queued) will be committed to the storage.
func (s *storageImageDestination) queueOrCommit(ctx context.Context, blob types.BlobInfo, index int) error {
func (s *storageImageDestination) queueOrCommit(ctx context.Context, blob types.BlobInfo, index int, emptyLayer bool) error {
// NOTE: whenever the code below is touched, make sure that all code
// paths unlock the lock and to unlock it exactly once.
//
@@ -764,7 +764,7 @@ func (s *storageImageDestination) queueOrCommit(ctx context.Context, blob types.
s.lock.Unlock()
layerInfo := manifest.LayerInfo{
BlobInfo: *info,
EmptyLayer: info.Digest == image.GzippedEmptyLayerDigest,
EmptyLayer: emptyLayer,
}
// Note: commitLayer locks on-demand.
if err := s.commitLayer(ctx, layerInfo, index); err != nil {
@@ -1034,25 +1034,6 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t
return errors.Wrapf(err, "error saving big data %q for image %q", blob.String(), img.ID)
}
}
// Set the reference's name on the image. We don't need to worry about avoiding duplicate
// values because SetNames() will deduplicate the list that we pass to it.
if name := s.imageRef.DockerReference(); len(oldNames) > 0 || name != nil {
names := []string{}
if name != nil {
names = append(names, name.String())
}
if len(oldNames) > 0 {
names = append(names, oldNames...)
}
if err := s.imageRef.transport.store.SetNames(img.ID, names); err != nil {
if _, err2 := s.imageRef.transport.store.DeleteImage(img.ID, true); err2 != nil {
logrus.Debugf("error deleting incomplete image %q: %v", img.ID, err2)
}
logrus.Debugf("error setting names %v on image %q: %v", names, img.ID, err)
return errors.Wrapf(err, "error setting names %v on image %q", names, img.ID)
}
logrus.Debugf("set names of image %q to %v", img.ID, names)
}
// Save the unparsedToplevel's manifest.
if len(toplevelManifest) != 0 {
manifestDigest, err := manifest.Digest(toplevelManifest)
@@ -1130,6 +1111,25 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t
}
logrus.Debugf("saved image metadata %q", string(metadata))
}
// Set the reference's name on the image. We don't need to worry about avoiding duplicate
// values because SetNames() will deduplicate the list that we pass to it.
if name := s.imageRef.DockerReference(); len(oldNames) > 0 || name != nil {
names := []string{}
if name != nil {
names = append(names, name.String())
}
if len(oldNames) > 0 {
names = append(names, oldNames...)
}
if err := s.imageRef.transport.store.SetNames(img.ID, names); err != nil {
if _, err2 := s.imageRef.transport.store.DeleteImage(img.ID, true); err2 != nil {
logrus.Debugf("error deleting incomplete image %q: %v", img.ID, err2)
}
logrus.Debugf("error setting names %v on image %q: %v", names, img.ID, err)
return errors.Wrapf(err, "error setting names %v on image %q", names, img.ID)
}
logrus.Debugf("set names of image %q to %v", img.ID, names)
}
return nil
}

View File

@@ -6,9 +6,9 @@ const (
// VersionMajor is for an API incompatible changes
VersionMajor = 5
// VersionMinor is for functionality in a backwards-compatible manner
VersionMinor = 12
VersionMinor = 13
// VersionPatch is for backwards-compatible bug fixes
VersionPatch = 0
VersionPatch = 1
// VersionDev indicates development branch. Releases will be empty string.
VersionDev = ""