This is an unreleased version of c/image, but it is important to
to have the test added in in the next commit enforcing as soon as
possible.

> go get github.com/containers/image/v5@HEAD
> make vendor

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This commit is contained in:
Miloslav Trmač 2020-04-30 21:23:18 +02:00 committed by Valentin Rothberg
parent 42f68c1c76
commit 8f845aac23
65 changed files with 545 additions and 364 deletions

4
go.mod
View File

@ -4,9 +4,9 @@ go 1.12
require (
github.com/containerd/containerd v1.3.0 // indirect
github.com/containers/image/v5 v5.4.3
github.com/containers/image/v5 v5.4.4-0.20200504143706-d52a99c5329e
github.com/containers/ocicrypt v1.0.2
github.com/containers/storage v1.19.0
github.com/containers/storage v1.19.1
github.com/docker/docker v1.4.2-0.20191219165747-a9416c67da9f
github.com/dsnet/compress v0.0.1 // indirect
github.com/go-check/check v0.0.0-20180628173108-788fd7840127

27
go.sum
View File

@ -38,16 +38,14 @@ github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv
github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
github.com/containers/image/v5 v5.4.3 h1:zn2HR7uu4hpvT5QQHgjqonOzKDuM1I1UHUEmzZT5sbs=
github.com/containers/image/v5 v5.4.3/go.mod h1:pN0tvp3YbDd7BWavK2aE0mvJUqVd2HmhPjekyWSFm0U=
github.com/containers/image/v5 v5.4.4-0.20200504143706-d52a99c5329e h1:9bh+m/q5cuowLt6jMei1gz3b1uqBkQ0hFKQH07OzdqM=
github.com/containers/image/v5 v5.4.4-0.20200504143706-d52a99c5329e/go.mod h1:Y16cLFoR9N1yWMeppYTWHd+KmUgwNhAsDiKVCmB+6H4=
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDplZ7U33NwHZkrVELsZP5fYj9pM5WBZB2GE=
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
github.com/containers/ocicrypt v1.0.2 h1:Q0/IPs8ohfbXNxEfyJ2pFVmvJu5BhqJUAmc6ES9NKbo=
github.com/containers/ocicrypt v1.0.2/go.mod h1:nsOhbP19flrX6rE7ieGFvBlr7modwmNjsqWarIUce4M=
github.com/containers/storage v1.18.2 h1:4cgFbrrgr9nR9xCeOmfpyxk1MtXYZGr7XGPJfAVkGmc=
github.com/containers/storage v1.18.2/go.mod h1:WTBMf+a9ZZ/LbmEVeLHH2TX4CikWbO1Bt+/m58ZHVPg=
github.com/containers/storage v1.19.0 h1:bVIF5EglbT5PQnqcN7sE6VWqoQzlToqzjXdz+eNubQg=
github.com/containers/storage v1.19.0/go.mod h1:9Xc4rrTubn5hmtBfL+PSJH1XlfTQwR4VAG1NDUIpCts=
github.com/containers/storage v1.19.1 h1:YKIzOO12iaD5Ra0PKFS6emcygbHLmwmQOCQRU/19YAQ=
github.com/containers/storage v1.19.1/go.mod h1:KbXjSwKnx17ejOsjFcCXSf78mCgZkQSLPBNTMRc3XrQ=
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/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
@ -133,10 +131,8 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eTO0Q8=
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.10.4 h1:jFzIFaf586tquEB5EhzQG0HwGNSlgAJpG53G6Ss11wc=
github.com/klauspost/compress v1.10.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.10.5 h1:7q6vHIqubShURwQz8cQK6yIe/xC3IF0Vm7TGfqjewrc=
github.com/klauspost/compress v1.10.5/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/pgzip v1.2.3 h1:Ce2to9wvs/cuJ2b86/CKQoTYr9VHfpanYosZ0UBJqdw=
github.com/klauspost/pgzip v1.2.3/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
@ -185,7 +181,6 @@ github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.m
github.com/opencontainers/runtime-spec v1.0.0 h1:O6L965K88AilqnxeYPks/75HLpp4IG+FjeSCI3cVdRg=
github.com/opencontainers/runtime-spec v1.0.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
github.com/opencontainers/selinux v1.4.0/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
github.com/opencontainers/selinux v1.5.1 h1:jskKwSMFYqyTrHEuJgQoUlTcId0av64S6EWObrIfn5Y=
github.com/opencontainers/selinux v1.5.1/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
github.com/ostreedev/ostree-go v0.0.0-20190702140239-759a8c1ac913 h1:TnbXhKzrTOyuvWrjI8W6pcoI9XPbLHFXCdN2dtUw7Rw=
@ -261,8 +256,8 @@ github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oW
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/vbatts/tar-split v0.11.1 h1:0Odu65rhcZ3JZaPHxl7tCI3V/C/Q9Zf82UFravl02dE=
github.com/vbatts/tar-split v0.11.1/go.mod h1:LEuURwDEiWjRjwu46yU3KVGuUdVv/dcnpcEPSzR8z6g=
github.com/vbauerster/mpb/v5 v5.0.3 h1:Ldt/azOkbThTk2loi6FrBd/3fhxGFQ24MxFAS88PoNY=
github.com/vbauerster/mpb/v5 v5.0.3/go.mod h1:h3YxU5CSr8rZP4Q3xZPVB3jJLhWPou63lHEdr9ytH4Y=
github.com/vbauerster/mpb/v5 v5.0.4 h1:w7l/tJfHmtIOKZkU+bhbDZOUxj1kln9jy4DUOp3Tl14=
github.com/vbauerster/mpb/v5 v5.0.4/go.mod h1:fvzasBUyuo35UyuA6sSOlVhpLoNQsp2nBdHw7OiSUU8=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b h1:6cLsL+2FW6dRAdl5iMtHgRogVCff0QpRi9653YmdcJA=
github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
@ -286,9 +281,10 @@ go4.org v0.0.0-20190218023631-ce4c26f7be8e/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59 h1:3zb4D3T4G8jdExgVU/95+vQXfpEPiMdCaZgmGVxjNHM=
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5 h1:Q7tZBpemrlsc2I7IyODzhtallWRSm4Q0d09pL6XbQtU=
golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@ -328,10 +324,11 @@ golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200327173247-9dae0f8f5775 h1:TC0v2RSO1u2kn1ZugjrFXkRZAEaqMN/RW+OTZkBzmLE=
golang.org/x/sys v0.0.0-20200327173247-9dae0f8f5775/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f h1:gWF768j/LaZugp8dyS4UwsslYCYz9XgFxvlgsn0n9H8=
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=

View File

@ -798,7 +798,6 @@ func (ic *imageCopier) copyLayers(ctx context.Context) error {
// copyGroup is used to determine if all layers are copied
copyGroup := sync.WaitGroup{}
copyGroup.Add(numLayers)
// copySemaphore is used to limit the number of parallel downloads to
// avoid malicious images causing troubles and to be nice to servers.
@ -850,18 +849,22 @@ func (ic *imageCopier) copyLayers(ctx context.Context) error {
if err := func() error { // A scope for defer
progressPool, progressCleanup := ic.c.newProgressPool(ctx)
defer progressCleanup()
defer func() {
// Wait for all layers to be copied. progressCleanup() must not be called while any of the copyLayerHelpers interact with the progressPool.
copyGroup.Wait()
progressCleanup()
}()
for i, srcLayer := range srcInfos {
err = copySemaphore.Acquire(ctx, 1)
if err != nil {
return errors.Wrapf(err, "Can't acquire semaphore")
}
copyGroup.Add(1)
go copyLayerHelper(i, srcLayer, encLayerBitmap[i], progressPool)
}
// Wait for all layers to be copied
copyGroup.Wait()
// A call to copyGroup.Wait() is done at this point by the defer above.
return nil
}(); err != nil {
return err

View File

@ -613,6 +613,9 @@ func (c *dockerClient) getBearerTokenOAuth2(ctx context.Context, challenge chall
params.Add("client_id", "containers/image")
authReq.Body = ioutil.NopCloser(bytes.NewBufferString(params.Encode()))
if c.sys != nil && c.sys.DockerRegistryUserAgent != "" {
authReq.Header.Add("User-Agent", c.sys.DockerRegistryUserAgent)
}
authReq.Header.Add("Content-Type", "application/x-www-form-urlencoded")
logrus.Debugf("%s %s", authReq.Method, authReq.URL.String())
res, err := c.client.Do(authReq)
@ -665,6 +668,9 @@ func (c *dockerClient) getBearerToken(ctx context.Context, challenge challenge,
if c.auth.Username != "" && c.auth.Password != "" {
authReq.SetBasicAuth(c.auth.Username, c.auth.Password)
}
if c.sys != nil && c.sys.DockerRegistryUserAgent != "" {
authReq.Header.Add("User-Agent", c.sys.DockerRegistryUserAgent)
}
logrus.Debugf("%s %s", authReq.Method, authReq.URL.String())
res, err := c.client.Do(authReq)

View File

@ -37,7 +37,7 @@ func newImage(ctx context.Context, sys *types.SystemContext, ref dockerReference
// SourceRefFullName returns a fully expanded name for the repository this image is in.
func (i *Image) SourceRefFullName() string {
return i.src.ref.ref.Name()
return i.src.logicalRef.ref.Name()
}
// GetRepositoryTags list all tags available in the repository. The tag
@ -45,7 +45,7 @@ func (i *Image) SourceRefFullName() string {
// backward-compatible shim method which calls the module-level
// GetRepositoryTags)
func (i *Image) GetRepositoryTags(ctx context.Context) ([]string, error) {
return GetRepositoryTags(ctx, i.src.c.sys, i.src.ref)
return GetRepositoryTags(ctx, i.src.c.sys, i.src.logicalRef)
}
// GetRepositoryTags list all tags available in the repository. The tag

View File

@ -16,6 +16,7 @@ import (
"github.com/containers/image/v5/docker/reference"
"github.com/containers/image/v5/internal/iolimits"
"github.com/containers/image/v5/internal/uploadreader"
"github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/pkg/blobinfocache/none"
"github.com/containers/image/v5/types"
@ -162,20 +163,31 @@ func (d *dockerImageDestination) PutBlob(ctx context.Context, stream io.Reader,
digester := digest.Canonical.Digester()
sizeCounter := &sizeCounter{}
tee := io.TeeReader(stream, io.MultiWriter(digester.Hash(), sizeCounter))
res, err = d.c.makeRequestToResolvedURL(ctx, "PATCH", uploadLocation.String(), map[string][]string{"Content-Type": {"application/octet-stream"}}, tee, inputInfo.Size, v2Auth, nil)
uploadLocation, err = func() (*url.URL, error) { // A scope for defer
uploadReader := uploadreader.NewUploadReader(io.TeeReader(stream, io.MultiWriter(digester.Hash(), sizeCounter)))
// This error text should never be user-visible, we terminate only after makeRequestToResolvedURL
// returns, so there isnt a way for the error text to be provided to any of our callers.
defer uploadReader.Terminate(errors.New("Reading data from an already terminated upload"))
res, err = d.c.makeRequestToResolvedURL(ctx, "PATCH", uploadLocation.String(), map[string][]string{"Content-Type": {"application/octet-stream"}}, uploadReader, inputInfo.Size, v2Auth, nil)
if err != nil {
logrus.Debugf("Error uploading layer chunked %v", err)
return nil, err
}
defer res.Body.Close()
if !successStatus(res.StatusCode) {
return nil, errors.Wrapf(client.HandleErrorResponse(res), "Error uploading layer chunked")
}
uploadLocation, err := res.Location()
if err != nil {
return nil, errors.Wrap(err, "Error determining upload URL")
}
return uploadLocation, nil
}()
if err != nil {
logrus.Debugf("Error uploading layer chunked, response %#v", res)
return types.BlobInfo{}, err
}
defer res.Body.Close()
computedDigest := digester.Digest()
uploadLocation, err = res.Location()
if err != nil {
return types.BlobInfo{}, errors.Wrap(err, "Error determining upload URL")
}
// FIXME: DELETE uploadLocation on failure (does not really work in docker/distribution servers, which incorrectly require the "delete" action in the token's scope)
locationQuery := uploadLocation.Query()
@ -469,17 +481,17 @@ func (d *dockerImageDestination) PutSignatures(ctx context.Context, signatures [
}
switch {
case d.c.signatureBase != nil:
return d.putSignaturesToLookaside(signatures, instanceDigest)
return d.putSignaturesToLookaside(signatures, *instanceDigest)
case d.c.supportsSignatures:
return d.putSignaturesToAPIExtension(ctx, signatures, instanceDigest)
return d.putSignaturesToAPIExtension(ctx, signatures, *instanceDigest)
default:
return errors.Errorf("X-Registry-Supports-Signatures extension not supported, and lookaside is not configured")
}
}
// putSignaturesToLookaside implements PutSignatures() from the lookaside location configured in s.c.signatureBase,
// which is not nil.
func (d *dockerImageDestination) putSignaturesToLookaside(signatures [][]byte, instanceDigest *digest.Digest) error {
// which is not nil, for a manifest with manifestDigest.
func (d *dockerImageDestination) putSignaturesToLookaside(signatures [][]byte, manifestDigest digest.Digest) error {
// FIXME? This overwrites files one at a time, definitely not atomic.
// A failure when updating signatures with a reordered copy could lose some of them.
@ -490,7 +502,7 @@ func (d *dockerImageDestination) putSignaturesToLookaside(signatures [][]byte, i
// NOTE: Keep this in sync with docs/signature-protocols.md!
for i, signature := range signatures {
url := signatureStorageURL(d.c.signatureBase, *instanceDigest, i)
url := signatureStorageURL(d.c.signatureBase, manifestDigest, i)
if url == nil {
return errors.Errorf("Internal error: signatureStorageURL with non-nil base returned nil")
}
@ -505,7 +517,7 @@ func (d *dockerImageDestination) putSignaturesToLookaside(signatures [][]byte, i
// is enough for dockerImageSource to stop looking for other signatures, so that
// is sufficient.
for i := len(signatures); ; i++ {
url := signatureStorageURL(d.c.signatureBase, *instanceDigest, i)
url := signatureStorageURL(d.c.signatureBase, manifestDigest, i)
if url == nil {
return errors.Errorf("Internal error: signatureStorageURL with non-nil base returned nil")
}
@ -564,8 +576,9 @@ func (c *dockerClient) deleteOneSignature(url *url.URL) (missing bool, err error
}
}
// putSignaturesToAPIExtension implements PutSignatures() using the X-Registry-Supports-Signatures API extension.
func (d *dockerImageDestination) putSignaturesToAPIExtension(ctx context.Context, signatures [][]byte, instanceDigest *digest.Digest) error {
// putSignaturesToAPIExtension implements PutSignatures() using the X-Registry-Supports-Signatures API extension,
// for a manifest with manifestDigest.
func (d *dockerImageDestination) putSignaturesToAPIExtension(ctx context.Context, signatures [][]byte, manifestDigest digest.Digest) error {
// Skip dealing with the manifest digest, or reading the old state, if not necessary.
if len(signatures) == 0 {
return nil
@ -575,7 +588,7 @@ func (d *dockerImageDestination) putSignaturesToAPIExtension(ctx context.Context
// always adds signatures. Eventually we should also allow removing signatures,
// but the X-Registry-Supports-Signatures API extension does not support that yet.
existingSignatures, err := d.c.getExtensionsSignatures(ctx, d.ref, *instanceDigest)
existingSignatures, err := d.c.getExtensionsSignatures(ctx, d.ref, manifestDigest)
if err != nil {
return err
}
@ -600,7 +613,7 @@ sigExists:
if err != nil || n != 16 {
return errors.Wrapf(err, "Error generating random signature len %d", n)
}
signatureName = fmt.Sprintf("%s@%032x", instanceDigest.String(), randBytes)
signatureName = fmt.Sprintf("%s@%032x", manifestDigest.String(), randBytes)
if _, ok := existingSigNames[signatureName]; !ok {
break
}
@ -616,7 +629,7 @@ sigExists:
return err
}
path := fmt.Sprintf(extensionsSignaturePath, reference.Path(d.ref.ref), d.manifestDigest.String())
path := fmt.Sprintf(extensionsSignaturePath, reference.Path(d.ref.ref), manifestDigest.String())
res, err := d.c.makeRequest(ctx, "PUT", path, nil, bytes.NewReader(body), v2Auth, nil)
if err != nil {
return err

View File

@ -24,8 +24,9 @@ import (
)
type dockerImageSource struct {
ref dockerReference
c *dockerClient
logicalRef dockerReference // The reference the user requested.
physicalRef dockerReference // The actual reference we are accessing (possibly a mirror)
c *dockerClient
// State
cachedManifest []byte // nil if not loaded yet
cachedManifestMIMEType string // Only valid if cachedManifest != nil
@ -49,7 +50,6 @@ func newImageSource(ctx context.Context, sys *types.SystemContext, ref dockerRef
}
}
primaryDomain := reference.Domain(ref.ref)
// Check all endpoints for the manifest availability. If we find one that does
// contain the image, it will be used for all future pull actions. Always try the
// non-mirror original location last; this both transparently handles the case
@ -66,7 +66,7 @@ func newImageSource(ctx context.Context, sys *types.SystemContext, ref dockerRef
attempts := []attempt{}
for _, pullSource := range pullSources {
logrus.Debugf("Trying to access %q", pullSource.Reference)
s, err := newImageSourceAttempt(ctx, sys, pullSource, primaryDomain)
s, err := newImageSourceAttempt(ctx, sys, ref, pullSource)
if err == nil {
return s, nil
}
@ -95,32 +95,33 @@ func newImageSource(ctx context.Context, sys *types.SystemContext, ref dockerRef
}
// newImageSourceAttempt is an internal helper for newImageSource. Everyone else must call newImageSource.
// Given a pullSource and primaryDomain, return a dockerImageSource if it is reachable.
// Given a logicalReference and a pullSource, return a dockerImageSource if it is reachable.
// The caller must call .Close() on the returned ImageSource.
func newImageSourceAttempt(ctx context.Context, sys *types.SystemContext, pullSource sysregistriesv2.PullSource, primaryDomain string) (*dockerImageSource, error) {
ref, err := newReference(pullSource.Reference)
func newImageSourceAttempt(ctx context.Context, sys *types.SystemContext, logicalRef dockerReference, pullSource sysregistriesv2.PullSource) (*dockerImageSource, error) {
physicalRef, err := newReference(pullSource.Reference)
if err != nil {
return nil, err
}
endpointSys := sys
// sys.DockerAuthConfig does not explicitly specify a registry; we must not blindly send the credentials intended for the primary endpoint to mirrors.
if endpointSys != nil && endpointSys.DockerAuthConfig != nil && reference.Domain(ref.ref) != primaryDomain {
if endpointSys != nil && endpointSys.DockerAuthConfig != nil && reference.Domain(physicalRef.ref) != reference.Domain(logicalRef.ref) {
copy := *endpointSys
copy.DockerAuthConfig = nil
copy.DockerBearerRegistryToken = ""
endpointSys = &copy
}
client, err := newDockerClientFromRef(endpointSys, ref, false, "pull")
client, err := newDockerClientFromRef(endpointSys, physicalRef, false, "pull")
if err != nil {
return nil, err
}
client.tlsClientConfig.InsecureSkipVerify = pullSource.Endpoint.Insecure
s := &dockerImageSource{
ref: ref,
c: client,
logicalRef: logicalRef,
physicalRef: physicalRef,
c: client,
}
if err := s.ensureManifestIsLoaded(ctx); err != nil {
@ -132,7 +133,7 @@ func newImageSourceAttempt(ctx context.Context, sys *types.SystemContext, pullSo
// Reference returns the reference used to set up this source, _as specified by the user_
// (not as the image itself, or its underlying storage, claims). This can be used e.g. to determine which public keys are trusted for this image.
func (s *dockerImageSource) Reference() types.ImageReference {
return s.ref
return s.logicalRef
}
// Close removes resources associated with an initialized ImageSource, if any.
@ -181,7 +182,7 @@ func (s *dockerImageSource) GetManifest(ctx context.Context, instanceDigest *dig
}
func (s *dockerImageSource) fetchManifest(ctx context.Context, tagOrDigest string) ([]byte, string, error) {
path := fmt.Sprintf(manifestPath, reference.Path(s.ref.ref), tagOrDigest)
path := fmt.Sprintf(manifestPath, reference.Path(s.physicalRef.ref), tagOrDigest)
headers := map[string][]string{
"Accept": manifest.DefaultRequestedManifestMIMETypes,
}
@ -191,7 +192,7 @@ func (s *dockerImageSource) fetchManifest(ctx context.Context, tagOrDigest strin
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return nil, "", errors.Wrapf(client.HandleErrorResponse(res), "Error reading manifest %s in %s", tagOrDigest, s.ref.ref.Name())
return nil, "", errors.Wrapf(client.HandleErrorResponse(res), "Error reading manifest %s in %s", tagOrDigest, s.physicalRef.ref.Name())
}
manblob, err := iolimits.ReadAtMost(res.Body, iolimits.MaxManifestBodySize)
@ -213,7 +214,7 @@ func (s *dockerImageSource) ensureManifestIsLoaded(ctx context.Context) error {
return nil
}
reference, err := s.ref.tagOrDigest()
reference, err := s.physicalRef.tagOrDigest()
if err != nil {
return err
}
@ -271,7 +272,7 @@ func (s *dockerImageSource) GetBlob(ctx context.Context, info types.BlobInfo, ca
return s.getExternalBlob(ctx, info.URLs)
}
path := fmt.Sprintf(blobsPath, reference.Path(s.ref.ref), info.Digest.String())
path := fmt.Sprintf(blobsPath, reference.Path(s.physicalRef.ref), info.Digest.String())
logrus.Debugf("Downloading %s", path)
res, err := s.c.makeRequest(ctx, "GET", path, nil, nil, v2Auth, nil)
if err != nil {
@ -280,7 +281,7 @@ func (s *dockerImageSource) GetBlob(ctx context.Context, info types.BlobInfo, ca
if err := httpResponseToError(res, "Error fetching blob"); err != nil {
return nil, 0, err
}
cache.RecordKnownLocation(s.ref.Transport(), bicTransportScope(s.ref), info.Digest, newBICLocationReference(s.ref))
cache.RecordKnownLocation(s.physicalRef.Transport(), bicTransportScope(s.physicalRef), info.Digest, newBICLocationReference(s.physicalRef))
return res.Body, getBlobSize(res), nil
}
@ -308,7 +309,7 @@ func (s *dockerImageSource) manifestDigest(ctx context.Context, instanceDigest *
if instanceDigest != nil {
return *instanceDigest, nil
}
if digested, ok := s.ref.ref.(reference.Digested); ok {
if digested, ok := s.physicalRef.ref.(reference.Digested); ok {
d := digested.Digest()
if d.Algorithm() == digest.Canonical {
return d, nil
@ -398,7 +399,7 @@ func (s *dockerImageSource) getSignaturesFromAPIExtension(ctx context.Context, i
return nil, err
}
parsedBody, err := s.c.getExtensionsSignatures(ctx, s.ref, manifestDigest)
parsedBody, err := s.c.getExtensionsSignatures(ctx, s.physicalRef, manifestDigest)
if err != nil {
return nil, err
}

View File

@ -115,12 +115,23 @@ func getCPUVariant(os string, arch string) string {
return ""
}
// compatibility contains, for a specified architecture, a list of known variants, in the
// order from most capable (most restrictive) to least capable (most compatible).
// Architectures that dont have variants should not have an entry here.
var compatibility = map[string][]string{
"arm": {"v7", "v6", "v5"},
"arm": {"v8", "v7", "v6", "v5"},
"arm64": {"v8"},
}
// Returns all compatible platforms with the platform specifics possibly overriden by user,
// baseVariants contains, for a specified architecture, a variant that is known to be
// supported by _all_ machines using that architecture.
// Architectures that dont have variants, or where there are possible versions without
// an established variant name, should not have an entry here.
var baseVariants = map[string]string{
"arm64": "v8",
}
// WantedPlatforms returns all compatible platforms with the platform specifics possibly overriden by user,
// the most compatible platform is first.
// If some option (arch, os, variant) is not present, a value from current platform is detected.
func WantedPlatforms(ctx *types.SystemContext) ([]imgspecv1.Platform, error) {
@ -145,59 +156,45 @@ func WantedPlatforms(ctx *types.SystemContext) ([]imgspecv1.Platform, error) {
wantedOS = ctx.OSChoice
}
var wantedPlatforms []imgspecv1.Platform
if wantedVariant != "" && compatibility[wantedArch] != nil {
wantedPlatforms = make([]imgspecv1.Platform, 0, len(compatibility[wantedArch]))
wantedIndex := -1
for i, v := range compatibility[wantedArch] {
if wantedVariant == v {
wantedIndex = i
break
var variants []string = nil
if wantedVariant != "" {
if compatibility[wantedArch] != nil {
variantOrder := compatibility[wantedArch]
for i, v := range variantOrder {
if wantedVariant == v {
variants = variantOrder[i:]
break
}
}
}
// user wants a variant which we know nothing about - not even compatibility
if wantedIndex == -1 {
wantedPlatforms = []imgspecv1.Platform{
{
OS: wantedOS,
Architecture: wantedArch,
Variant: wantedVariant,
},
}
} else {
for i := wantedIndex; i < len(compatibility[wantedArch]); i++ {
v := compatibility[wantedArch][i]
wantedPlatforms = append(wantedPlatforms, imgspecv1.Platform{
OS: wantedOS,
Architecture: wantedArch,
Variant: v,
})
}
if variants == nil {
// user wants a variant which we know nothing about - not even compatibility
variants = []string{wantedVariant}
}
variants = append(variants, "")
} else {
wantedPlatforms = []imgspecv1.Platform{
{
OS: wantedOS,
Architecture: wantedArch,
Variant: wantedVariant,
},
variants = append(variants, "") // No variant specified, use a “no variant specified” image if present
if baseVariant, ok := baseVariants[wantedArch]; ok {
// But also accept an image with the “base” variant for the architecture, if it exists.
variants = append(variants, baseVariant)
}
}
return wantedPlatforms, nil
res := make([]imgspecv1.Platform, 0, len(variants))
for _, v := range variants {
res = append(res, imgspecv1.Platform{
OS: wantedOS,
Architecture: wantedArch,
Variant: v,
})
}
return res, nil
}
// MatchesPlatform returns true if a platform descriptor from a multi-arch image matches
// an item from the return value of WantedPlatforms.
func MatchesPlatform(image imgspecv1.Platform, wanted imgspecv1.Platform) bool {
if image.Architecture != wanted.Architecture {
return false
}
if image.OS != wanted.OS {
return false
}
if wanted.Variant == "" || image.Variant == wanted.Variant {
return true
}
return false
return image.Architecture == wanted.Architecture &&
image.OS == wanted.OS &&
image.Variant == wanted.Variant
}

View File

@ -0,0 +1,61 @@
package uploadreader
import (
"io"
"sync"
)
// UploadReader is a pass-through reader for use in sending non-trivial data using the net/http
// package (http.NewRequest, http.Post and the like).
//
// The net/http package uses a separate goroutine to upload data to a HTTP connection,
// and it is possible for the server to return a response (typically an error) before consuming
// the full body of the request. In that case http.Client.Do can return with an error while
// the body is still being read — regardless of of the cancellation, if any, of http.Request.Context().
//
// As a result, any data used/updated by the io.Reader() provided as the request body may be
// used/updated even after http.Client.Do returns, causing races.
//
// To fix this, UploadReader provides a synchronized Terminate() method, which can block for
// a not-completely-negligible time (for a duration of the underlying Read()), but guarantees that
// after Terminate() returns, the underlying reader is never used any more (unlike calling
// the cancellation callback of context.WithCancel, which returns before any recipients may have
// reacted to the cancellation).
type UploadReader struct {
mutex sync.Mutex
// The following members can only be used with mutex held
reader io.Reader
terminationError error // nil if not terminated yet
}
// NewUploadReader returns an UploadReader for an "underlying" reader.
func NewUploadReader(underlying io.Reader) *UploadReader {
return &UploadReader{
reader: underlying,
terminationError: nil,
}
}
// Read returns the error set by Terminate, if any, or calls the underlying reader.
// It is safe to call this from a different goroutine than Terminate.
func (ur *UploadReader) Read(p []byte) (int, error) {
ur.mutex.Lock()
defer ur.mutex.Unlock()
if ur.terminationError != nil {
return 0, ur.terminationError
}
return ur.reader.Read(p)
}
// Terminate waits for in-progress Read calls, if any, to finish, and ensures that after
// this function returns, any Read calls will fail with the provided error, and the underlying
// reader will never be used any more.
//
// It is safe to call this from a different goroutine than Read.
func (ur *UploadReader) Terminate(err error) {
ur.mutex.Lock() // May block for some time if ur.reader.Read() is in progress
defer ur.mutex.Unlock()
ur.terminationError = err
}

View File

@ -0,0 +1,118 @@
package manifest
import (
"fmt"
"github.com/containers/image/v5/pkg/compression"
"github.com/containers/image/v5/types"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
// dupStringSlice returns a deep copy of a slice of strings, or nil if the
// source slice is empty.
func dupStringSlice(list []string) []string {
if len(list) == 0 {
return nil
}
dup := make([]string, len(list))
copy(dup, list)
return dup
}
// dupStringStringMap returns a deep copy of a map[string]string, or nil if the
// passed-in map is nil or has no keys.
func dupStringStringMap(m map[string]string) map[string]string {
if len(m) == 0 {
return nil
}
result := make(map[string]string)
for k, v := range m {
result[k] = v
}
return result
}
// layerInfosToStrings converts a list of layer infos, presumably obtained from a Manifest.LayerInfos()
// method call, into a format suitable for inclusion in a types.ImageInspectInfo structure.
func layerInfosToStrings(infos []LayerInfo) []string {
layers := make([]string, len(infos))
for i, info := range infos {
layers[i] = info.Digest.String()
}
return layers
}
// compressionMIMETypeSet describes a set of MIME type “variants” that represent differently-compressed
// versions of “the same kind of content”.
// The map key is the return value of compression.Algorithm.Name(), or mtsUncompressed;
// the map value is a MIME type, or mtsUnsupportedMIMEType to mean "recognized but unsupported".
type compressionMIMETypeSet map[string]string
const mtsUncompressed = "" // A key in compressionMIMETypeSet for the uncompressed variant
const mtsUnsupportedMIMEType = "" // A value in compressionMIMETypeSet that means “recognized but unsupported”
// compressionVariantMIMEType returns a variant of mimeType for the specified algorithm (which may be nil
// to mean "no compression"), based on variantTable.
func compressionVariantMIMEType(variantTable []compressionMIMETypeSet, mimeType string, algorithm *compression.Algorithm) (string, error) {
if mimeType == mtsUnsupportedMIMEType { // Prevent matching against the {algo:mtsUnsupportedMIMEType} entries
return "", fmt.Errorf("cannot update unknown MIME type")
}
for _, variants := range variantTable {
for _, mt := range variants {
if mt == mimeType { // Found the variant
name := mtsUncompressed
if algorithm != nil {
name = algorithm.Name()
}
if res, ok := variants[name]; ok {
if res != mtsUnsupportedMIMEType {
return res, nil
}
if name != mtsUncompressed {
return "", fmt.Errorf("%s compression is not supported", name)
}
return "", errors.New("uncompressed variant is not supported")
}
if name != mtsUncompressed {
return "", fmt.Errorf("unknown compression algorithm %s", name)
}
// We can't very well say “the idea of no compression is unknown”
return "", errors.New("uncompressed variant is not supported")
}
}
}
if algorithm != nil {
return "", fmt.Errorf("unsupported MIME type for compression: %s", mimeType)
}
return "", fmt.Errorf("unsupported MIME type for decompression: %s", mimeType)
}
// updatedMIMEType returns the result of applying edits in updated (MediaType, CompressionOperation) to
// mimeType, based on variantTable. It may use updated.Digest for error messages.
func updatedMIMEType(variantTable []compressionMIMETypeSet, mimeType string, updated types.BlobInfo) (string, error) {
// Note that manifests in containers-storage might be reporting the
// wrong media type since the original manifests are stored while layers
// are decompressed in storage. Hence, we need to consider the case
// that an already {de}compressed layer should be {de}compressed;
// compressionVariantMIMEType does that by not caring whether the original is
// {de}compressed.
switch updated.CompressionOperation {
case types.PreserveOriginal:
// Keep the original media type.
return mimeType, nil
case types.Decompress:
return compressionVariantMIMEType(variantTable, mimeType, nil)
case types.Compress:
if updated.CompressionAlgorithm == nil {
logrus.Debugf("Error preparing updated manifest: blob %q was compressed but does not specify by which algorithm: falling back to use the original blob", updated.Digest)
return mimeType, nil
}
return compressionVariantMIMEType(variantTable, mimeType, updated.CompressionAlgorithm)
default:
return "", fmt.Errorf("unknown compression operation (%d)", updated.CompressionOperation)
}
}

View File

@ -10,7 +10,6 @@ import (
"github.com/containers/image/v5/types"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
// Schema2Descriptor is a “descriptor” in docker/distribution schema 2.
@ -213,26 +212,17 @@ func (m *Schema2) LayerInfos() []LayerInfo {
return blobs
}
// isSchema2ForeignLayer is a convenience wrapper to check if a given mime type
// is a compressed or decompressed schema 2 foreign layer.
func isSchema2ForeignLayer(mimeType string) bool {
switch mimeType {
case DockerV2Schema2ForeignLayerMediaType, DockerV2Schema2ForeignLayerMediaTypeGzip:
return true
default:
return false
}
}
// isSchema2Layer is a convenience wrapper to check if a given mime type is a
// compressed or decompressed schema 2 layer.
func isSchema2Layer(mimeType string) bool {
switch mimeType {
case DockerV2SchemaLayerMediaTypeUncompressed, DockerV2Schema2LayerMediaType:
return true
default:
return false
}
var schema2CompressionMIMETypeSets = []compressionMIMETypeSet{
{
mtsUncompressed: DockerV2Schema2ForeignLayerMediaType,
compression.Gzip.Name(): DockerV2Schema2ForeignLayerMediaTypeGzip,
compression.Zstd.Name(): mtsUnsupportedMIMEType,
},
{
mtsUncompressed: DockerV2SchemaLayerMediaTypeUncompressed,
compression.Gzip.Name(): DockerV2Schema2LayerMediaType,
compression.Zstd.Name(): mtsUnsupportedMIMEType,
},
}
// UpdateLayerInfos replaces the original layers with the specified BlobInfos (size+digest+urls), in order (the root layer first, and then successive layered layers)
@ -243,67 +233,16 @@ func (m *Schema2) UpdateLayerInfos(layerInfos []types.BlobInfo) error {
original := m.LayersDescriptors
m.LayersDescriptors = make([]Schema2Descriptor, len(layerInfos))
for i, info := range layerInfos {
mimeType := original[i].MediaType
// First make sure we support the media type of the original layer.
if err := SupportedSchema2MediaType(original[i].MediaType); err != nil {
return fmt.Errorf("Error preparing updated manifest: unknown media type of original layer: %q", original[i].MediaType)
if err := SupportedSchema2MediaType(mimeType); err != nil {
return fmt.Errorf("Error preparing updated manifest: unknown media type of original layer %q: %q", info.Digest, mimeType)
}
// Set the correct media types based on the specified compression
// operation, the desired compression algorithm AND the original media
// type.
//
// Note that manifests in containers-storage might be reporting the
// wrong media type since the original manifests are stored while layers
// are decompressed in storage. Hence, we need to consider the case
// that an already {de}compressed layer should be {de}compressed, which
// is being addressed in `isSchema2{Foreign}Layer`.
switch info.CompressionOperation {
case types.PreserveOriginal:
// Keep the original media type.
m.LayersDescriptors[i].MediaType = original[i].MediaType
case types.Decompress:
// Decompress the original media type and check if it was
// non-distributable one or not.
mimeType := original[i].MediaType
switch {
case isSchema2ForeignLayer(mimeType):
m.LayersDescriptors[i].MediaType = DockerV2Schema2ForeignLayerMediaType
case isSchema2Layer(mimeType):
m.LayersDescriptors[i].MediaType = DockerV2SchemaLayerMediaTypeUncompressed
default:
return fmt.Errorf("Error preparing updated manifest: unsupported media type for decompression: %q", original[i].MediaType)
}
case types.Compress:
if info.CompressionAlgorithm == nil {
logrus.Debugf("Preparing updated manifest: blob %q was compressed but does not specify by which algorithm: falling back to use the original blob", info.Digest)
m.LayersDescriptors[i].MediaType = original[i].MediaType
break
}
// Compress the original media type and set the new one based on
// that type (distributable or not) and the specified compression
// algorithm. Throw an error if the algorithm is not supported.
switch info.CompressionAlgorithm.Name() {
case compression.Gzip.Name():
mimeType := original[i].MediaType
switch {
case isSchema2ForeignLayer(mimeType):
m.LayersDescriptors[i].MediaType = DockerV2Schema2ForeignLayerMediaTypeGzip
case isSchema2Layer(mimeType):
m.LayersDescriptors[i].MediaType = DockerV2Schema2LayerMediaType
default:
return fmt.Errorf("Error preparing updated manifest: unsupported media type for compression: %q", original[i].MediaType)
}
case compression.Zstd.Name():
return fmt.Errorf("Error preparing updated manifest: zstd compression is not supported for docker images")
default:
return fmt.Errorf("Error preparing updated manifest: unknown compression algorithm %q for layer %q", info.CompressionAlgorithm.Name(), info.Digest)
}
default:
return fmt.Errorf("Error preparing updated manifest: unknown compression operation (%d) for layer %q", info.CompressionOperation, info.Digest)
mimeType, err := updatedMIMEType(schema2CompressionMIMETypeSets, mimeType, info)
if err != nil {
return errors.Wrapf(err, "Error preparing updated manifest, layer %q", info.Digest)
}
m.LayersDescriptors[i].MediaType = mimeType
m.LayersDescriptors[i].Digest = info.Digest
m.LayersDescriptors[i].Size = info.Size
m.LayersDescriptors[i].URLs = info.URLs

View File

@ -107,7 +107,7 @@ func (list *Schema2List) ChooseInstance(ctx *types.SystemContext) (digest.Digest
}
}
}
return "", fmt.Errorf("no image found in manifest list for architecture %s, variant %s, OS %s", wantedPlatforms[0].Architecture, wantedPlatforms[0].Variant, wantedPlatforms[0].OS)
return "", fmt.Errorf("no image found in manifest list for architecture %s, variant %q, OS %s", wantedPlatforms[0].Architecture, wantedPlatforms[0].Variant, wantedPlatforms[0].OS)
}
// Serialize returns the list in a blob format.

View File

@ -59,30 +59,6 @@ type ListUpdate struct {
MediaType string
}
// dupStringSlice returns a deep copy of a slice of strings, or nil if the
// source slice is empty.
func dupStringSlice(list []string) []string {
if len(list) == 0 {
return nil
}
dup := make([]string, len(list))
copy(dup, list)
return dup
}
// dupStringStringMap returns a deep copy of a map[string]string, or nil if the
// passed-in map is nil or has no keys.
func dupStringStringMap(m map[string]string) map[string]string {
if len(m) == 0 {
return nil
}
result := make(map[string]string)
for k, v := range m {
result[k] = v
}
return result
}
// ListFromBlob parses a list of manifests.
func ListFromBlob(manifest []byte, manifestMIMEType string) (List, error) {
normalized := NormalizedMIMEType(manifestMIMEType)

View File

@ -256,13 +256,3 @@ func FromBlob(manblob []byte, mt string) (Manifest, error) {
// Note that this may not be reachable, NormalizedMIMEType has a default for unknown values.
return nil, fmt.Errorf("Unimplemented manifest MIME type %s (normalized as %s)", mt, nmt)
}
// layerInfosToStrings converts a list of layer infos, presumably obtained from a Manifest.LayerInfos()
// method call, into a format suitable for inclusion in a types.ImageInspectInfo structure.
func layerInfosToStrings(infos []LayerInfo) []string {
layers := make([]string, len(infos))
for i, info := range infos {
layers[i] = info.Digest.String()
}
return layers
}

View File

@ -12,7 +12,6 @@ import (
"github.com/opencontainers/image-spec/specs-go"
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
// BlobInfoFromOCI1Descriptor returns a types.BlobInfo based on the input OCI1 descriptor.
@ -95,26 +94,17 @@ func (m *OCI1) LayerInfos() []LayerInfo {
return blobs
}
// isOCI1NonDistributableLayer is a convenience wrapper to check if a given mime
// type is a compressed or decompressed OCI v1 non-distributable layer.
func isOCI1NonDistributableLayer(mimeType string) bool {
switch mimeType {
case imgspecv1.MediaTypeImageLayerNonDistributable, imgspecv1.MediaTypeImageLayerNonDistributableGzip, imgspecv1.MediaTypeImageLayerNonDistributableZstd:
return true
default:
return false
}
}
// isOCI1Layer is a convenience wrapper to check if a given mime type is a
// compressed or decompressed OCI v1 layer.
func isOCI1Layer(mimeType string) bool {
switch mimeType {
case imgspecv1.MediaTypeImageLayer, imgspecv1.MediaTypeImageLayerGzip, imgspecv1.MediaTypeImageLayerZstd:
return true
default:
return false
}
var oci1CompressionMIMETypeSets = []compressionMIMETypeSet{
{
mtsUncompressed: imgspecv1.MediaTypeImageLayerNonDistributable,
compression.Gzip.Name(): imgspecv1.MediaTypeImageLayerNonDistributableGzip,
compression.Zstd.Name(): imgspecv1.MediaTypeImageLayerNonDistributableZstd,
},
{
mtsUncompressed: imgspecv1.MediaTypeImageLayer,
compression.Gzip.Name(): imgspecv1.MediaTypeImageLayerGzip,
compression.Zstd.Name(): imgspecv1.MediaTypeImageLayerZstd,
},
}
// UpdateLayerInfos replaces the original layers with the specified BlobInfos (size+digest+urls+mediatype), in order (the root layer first, and then successive layered layers)
@ -133,79 +123,19 @@ func (m *OCI1) UpdateLayerInfos(layerInfos []types.BlobInfo) error {
}
mimeType = decMimeType
}
// Set the correct media types based on the specified compression
// operation, the desired compression algorithm AND the original media
// type.
//
// Note that manifests in containers-storage might be reporting the
// wrong media type since the original manifests are stored while layers
// are decompressed in storage. Hence, we need to consider the case
// that an already {de}compressed layer should be {de}compressed, which
// is being addressed in `isSchema2{Foreign}Layer`.
switch info.CompressionOperation {
case types.PreserveOriginal:
// Keep the original media type.
m.Layers[i].MediaType = mimeType
case types.Decompress:
// Decompress the original media type and check if it was
// non-distributable one or not.
switch {
case isOCI1NonDistributableLayer(mimeType):
m.Layers[i].MediaType = imgspecv1.MediaTypeImageLayerNonDistributable
case isOCI1Layer(mimeType):
m.Layers[i].MediaType = imgspecv1.MediaTypeImageLayer
default:
return fmt.Errorf("Error preparing updated manifest: unsupported media type for decompression: %q", mimeType)
}
case types.Compress:
if info.CompressionAlgorithm == nil {
logrus.Debugf("Error preparing updated manifest: blob %q was compressed but does not specify by which algorithm: falling back to use the original blob", info.Digest)
m.Layers[i].MediaType = mimeType
break
}
// Compress the original media type and set the new one based on
// that type (distributable or not) and the specified compression
// algorithm. Throw an error if the algorithm is not supported.
switch info.CompressionAlgorithm.Name() {
case compression.Gzip.Name():
switch {
case isOCI1NonDistributableLayer(mimeType):
m.Layers[i].MediaType = imgspecv1.MediaTypeImageLayerNonDistributableGzip
case isOCI1Layer(mimeType):
m.Layers[i].MediaType = imgspecv1.MediaTypeImageLayerGzip
default:
return fmt.Errorf("Error preparing updated manifest: unsupported media type for compression: %q", mimeType)
}
case compression.Zstd.Name():
switch {
case isOCI1NonDistributableLayer(mimeType):
m.Layers[i].MediaType = imgspecv1.MediaTypeImageLayerNonDistributableZstd
case isOCI1Layer(mimeType):
m.Layers[i].MediaType = imgspecv1.MediaTypeImageLayerZstd
default:
return fmt.Errorf("Error preparing updated manifest: unsupported media type for compression: %q", mimeType)
}
default:
return fmt.Errorf("Error preparing updated manifest: unknown compression algorithm %q for layer %q", info.CompressionAlgorithm.Name(), info.Digest)
}
default:
return fmt.Errorf("Error preparing updated manifest: unknown compression operation (%d) for layer %q", info.CompressionOperation, info.Digest)
mimeType, err := updatedMIMEType(oci1CompressionMIMETypeSets, mimeType, info)
if err != nil {
return errors.Wrapf(err, "Error preparing updated manifest, layer %q", info.Digest)
}
if info.CryptoOperation == types.Encrypt {
encMediaType, err := getEncryptedMediaType(m.Layers[i].MediaType)
encMediaType, err := getEncryptedMediaType(mimeType)
if err != nil {
return fmt.Errorf("error preparing updated manifest: encryption specified but no counterpart for mediatype: %q", m.Layers[i].MediaType)
return fmt.Errorf("error preparing updated manifest: encryption specified but no counterpart for mediatype: %q", mimeType)
}
m.Layers[i].MediaType = encMediaType
mimeType = encMediaType
}
m.Layers[i].MediaType = mimeType
m.Layers[i].Digest = info.Digest
m.Layers[i].Size = info.Size
m.Layers[i].Annotations = info.Annotations

View File

@ -79,6 +79,9 @@ func (index *OCI1Index) ChooseInstance(ctx *types.SystemContext) (digest.Digest,
}
for _, wantedPlatform := range wantedPlatforms {
for _, d := range index.Manifests {
if d.Platform == nil {
continue
}
imagePlatform := imgspecv1.Platform{
Architecture: d.Platform.Architecture,
OS: d.Platform.OS,
@ -97,7 +100,7 @@ func (index *OCI1Index) ChooseInstance(ctx *types.SystemContext) (digest.Digest,
return d.Digest, nil
}
}
return "", fmt.Errorf("no image found in image index for architecture %s, variant %s, OS %s", wantedPlatforms[0].Architecture, wantedPlatforms[0].Variant, wantedPlatforms[0].OS)
return "", fmt.Errorf("no image found in image index for architecture %s, variant %q, OS %s", wantedPlatforms[0].Architecture, wantedPlatforms[0].Variant, wantedPlatforms[0].OS)
}
// Serialize returns the index in a blob format.

View File

@ -6,12 +6,12 @@ const (
// VersionMajor is for an API incompatible changes
VersionMajor = 5
// VersionMinor is for functionality in a backwards-compatible manner
VersionMinor = 4
VersionMinor = 5
// VersionPatch is for backwards-compatible bug fixes
VersionPatch = 3
VersionPatch = 0
// VersionDev indicates development branch. Releases will be empty string.
VersionDev = ""
VersionDev = "-dev"
)
// Version is the specification version that the package types support.

View File

@ -19,9 +19,9 @@ env:
####
# GCE project where images live
IMAGE_PROJECT: "libpod-218412"
_BUILT_IMAGE_SUFFIX: "libpod-5874660151656448"
FEDORA_CACHE_IMAGE_NAME: "fedora-31-${_BUILT_IMAGE_SUFFIX}"
PRIOR_FEDORA_CACHE_IMAGE_NAME: "fedora-30-${_BUILT_IMAGE_SUFFIX}"
_BUILT_IMAGE_SUFFIX: "libpod-6301182083727360"
FEDORA_CACHE_IMAGE_NAME: "fedora-32-${_BUILT_IMAGE_SUFFIX}"
PRIOR_FEDORA_CACHE_IMAGE_NAME: "fedora-31-${_BUILT_IMAGE_SUFFIX}"
UBUNTU_CACHE_IMAGE_NAME: "ubuntu-19-${_BUILT_IMAGE_SUFFIX}"
PRIOR_UBUNTU_CACHE_IMAGE_NAME: "ubuntu-18-${_BUILT_IMAGE_SUFFIX}"

View File

@ -1 +1 @@
1.19.0
1.19.1

View File

@ -148,10 +148,20 @@ func (c *Container) ProcessLabel() string {
}
func (c *Container) MountOpts() []string {
if mountOpts, ok := c.Flags["MountOpts"].([]string); ok {
switch c.Flags["MountOpts"].(type) {
case []string:
return c.Flags["MountOpts"].([]string)
case []interface{}:
var mountOpts []string
for _, v := range c.Flags["MountOpts"].([]interface{}) {
if flag, ok := v.(string); ok {
mountOpts = append(mountOpts, flag)
}
}
return mountOpts
default:
return nil
}
return nil
}
func (r *containerStore) Containers() ([]Container, error) {

View File

@ -384,9 +384,21 @@ func (d *Driver) Get(id string, options graphdriver.MountOpts) (_ string, retErr
}
}()
// In the case of a read-only mount we first mount read-write so we can set the
// correct permissions on the mount point and remount read-only afterwards.
remountReadOnly := false
mountOptions := d.options.mountOptions
if len(options.Options) > 0 {
mountOptions = strings.Join(options.Options, ",")
var newOptions []string
for _, option := range options.Options {
if option == "ro" {
// Filter out read-only mount option but remember for later remounting.
remountReadOnly = true
} else {
newOptions = append(newOptions, option)
}
}
mountOptions = strings.Join(newOptions, ",")
}
filesystem := d.zfsPath(id)
@ -409,7 +421,14 @@ func (d *Driver) Get(id string, options graphdriver.MountOpts) (_ string, retErr
// this could be our first mount after creation of the filesystem, and the root dir may still have root
// permissions instead of the remapped root uid:gid (if user namespaces are enabled):
if err := os.Chown(mountpoint, rootUID, rootGID); err != nil {
return "", fmt.Errorf("error modifying zfs mountpoint (%s) directory ownership: %v", mountpoint, err)
return "", errors.Wrapf(err, "modifying zfs mountpoint (%s) ownership", mountpoint)
}
if remountReadOnly {
opts = label.FormatMountLabel("remount,ro", options.MountLabel)
if err := mount.Mount(filesystem, mountpoint, "zfs", opts); err != nil {
return "", errors.Wrap(err, "error remounting zfs mount read-only")
}
}
return mountpoint, nil

View File

@ -6,7 +6,7 @@ require (
github.com/Microsoft/hcsshim v0.8.7
github.com/docker/go-units v0.4.0
github.com/hashicorp/go-multierror v1.0.0
github.com/klauspost/compress v1.10.4
github.com/klauspost/compress v1.10.5
github.com/klauspost/pgzip v1.2.3
github.com/mattn/go-shellwords v1.0.10
github.com/mistifyio/go-zfs v2.1.1+incompatible

View File

@ -41,8 +41,8 @@ github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.10.4 h1:jFzIFaf586tquEB5EhzQG0HwGNSlgAJpG53G6Ss11wc=
github.com/klauspost/compress v1.10.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.10.5 h1:7q6vHIqubShURwQz8cQK6yIe/xC3IF0Vm7TGfqjewrc=
github.com/klauspost/compress v1.10.5/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/pgzip v1.2.3 h1:Ce2to9wvs/cuJ2b86/CKQoTYr9VHfpanYosZ0UBJqdw=
github.com/klauspost/pgzip v1.2.3/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=

View File

@ -992,6 +992,9 @@ func (r *layerStore) deleteInternal(id string) error {
if err == nil {
os.Remove(r.tspath(id))
delete(r.byid, id)
for _, name := range layer.Names {
delete(r.byname, name)
}
r.idindex.Delete(id)
mountLabel := layer.MountLabel
if layer.MountPoint != "" {

View File

@ -394,7 +394,7 @@ func fillGo18FileTypeBits(mode int64, fi os.FileInfo) int64 {
// to a tar header
func ReadSecurityXattrToTarHeader(path string, hdr *tar.Header) error {
capability, err := system.Lgetxattr(path, "security.capability")
if err != nil && err != system.EOPNOTSUPP {
if err != nil && err != system.EOPNOTSUPP && err != system.ErrNotSupportedPlatform {
return err
}
if capability != nil {
@ -407,7 +407,7 @@ func ReadSecurityXattrToTarHeader(path string, hdr *tar.Header) error {
// ReadUserXattrToTarHeader reads user.* xattr from filesystem to a tar header
func ReadUserXattrToTarHeader(path string, hdr *tar.Header) error {
xattrs, err := system.Llistxattr(path)
if err != nil && err != system.EOPNOTSUPP {
if err != nil && err != system.EOPNOTSUPP && err != system.ErrNotSupportedPlatform {
return err
}
for _, key := range xattrs {

View File

@ -3397,7 +3397,7 @@ func copyStringInterfaceMap(m map[string]interface{}) map[string]interface{} {
}
// defaultConfigFile path to the system wide storage.conf file
const defaultConfigFile = "/etc/containers/storage.conf"
var defaultConfigFile = "/etc/containers/storage.conf"
// AutoUserNsMinSize is the minimum size for automatically created user namespaces
const AutoUserNsMinSize = 1024
@ -3409,6 +3409,11 @@ const AutoUserNsMaxSize = 65536
// creating a user namespace.
const RootAutoUserNsUser = "containers"
// SetDefaultConfigFilePath sets the default configuration to the specified path
func SetDefaultConfigFilePath(path string) {
defaultConfigFile = path
}
// DefaultConfigFile returns the path to the storage config file used
func DefaultConfigFile(rootless bool) (string, error) {
if rootless {

View File

@ -131,17 +131,25 @@ func (b *blockDec) reset(br byteBuffer, windowSize uint64) error {
b.Type = blockType((bh >> 1) & 3)
// find size.
cSize := int(bh >> 3)
maxSize := maxBlockSize
switch b.Type {
case blockTypeReserved:
return ErrReservedBlockType
case blockTypeRLE:
b.RLESize = uint32(cSize)
if b.lowMem {
maxSize = cSize
}
cSize = 1
case blockTypeCompressed:
if debug {
println("Data size on stream:", cSize)
}
b.RLESize = 0
maxSize = maxCompressedBlockSize
if windowSize < maxCompressedBlockSize && b.lowMem {
maxSize = int(windowSize)
}
if cSize > maxCompressedBlockSize || uint64(cSize) > b.WindowSize {
if debug {
printf("compressed block too big: csize:%d block: %+v\n", uint64(cSize), b)
@ -160,8 +168,8 @@ func (b *blockDec) reset(br byteBuffer, windowSize uint64) error {
b.dataStorage = make([]byte, 0, maxBlockSize)
}
}
if cap(b.dst) <= maxBlockSize {
b.dst = make([]byte, 0, maxBlockSize+1)
if cap(b.dst) <= maxSize {
b.dst = make([]byte, 0, maxSize+1)
}
var err error
b.data, err = br.readBig(cSize, b.dataStorage)
@ -679,8 +687,11 @@ func (b *blockDec) decodeCompressed(hist *history) error {
println("initializing sequences:", err)
return err
}
err = seqs.decode(nSeqs, br, hist.b)
hbytes := hist.b
if len(hbytes) > hist.windowSize {
hbytes = hbytes[len(hbytes)-hist.windowSize:]
}
err = seqs.decode(nSeqs, br, hbytes)
if err != nil {
return err
}

View File

@ -233,7 +233,11 @@ func (d *frameDec) reset(br byteBuffer) error {
return ErrWindowSizeTooSmall
}
d.history.windowSize = int(d.WindowSize)
d.history.maxSize = d.history.windowSize + maxBlockSize
if d.o.lowMem && d.history.windowSize < maxBlockSize {
d.history.maxSize = d.history.windowSize * 2
} else {
d.history.maxSize = d.history.windowSize + maxBlockSize
}
// history contains input - maybe we do something
d.rawInput = br
return nil
@ -320,8 +324,8 @@ func (d *frameDec) checkCRC() error {
func (d *frameDec) initAsync() {
if !d.o.lowMem && !d.SingleSegment {
// set max extra size history to 20MB.
d.history.maxSize = d.history.windowSize + maxBlockSize*10
// set max extra size history to 10MB.
d.history.maxSize = d.history.windowSize + maxBlockSize*5
}
// re-alloc if more than one extra block size.
if d.o.lowMem && cap(d.history.b) > d.history.maxSize+maxBlockSize {

View File

@ -69,6 +69,7 @@ type bState struct {
trimSpace bool
toComplete bool
completeFlushed bool
ignoreComplete bool
noPop bool
aDecorators []decor.Decorator
pDecorators []decor.Decorator
@ -170,17 +171,18 @@ func (b *Bar) TraverseDecorators(cb func(decor.Decorator)) {
}
// SetTotal sets total dynamically.
// If total is less or equal to zero it takes progress' current value.
// If complete is true, complete event will be triggered.
// If total is less than or equal to zero it takes progress' current value.
// A complete flag enables or disables complete event on `current >= total`.
func (b *Bar) SetTotal(total int64, complete bool) {
select {
case b.operateState <- func(s *bState) {
s.ignoreComplete = !complete
if total <= 0 {
s.total = s.current
} else {
s.total = total
}
if complete && !s.toComplete {
if !s.ignoreComplete && !s.toComplete {
s.current = s.total
s.toComplete = true
go b.refreshTillShutdown()
@ -197,7 +199,7 @@ func (b *Bar) SetCurrent(current int64) {
s.iterated = true
s.lastN = current - s.current
s.current = current
if s.total > 0 && s.current >= s.total {
if !s.ignoreComplete && s.current >= s.total {
s.current = s.total
s.toComplete = true
go b.refreshTillShutdown()
@ -224,7 +226,7 @@ func (b *Bar) IncrInt64(n int64) {
s.iterated = true
s.lastN = n
s.current += n
if s.total > 0 && s.current >= s.total {
if !s.ignoreComplete && s.current >= s.total {
s.current = s.total
s.toComplete = true
go b.refreshTillShutdown()

View File

@ -76,7 +76,7 @@ func (s *barFiller) SetReverse(reverse bool) {
s.flush = reverseFlush
} else {
s.tip = s.format[rTip]
s.flush = normalFlush
s.flush = regularFlush
}
s.reverse = reverse
}
@ -125,7 +125,7 @@ func (s *barFiller) Fill(w io.Writer, width int, stat *decor.Statistics) {
s.flush(w, bb)
}
func normalFlush(w io.Writer, bb [][]byte) {
func regularFlush(w io.Writer, bb [][]byte) {
for i := 0; i < len(bb); i++ {
w.Write(bb[i])
}

View File

@ -3,8 +3,8 @@ module github.com/vbauerster/mpb/v5
require (
github.com/VividCortex/ewma v1.1.1
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 // indirect
golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f // indirect
)
go 1.14

View File

@ -3,11 +3,11 @@ github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmx
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4 h1:QmwruyY+bKbDDL0BaglrbZABEali68eoMFhTZpCjYVA=
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5 h1:Q7tZBpemrlsc2I7IyODzhtallWRSm4Q0d09pL6XbQtU=
golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f h1:gWF768j/LaZugp8dyS4UwsslYCYz9XgFxvlgsn0n9H8=
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

View File

@ -7,6 +7,9 @@ func Percentage(total, current int64, width int) float64 {
if total <= 0 {
return 0
}
if current >= total {
return float64(width)
}
return float64(int64(width)*current) / float64(total)
}

View File

@ -113,6 +113,7 @@ func NewTerminal(c io.ReadWriter, prompt string) *Terminal {
}
const (
keyCtrlC = 3
keyCtrlD = 4
keyCtrlU = 21
keyEnter = '\r'
@ -151,8 +152,12 @@ func bytesToKey(b []byte, pasteActive bool) (rune, []byte) {
switch b[0] {
case 1: // ^A
return keyHome, b[1:]
case 2: // ^B
return keyLeft, b[1:]
case 5: // ^E
return keyEnd, b[1:]
case 6: // ^F
return keyRight, b[1:]
case 8: // ^H
return keyBackspace, b[1:]
case 11: // ^K
@ -738,6 +743,9 @@ func (t *Terminal) readLine() (line string, err error) {
return "", io.EOF
}
}
if key == keyCtrlC {
return "", io.EOF
}
if key == keyPasteStart {
t.pasteActive = true
if len(t.line) == 0 {

View File

@ -89,7 +89,7 @@ constants.
Adding new syscall numbers is mostly done by running the build on a sufficiently
new installation of the target OS (or updating the source checkouts for the
new build system). However, depending on the OS, you make need to update the
new build system). However, depending on the OS, you may need to update the
parsing in mksysnum.
### mksyscall.go
@ -163,7 +163,7 @@ The merge is performed in the following steps:
## Generated files
### `zerror_${GOOS}_${GOARCH}.go`
### `zerrors_${GOOS}_${GOARCH}.go`
A file containing all of the system's generated error numbers, error strings,
signal numbers, and constants. Generated by `mkerrors.sh` (see above).

View File

@ -486,6 +486,7 @@ ccflags="$@"
$2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||
$2 ~ /^MODULE_INIT_/ ||
$2 !~ "NLA_TYPE_MASK" &&
$2 !~ /^RTC_VL_(ACCURACY|BACKUP|DATA)/ &&
$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTC|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P|NETNSA)_/ ||
$2 ~ /^SIOC/ ||
$2 ~ /^TIOC/ ||

View File

@ -216,6 +216,7 @@ const (
BPF_F_RDONLY = 0x8
BPF_F_RDONLY_PROG = 0x80
BPF_F_RECOMPUTE_CSUM = 0x1
BPF_F_REPLACE = 0x4
BPF_F_REUSE_STACKID = 0x400
BPF_F_SEQ_NUMBER = 0x8
BPF_F_SKIP_FIELD_MASK = 0xff
@ -389,6 +390,7 @@ const (
CLONE_NEWNET = 0x40000000
CLONE_NEWNS = 0x20000
CLONE_NEWPID = 0x20000000
CLONE_NEWTIME = 0x80
CLONE_NEWUSER = 0x10000000
CLONE_NEWUTS = 0x4000000
CLONE_PARENT = 0x8000
@ -737,6 +739,7 @@ const (
GENL_NAMSIZ = 0x10
GENL_START_ALLOC = 0x13
GENL_UNS_ADMIN_PERM = 0x10
GRND_INSECURE = 0x4
GRND_NONBLOCK = 0x1
GRND_RANDOM = 0x2
HDIO_DRIVE_CMD = 0x31f
@ -1487,6 +1490,7 @@ const (
PR_GET_FPEMU = 0x9
PR_GET_FPEXC = 0xb
PR_GET_FP_MODE = 0x2e
PR_GET_IO_FLUSHER = 0x3a
PR_GET_KEEPCAPS = 0x7
PR_GET_NAME = 0x10
PR_GET_NO_NEW_PRIVS = 0x27
@ -1522,6 +1526,7 @@ const (
PR_SET_FPEMU = 0xa
PR_SET_FPEXC = 0xc
PR_SET_FP_MODE = 0x2d
PR_SET_IO_FLUSHER = 0x39
PR_SET_KEEPCAPS = 0x8
PR_SET_MM = 0x23
PR_SET_MM_ARG_END = 0x9
@ -1750,12 +1755,15 @@ const (
RTM_DELRULE = 0x21
RTM_DELTCLASS = 0x29
RTM_DELTFILTER = 0x2d
RTM_DELVLAN = 0x71
RTM_F_CLONED = 0x200
RTM_F_EQUALIZE = 0x400
RTM_F_FIB_MATCH = 0x2000
RTM_F_LOOKUP_TABLE = 0x1000
RTM_F_NOTIFY = 0x100
RTM_F_OFFLOAD = 0x4000
RTM_F_PREFIX = 0x800
RTM_F_TRAP = 0x8000
RTM_GETACTION = 0x32
RTM_GETADDR = 0x16
RTM_GETADDRLABEL = 0x4a
@ -1777,7 +1785,8 @@ const (
RTM_GETSTATS = 0x5e
RTM_GETTCLASS = 0x2a
RTM_GETTFILTER = 0x2e
RTM_MAX = 0x6f
RTM_GETVLAN = 0x72
RTM_MAX = 0x73
RTM_NEWACTION = 0x30
RTM_NEWADDR = 0x14
RTM_NEWADDRLABEL = 0x48
@ -1792,6 +1801,7 @@ const (
RTM_NEWNETCONF = 0x50
RTM_NEWNEXTHOP = 0x68
RTM_NEWNSID = 0x58
RTM_NEWNVLAN = 0x70
RTM_NEWPREFIX = 0x34
RTM_NEWQDISC = 0x24
RTM_NEWROUTE = 0x18
@ -1799,8 +1809,8 @@ const (
RTM_NEWSTATS = 0x5c
RTM_NEWTCLASS = 0x28
RTM_NEWTFILTER = 0x2c
RTM_NR_FAMILIES = 0x18
RTM_NR_MSGTYPES = 0x60
RTM_NR_FAMILIES = 0x19
RTM_NR_MSGTYPES = 0x64
RTM_SETDCB = 0x4f
RTM_SETLINK = 0x13
RTM_SETNEIGHTBL = 0x43
@ -2090,7 +2100,7 @@ const (
TASKSTATS_GENL_NAME = "TASKSTATS"
TASKSTATS_GENL_VERSION = 0x1
TASKSTATS_TYPE_MAX = 0x6
TASKSTATS_VERSION = 0x9
TASKSTATS_VERSION = 0xa
TCIFLUSH = 0x0
TCIOFF = 0x2
TCIOFLUSH = 0x2
@ -2271,7 +2281,7 @@ const (
VMADDR_CID_ANY = 0xffffffff
VMADDR_CID_HOST = 0x2
VMADDR_CID_HYPERVISOR = 0x0
VMADDR_CID_RESERVED = 0x1
VMADDR_CID_LOCAL = 0x1
VMADDR_PORT_ANY = 0xffffffff
VM_SOCKETS_INVALID_VERSION = 0xffffffff
VQUIT = 0x1
@ -2398,6 +2408,7 @@ const (
XENFS_SUPER_MAGIC = 0xabba1974
XFS_SUPER_MAGIC = 0x58465342
Z3FOLD_MAGIC = 0x33
ZONEFS_MAGIC = 0x5a4f4653
ZSMALLOC_MAGIC = 0x58295829
)

View File

@ -431,4 +431,6 @@ const (
SYS_FSPICK = 433
SYS_PIDFD_OPEN = 434
SYS_CLONE3 = 435
SYS_OPENAT2 = 437
SYS_PIDFD_GETFD = 438
)

View File

@ -353,4 +353,6 @@ const (
SYS_FSPICK = 433
SYS_PIDFD_OPEN = 434
SYS_CLONE3 = 435
SYS_OPENAT2 = 437
SYS_PIDFD_GETFD = 438
)

View File

@ -395,4 +395,6 @@ const (
SYS_FSPICK = 433
SYS_PIDFD_OPEN = 434
SYS_CLONE3 = 435
SYS_OPENAT2 = 437
SYS_PIDFD_GETFD = 438
)

View File

@ -298,4 +298,6 @@ const (
SYS_FSPICK = 433
SYS_PIDFD_OPEN = 434
SYS_CLONE3 = 435
SYS_OPENAT2 = 437
SYS_PIDFD_GETFD = 438
)

View File

@ -416,4 +416,6 @@ const (
SYS_FSPICK = 4433
SYS_PIDFD_OPEN = 4434
SYS_CLONE3 = 4435
SYS_OPENAT2 = 4437
SYS_PIDFD_GETFD = 4438
)

View File

@ -346,4 +346,6 @@ const (
SYS_FSPICK = 5433
SYS_PIDFD_OPEN = 5434
SYS_CLONE3 = 5435
SYS_OPENAT2 = 5437
SYS_PIDFD_GETFD = 5438
)

View File

@ -346,4 +346,6 @@ const (
SYS_FSPICK = 5433
SYS_PIDFD_OPEN = 5434
SYS_CLONE3 = 5435
SYS_OPENAT2 = 5437
SYS_PIDFD_GETFD = 5438
)

View File

@ -416,4 +416,6 @@ const (
SYS_FSPICK = 4433
SYS_PIDFD_OPEN = 4434
SYS_CLONE3 = 4435
SYS_OPENAT2 = 4437
SYS_PIDFD_GETFD = 4438
)

View File

@ -395,4 +395,6 @@ const (
SYS_FSPICK = 433
SYS_PIDFD_OPEN = 434
SYS_CLONE3 = 435
SYS_OPENAT2 = 437
SYS_PIDFD_GETFD = 438
)

View File

@ -395,4 +395,6 @@ const (
SYS_FSPICK = 433
SYS_PIDFD_OPEN = 434
SYS_CLONE3 = 435
SYS_OPENAT2 = 437
SYS_PIDFD_GETFD = 438
)

View File

@ -297,4 +297,6 @@ const (
SYS_FSPICK = 433
SYS_PIDFD_OPEN = 434
SYS_CLONE3 = 435
SYS_OPENAT2 = 437
SYS_PIDFD_GETFD = 438
)

View File

@ -360,4 +360,6 @@ const (
SYS_FSPICK = 433
SYS_PIDFD_OPEN = 434
SYS_CLONE3 = 435
SYS_OPENAT2 = 437
SYS_PIDFD_GETFD = 438
)

View File

@ -374,4 +374,6 @@ const (
SYS_FSMOUNT = 432
SYS_FSPICK = 433
SYS_PIDFD_OPEN = 434
SYS_OPENAT2 = 437
SYS_PIDFD_GETFD = 438
)

View File

@ -114,7 +114,8 @@ type FscryptKeySpecifier struct {
type FscryptAddKeyArg struct {
Key_spec FscryptKeySpecifier
Raw_size uint32
_ [9]uint32
Key_id uint32
_ [8]uint32
}
type FscryptRemoveKeyArg struct {
@ -479,7 +480,7 @@ const (
IFLA_NEW_IFINDEX = 0x31
IFLA_MIN_MTU = 0x32
IFLA_MAX_MTU = 0x33
IFLA_MAX = 0x35
IFLA_MAX = 0x36
IFLA_INFO_KIND = 0x1
IFLA_INFO_DATA = 0x2
IFLA_INFO_XSTATS = 0x3
@ -2308,3 +2309,32 @@ type FsverityEnableArg struct {
Sig_ptr uint64
_ [11]uint64
}
type Nhmsg struct {
Family uint8
Scope uint8
Protocol uint8
Resvd uint8
Flags uint32
}
type NexthopGrp struct {
Id uint32
Weight uint8
Resvd1 uint8
Resvd2 uint16
}
const (
NHA_UNSPEC = 0x0
NHA_ID = 0x1
NHA_GROUP = 0x2
NHA_GROUP_TYPE = 0x3
NHA_BLACKHOLE = 0x4
NHA_OIF = 0x5
NHA_GATEWAY = 0x6
NHA_ENCAP_TYPE = 0x7
NHA_ENCAP = 0x8
NHA_GROUPS = 0x9
NHA_MASTER = 0xa
)

View File

@ -287,6 +287,7 @@ type Taskstats struct {
Freepages_delay_total uint64
Thrashing_count uint64
Thrashing_delay_total uint64
Ac_btime64 uint64
}
type cpuMask uint32

View File

@ -298,6 +298,7 @@ type Taskstats struct {
Freepages_delay_total uint64
Thrashing_count uint64
Thrashing_delay_total uint64
Ac_btime64 uint64
}
type cpuMask uint64

View File

@ -276,6 +276,7 @@ type Taskstats struct {
Freepages_delay_total uint64
Thrashing_count uint64
Thrashing_delay_total uint64
Ac_btime64 uint64
}
type cpuMask uint32

View File

@ -277,6 +277,7 @@ type Taskstats struct {
Freepages_delay_total uint64
Thrashing_count uint64
Thrashing_delay_total uint64
Ac_btime64 uint64
}
type cpuMask uint64

View File

@ -281,6 +281,7 @@ type Taskstats struct {
Freepages_delay_total uint64
Thrashing_count uint64
Thrashing_delay_total uint64
Ac_btime64 uint64
}
type cpuMask uint32

View File

@ -280,6 +280,7 @@ type Taskstats struct {
Freepages_delay_total uint64
Thrashing_count uint64
Thrashing_delay_total uint64
Ac_btime64 uint64
}
type cpuMask uint64

View File

@ -280,6 +280,7 @@ type Taskstats struct {
Freepages_delay_total uint64
Thrashing_count uint64
Thrashing_delay_total uint64
Ac_btime64 uint64
}
type cpuMask uint64

View File

@ -281,6 +281,7 @@ type Taskstats struct {
Freepages_delay_total uint64
Thrashing_count uint64
Thrashing_delay_total uint64
Ac_btime64 uint64
}
type cpuMask uint32

View File

@ -287,6 +287,7 @@ type Taskstats struct {
Freepages_delay_total uint64
Thrashing_count uint64
Thrashing_delay_total uint64
Ac_btime64 uint64
}
type cpuMask uint64

View File

@ -287,6 +287,7 @@ type Taskstats struct {
Freepages_delay_total uint64
Thrashing_count uint64
Thrashing_delay_total uint64
Ac_btime64 uint64
}
type cpuMask uint64

View File

@ -305,6 +305,7 @@ type Taskstats struct {
Freepages_delay_total uint64
Thrashing_count uint64
Thrashing_delay_total uint64
Ac_btime64 uint64
}
type cpuMask uint64

View File

@ -300,6 +300,7 @@ type Taskstats struct {
Freepages_delay_total uint64
Thrashing_count uint64
Thrashing_delay_total uint64
Ac_btime64 uint64
}
type cpuMask uint64

View File

@ -282,6 +282,7 @@ type Taskstats struct {
Freepages_delay_total uint64
Thrashing_count uint64
Thrashing_delay_total uint64
Ac_btime64 uint64
}
type cpuMask uint64

13
vendor/modules.txt vendored
View File

@ -36,7 +36,7 @@ github.com/containerd/cgroups/stats/v1
github.com/containerd/containerd/errdefs
github.com/containerd/containerd/log
github.com/containerd/containerd/platforms
# github.com/containers/image/v5 v5.4.3
# github.com/containers/image/v5 v5.4.4-0.20200504143706-d52a99c5329e
github.com/containers/image/v5/copy
github.com/containers/image/v5/directory
github.com/containers/image/v5/directory/explicitfilepath
@ -51,6 +51,7 @@ github.com/containers/image/v5/internal/iolimits
github.com/containers/image/v5/internal/pkg/keyctl
github.com/containers/image/v5/internal/pkg/platform
github.com/containers/image/v5/internal/tmpdir
github.com/containers/image/v5/internal/uploadreader
github.com/containers/image/v5/manifest
github.com/containers/image/v5/oci/archive
github.com/containers/image/v5/oci/internal
@ -89,7 +90,7 @@ github.com/containers/ocicrypt/keywrap/pgp
github.com/containers/ocicrypt/keywrap/pkcs7
github.com/containers/ocicrypt/spec
github.com/containers/ocicrypt/utils
# github.com/containers/storage v1.19.0
# github.com/containers/storage v1.19.1
github.com/containers/storage
github.com/containers/storage/drivers
github.com/containers/storage/drivers/aufs
@ -203,7 +204,7 @@ github.com/hashicorp/golang-lru/simplelru
github.com/imdario/mergo
# github.com/inconshreveable/mousetrap v1.0.0
github.com/inconshreveable/mousetrap
# github.com/klauspost/compress v1.10.4
# github.com/klauspost/compress v1.10.5
github.com/klauspost/compress/flate
github.com/klauspost/compress/fse
github.com/klauspost/compress/huff0
@ -291,7 +292,7 @@ github.com/ulikunitz/xz/lzma
github.com/vbatts/tar-split/archive/tar
github.com/vbatts/tar-split/tar/asm
github.com/vbatts/tar-split/tar/storage
# github.com/vbauerster/mpb/v5 v5.0.3
# github.com/vbauerster/mpb/v5 v5.0.4
github.com/vbauerster/mpb/v5
github.com/vbauerster/mpb/v5/cwriter
github.com/vbauerster/mpb/v5/decor
@ -312,7 +313,7 @@ go.opencensus.io/trace/internal
go.opencensus.io/trace/tracestate
# go4.org v0.0.0-20190218023631-ce4c26f7be8e
go4.org/errorutil
# golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59
# golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5
golang.org/x/crypto/cast5
golang.org/x/crypto/ed25519
golang.org/x/crypto/ed25519/internal/edwards25519
@ -334,7 +335,7 @@ golang.org/x/net/internal/socks
golang.org/x/net/proxy
# golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a
golang.org/x/sync/semaphore
# golang.org/x/sys v0.0.0-20200327173247-9dae0f8f5775
# golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f
golang.org/x/sys/unix
golang.org/x/sys/windows
# golang.org/x/text v0.3.2