mirror of
https://github.com/containers/skopeo.git
synced 2025-07-06 03:16:55 +00:00
Merge pull request #1467 from containers/dependabot/go_modules/github.com/containers/storage-1.37.0
Bump github.com/containers/storage from 1.36.0 to 1.37.0
This commit is contained in:
commit
a95b0cc6fa
2
go.mod
2
go.mod
@ -6,7 +6,7 @@ require (
|
||||
github.com/containers/common v0.46.0
|
||||
github.com/containers/image/v5 v5.16.0
|
||||
github.com/containers/ocicrypt v1.1.2
|
||||
github.com/containers/storage v1.36.0
|
||||
github.com/containers/storage v1.37.0
|
||||
github.com/docker/docker v20.10.8+incompatible
|
||||
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0
|
||||
|
15
go.sum
15
go.sum
@ -200,8 +200,9 @@ github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJ
|
||||
github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c=
|
||||
github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
|
||||
github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.8.0 h1:oA1wx8kTFfImfsT5bScbrZd8gK+WtQnn15q82Djvm0Y=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.8.0/go.mod h1:mwIwuwb+D8FX2t45Trwi0hmWmZm5VW7zPP/rekwhWQU=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.9.0 h1:PkB6BSTfOKX23erT2GkoUKkJEcXfNcyKskIViK770v8=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.9.0/go.mod h1:aE5PCyhFMwR8sbrErO5eM2GcvkyXTTJremG883D4qF0=
|
||||
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
|
||||
github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
|
||||
github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8=
|
||||
@ -233,8 +234,9 @@ github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B
|
||||
github.com/containers/ocicrypt v1.1.2 h1:Ez+GAMP/4GLix5Ywo/fL7O0nY771gsBIigiqUm1aXz0=
|
||||
github.com/containers/ocicrypt v1.1.2/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY=
|
||||
github.com/containers/storage v1.35.0/go.mod h1:qzYhasQP2/V9D9XdO+vRwkHBhsBO0oznMLzzRDQ8s20=
|
||||
github.com/containers/storage v1.36.0 h1:OelxllCW19tnNngYuZw2ty/zLabVMG5rSs3KSwO1Lzc=
|
||||
github.com/containers/storage v1.36.0/go.mod h1:vbd3SKVQNHdmU5qQI6hTEcKPxnZkGqydG4f6uwrI5a8=
|
||||
github.com/containers/storage v1.37.0 h1:HVhDsur6sx889ZIZ1d1kEiOzv3gsr5q0diX2VZmOdSg=
|
||||
github.com/containers/storage v1.37.0/go.mod h1:kqeJeS0b7DO2ZT1nVWs0XufrmPFbgV3c+Q/45RlH6r4=
|
||||
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-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
||||
@ -487,8 +489,9 @@ github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
@ -502,8 +505,9 @@ github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0
|
||||
github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
|
||||
github.com/klauspost/compress v1.13.5 h1:9O69jUPDcsT9fEm74W92rZL9FQY7rCdaXVneq+yyzl4=
|
||||
github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
|
||||
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
@ -568,8 +572,9 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
|
||||
|
131
vendor/github.com/containerd/stargz-snapshotter/estargz/estargz.go
generated
vendored
131
vendor/github.com/containerd/stargz-snapshotter/estargz/estargz.go
generated
vendored
@ -23,7 +23,6 @@
|
||||
package estargz
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bufio"
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
@ -42,6 +41,7 @@ import (
|
||||
"github.com/containerd/stargz-snapshotter/estargz/errorutil"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/vbatts/tar-split/archive/tar"
|
||||
)
|
||||
|
||||
// A Reader permits random access reads from a stargz file.
|
||||
@ -95,10 +95,10 @@ func WithTelemetry(telemetry *Telemetry) OpenOption {
|
||||
}
|
||||
}
|
||||
|
||||
// A func which takes start time and records the diff
|
||||
// MeasureLatencyHook is a func which takes start time and records the diff
|
||||
type MeasureLatencyHook func(time.Time)
|
||||
|
||||
// A struct which defines telemetry hooks. By implementing these hooks you should be able to record
|
||||
// Telemetry is a struct which defines telemetry hooks. By implementing these hooks you should be able to record
|
||||
// the latency metrics of the respective steps of estargz open operation. To be used with estargz.OpenWithTelemetry(...)
|
||||
type Telemetry struct {
|
||||
GetFooterLatency MeasureLatencyHook // measure time to get stargz footer (in milliseconds)
|
||||
@ -146,7 +146,7 @@ func Open(sr *io.SectionReader, opt ...OpenOption) (*Reader, error) {
|
||||
fSize := d.FooterSize()
|
||||
fOffset := positive(int64(len(footer)) - fSize)
|
||||
maybeTocBytes := footer[:fOffset]
|
||||
tocOffset, tocSize, err := d.ParseFooter(footer[fOffset:])
|
||||
_, tocOffset, tocSize, err := d.ParseFooter(footer[fOffset:])
|
||||
if err != nil {
|
||||
allErr = append(allErr, err)
|
||||
continue
|
||||
@ -187,7 +187,7 @@ func OpenFooter(sr *io.SectionReader) (tocOffset int64, footerSize int64, rErr e
|
||||
for _, d := range []Decompressor{new(GzipDecompressor), new(legacyGzipDecompressor)} {
|
||||
fSize := d.FooterSize()
|
||||
fOffset := positive(int64(len(footer)) - fSize)
|
||||
tocOffset, _, err := d.ParseFooter(footer[fOffset:])
|
||||
_, tocOffset, _, err := d.ParseFooter(footer[fOffset:])
|
||||
if err == nil {
|
||||
return tocOffset, fSize, err
|
||||
}
|
||||
@ -326,6 +326,10 @@ func (r *Reader) getOrCreateDir(d string) *TOCEntry {
|
||||
return e
|
||||
}
|
||||
|
||||
func (r *Reader) TOCDigest() digest.Digest {
|
||||
return r.tocDigest
|
||||
}
|
||||
|
||||
// VerifyTOC checks that the TOC JSON in the passed blob matches the
|
||||
// passed digests and that the TOC JSON contains digests for all chunks
|
||||
// contained in the blob. If the verification succceeds, this function
|
||||
@ -335,7 +339,12 @@ func (r *Reader) VerifyTOC(tocDigest digest.Digest) (TOCEntryVerifier, error) {
|
||||
if r.tocDigest != tocDigest {
|
||||
return nil, fmt.Errorf("invalid TOC JSON %q; want %q", r.tocDigest, tocDigest)
|
||||
}
|
||||
return r.Verifiers()
|
||||
}
|
||||
|
||||
// Verifiers returns TOCEntryVerifier of this chunk. Use VerifyTOC instead in most cases
|
||||
// because this doesn't verify TOC.
|
||||
func (r *Reader) Verifiers() (TOCEntryVerifier, error) {
|
||||
chunkDigestMap := make(map[int64]digest.Digest) // map from chunk offset to the chunk digest
|
||||
regDigestMap := make(map[int64]digest.Digest) // map from chunk offset to the reg file digest
|
||||
var chunkDigestMapIncomplete bool
|
||||
@ -591,6 +600,11 @@ type currentCompressionWriter struct{ w *Writer }
|
||||
|
||||
func (ccw currentCompressionWriter) Write(p []byte) (int, error) {
|
||||
ccw.w.diffHash.Write(p)
|
||||
if ccw.w.gz == nil {
|
||||
if err := ccw.w.condOpenGz(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
return ccw.w.gz.Write(p)
|
||||
}
|
||||
|
||||
@ -601,6 +615,25 @@ func (w *Writer) chunkSize() int {
|
||||
return w.ChunkSize
|
||||
}
|
||||
|
||||
// Unpack decompresses the given estargz blob and returns a ReadCloser of the tar blob.
|
||||
// TOC JSON and footer are removed.
|
||||
func Unpack(sr *io.SectionReader, c Decompressor) (io.ReadCloser, error) {
|
||||
footerSize := c.FooterSize()
|
||||
if sr.Size() < footerSize {
|
||||
return nil, fmt.Errorf("blob is too small; %d < %d", sr.Size(), footerSize)
|
||||
}
|
||||
footerOffset := sr.Size() - footerSize
|
||||
footer := make([]byte, footerSize)
|
||||
if _, err := sr.ReadAt(footer, footerOffset); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blobPayloadSize, _, _, err := c.ParseFooter(footer)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to parse footer")
|
||||
}
|
||||
return c.Reader(io.LimitReader(sr, blobPayloadSize))
|
||||
}
|
||||
|
||||
// NewWriter returns a new stargz writer (gzip-based) writing to w.
|
||||
//
|
||||
// The writer must be closed to write its trailing table of contents.
|
||||
@ -616,7 +649,7 @@ func NewWriterLevel(w io.Writer, compressionLevel int) *Writer {
|
||||
return NewWriterWithCompressor(w, NewGzipCompressorWithLevel(compressionLevel))
|
||||
}
|
||||
|
||||
// NewWriterLevel returns a new stargz writer writing to w.
|
||||
// NewWriterWithCompressor returns a new stargz writer writing to w.
|
||||
// The compression method is configurable.
|
||||
//
|
||||
// The writer must be closed to write its trailing table of contents.
|
||||
@ -696,29 +729,71 @@ func (w *Writer) condOpenGz() (err error) {
|
||||
// each of its contents to w.
|
||||
//
|
||||
// The input r can optionally be gzip compressed but the output will
|
||||
// always be gzip compressed.
|
||||
// always be compressed by the specified compressor.
|
||||
func (w *Writer) AppendTar(r io.Reader) error {
|
||||
return w.appendTar(r, false)
|
||||
}
|
||||
|
||||
// AppendTarLossLess reads the tar or tar.gz file from r and appends
|
||||
// each of its contents to w.
|
||||
//
|
||||
// The input r can optionally be gzip compressed but the output will
|
||||
// always be compressed by the specified compressor.
|
||||
//
|
||||
// The difference of this func with AppendTar is that this writes
|
||||
// the input tar stream into w without any modification (e.g. to header bytes).
|
||||
//
|
||||
// Note that if the input tar stream already contains TOC JSON, this returns
|
||||
// error because w cannot overwrite the TOC JSON to the one generated by w without
|
||||
// lossy modification. To avoid this error, if the input stream is known to be stargz/estargz,
|
||||
// you shoud decompress it and remove TOC JSON in advance.
|
||||
func (w *Writer) AppendTarLossLess(r io.Reader) error {
|
||||
return w.appendTar(r, true)
|
||||
}
|
||||
|
||||
func (w *Writer) appendTar(r io.Reader, lossless bool) error {
|
||||
var src io.Reader
|
||||
br := bufio.NewReader(r)
|
||||
var tr *tar.Reader
|
||||
if isGzip(br) {
|
||||
// NewReader can't fail if isGzip returned true.
|
||||
zr, _ := gzip.NewReader(br)
|
||||
tr = tar.NewReader(zr)
|
||||
src = zr
|
||||
} else {
|
||||
tr = tar.NewReader(br)
|
||||
src = io.Reader(br)
|
||||
}
|
||||
dst := currentCompressionWriter{w}
|
||||
var tw *tar.Writer
|
||||
if !lossless {
|
||||
tw = tar.NewWriter(dst) // use tar writer only when this isn't lossless mode.
|
||||
}
|
||||
tr := tar.NewReader(src)
|
||||
if lossless {
|
||||
tr.RawAccounting = true
|
||||
}
|
||||
for {
|
||||
h, err := tr.Next()
|
||||
if err == io.EOF {
|
||||
if lossless {
|
||||
if remain := tr.RawBytes(); len(remain) > 0 {
|
||||
// Collect the remaining null bytes.
|
||||
// https://github.com/vbatts/tar-split/blob/80a436fd6164c557b131f7c59ed69bd81af69761/concept/main.go#L49-L53
|
||||
if _, err := dst.Write(remain); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("error reading from source tar: tar.Reader.Next: %v", err)
|
||||
}
|
||||
if h.Name == TOCTarName {
|
||||
if cleanEntryName(h.Name) == TOCTarName {
|
||||
// It is possible for a layer to be "stargzified" twice during the
|
||||
// distribution lifecycle. So we reserve "TOCTarName" here to avoid
|
||||
// duplicated entries in the resulting layer.
|
||||
if lossless {
|
||||
// We cannot handle this in lossless way.
|
||||
return fmt.Errorf("existing TOC JSON is not allowed; decompress layer before append")
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
@ -744,9 +819,14 @@ func (w *Writer) AppendTar(r io.Reader) error {
|
||||
if err := w.condOpenGz(); err != nil {
|
||||
return err
|
||||
}
|
||||
tw := tar.NewWriter(currentCompressionWriter{w})
|
||||
if err := tw.WriteHeader(h); err != nil {
|
||||
return err
|
||||
if tw != nil {
|
||||
if err := tw.WriteHeader(h); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if _, err := dst.Write(tr.RawBytes()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
switch h.Typeflag {
|
||||
case tar.TypeLink:
|
||||
@ -808,7 +888,13 @@ func (w *Writer) AppendTar(r io.Reader) error {
|
||||
}
|
||||
|
||||
teeChunk := io.TeeReader(tee, chunkDigest.Hash())
|
||||
if _, err := io.CopyN(tw, teeChunk, chunkSize); err != nil {
|
||||
var out io.Writer
|
||||
if tw != nil {
|
||||
out = tw
|
||||
} else {
|
||||
out = dst
|
||||
}
|
||||
if _, err := io.CopyN(out, teeChunk, chunkSize); err != nil {
|
||||
return fmt.Errorf("error copying %q: %v", h.Name, err)
|
||||
}
|
||||
ent.ChunkDigest = chunkDigest.Digest().String()
|
||||
@ -825,11 +911,18 @@ func (w *Writer) AppendTar(r io.Reader) error {
|
||||
if payloadDigest != nil {
|
||||
regFileEntry.Digest = payloadDigest.Digest().String()
|
||||
}
|
||||
if err := tw.Flush(); err != nil {
|
||||
return err
|
||||
if tw != nil {
|
||||
if err := tw.Flush(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
remainDest := ioutil.Discard
|
||||
if lossless {
|
||||
remainDest = dst // Preserve the remaining bytes in lossless mode
|
||||
}
|
||||
_, err := io.Copy(remainDest, src)
|
||||
return err
|
||||
}
|
||||
|
||||
// DiffID returns the SHA-256 of the uncompressed tar bytes.
|
||||
|
3
vendor/github.com/containerd/stargz-snapshotter/estargz/go.mod
generated
vendored
3
vendor/github.com/containerd/stargz-snapshotter/estargz/go.mod
generated
vendored
@ -3,8 +3,9 @@ module github.com/containerd/stargz-snapshotter/estargz
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/klauspost/compress v1.13.5
|
||||
github.com/klauspost/compress v1.13.6
|
||||
github.com/opencontainers/go-digest v1.0.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/vbatts/tar-split v0.11.2
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
|
||||
)
|
||||
|
18
vendor/github.com/containerd/stargz-snapshotter/estargz/go.sum
generated
vendored
18
vendor/github.com/containerd/stargz-snapshotter/estargz/go.sum
generated
vendored
@ -1,8 +1,22 @@
|
||||
github.com/klauspost/compress v1.13.5 h1:9O69jUPDcsT9fEm74W92rZL9FQY7rCdaXVneq+yyzl4=
|
||||
github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlIME=
|
||||
github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
30
vendor/github.com/containerd/stargz-snapshotter/estargz/gzip.go
generated
vendored
30
vendor/github.com/containerd/stargz-snapshotter/estargz/gzip.go
generated
vendored
@ -124,31 +124,31 @@ func (gz *GzipDecompressor) ParseTOC(r io.Reader) (toc *JTOC, tocDgst digest.Dig
|
||||
return parseTOCEStargz(r)
|
||||
}
|
||||
|
||||
func (gz *GzipDecompressor) ParseFooter(p []byte) (tocOffset, tocSize int64, err error) {
|
||||
func (gz *GzipDecompressor) ParseFooter(p []byte) (blobPayloadSize, tocOffset, tocSize int64, err error) {
|
||||
if len(p) != FooterSize {
|
||||
return 0, 0, fmt.Errorf("invalid length %d cannot be parsed", len(p))
|
||||
return 0, 0, 0, fmt.Errorf("invalid length %d cannot be parsed", len(p))
|
||||
}
|
||||
zr, err := gzip.NewReader(bytes.NewReader(p))
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
return 0, 0, 0, err
|
||||
}
|
||||
defer zr.Close()
|
||||
extra := zr.Header.Extra
|
||||
si1, si2, subfieldlen, subfield := extra[0], extra[1], extra[2:4], extra[4:]
|
||||
if si1 != 'S' || si2 != 'G' {
|
||||
return 0, 0, fmt.Errorf("invalid subfield IDs: %q, %q; want E, S", si1, si2)
|
||||
return 0, 0, 0, fmt.Errorf("invalid subfield IDs: %q, %q; want E, S", si1, si2)
|
||||
}
|
||||
if slen := binary.LittleEndian.Uint16(subfieldlen); slen != uint16(16+len("STARGZ")) {
|
||||
return 0, 0, fmt.Errorf("invalid length of subfield %d; want %d", slen, 16+len("STARGZ"))
|
||||
return 0, 0, 0, fmt.Errorf("invalid length of subfield %d; want %d", slen, 16+len("STARGZ"))
|
||||
}
|
||||
if string(subfield[16:]) != "STARGZ" {
|
||||
return 0, 0, fmt.Errorf("STARGZ magic string must be included in the footer subfield")
|
||||
return 0, 0, 0, fmt.Errorf("STARGZ magic string must be included in the footer subfield")
|
||||
}
|
||||
tocOffset, err = strconv.ParseInt(string(subfield[:16]), 16, 64)
|
||||
if err != nil {
|
||||
return 0, 0, errors.Wrapf(err, "legacy: failed to parse toc offset")
|
||||
return 0, 0, 0, errors.Wrapf(err, "legacy: failed to parse toc offset")
|
||||
}
|
||||
return tocOffset, 0, nil
|
||||
return tocOffset, tocOffset, 0, nil
|
||||
}
|
||||
|
||||
func (gz *GzipDecompressor) FooterSize() int64 {
|
||||
@ -165,27 +165,27 @@ func (gz *legacyGzipDecompressor) ParseTOC(r io.Reader) (toc *JTOC, tocDgst dige
|
||||
return parseTOCEStargz(r)
|
||||
}
|
||||
|
||||
func (gz *legacyGzipDecompressor) ParseFooter(p []byte) (tocOffset, tocSize int64, err error) {
|
||||
func (gz *legacyGzipDecompressor) ParseFooter(p []byte) (blobPayloadSize, tocOffset, tocSize int64, err error) {
|
||||
if len(p) != legacyFooterSize {
|
||||
return 0, 0, fmt.Errorf("legacy: invalid length %d cannot be parsed", len(p))
|
||||
return 0, 0, 0, fmt.Errorf("legacy: invalid length %d cannot be parsed", len(p))
|
||||
}
|
||||
zr, err := gzip.NewReader(bytes.NewReader(p))
|
||||
if err != nil {
|
||||
return 0, 0, errors.Wrapf(err, "legacy: failed to get footer gzip reader")
|
||||
return 0, 0, 0, errors.Wrapf(err, "legacy: failed to get footer gzip reader")
|
||||
}
|
||||
defer zr.Close()
|
||||
extra := zr.Header.Extra
|
||||
if len(extra) != 16+len("STARGZ") {
|
||||
return 0, 0, fmt.Errorf("legacy: invalid stargz's extra field size")
|
||||
return 0, 0, 0, fmt.Errorf("legacy: invalid stargz's extra field size")
|
||||
}
|
||||
if string(extra[16:]) != "STARGZ" {
|
||||
return 0, 0, fmt.Errorf("legacy: magic string STARGZ not found")
|
||||
return 0, 0, 0, fmt.Errorf("legacy: magic string STARGZ not found")
|
||||
}
|
||||
tocOffset, err = strconv.ParseInt(string(extra[:16]), 16, 64)
|
||||
if err != nil {
|
||||
return 0, 0, errors.Wrapf(err, "legacy: failed to parse toc offset")
|
||||
return 0, 0, 0, errors.Wrapf(err, "legacy: failed to parse toc offset")
|
||||
}
|
||||
return tocOffset, 0, nil
|
||||
return tocOffset, tocOffset, 0, nil
|
||||
}
|
||||
|
||||
func (gz *legacyGzipDecompressor) FooterSize() int64 {
|
||||
|
494
vendor/github.com/containerd/stargz-snapshotter/estargz/testutil.go
generated
vendored
494
vendor/github.com/containerd/stargz-snapshotter/estargz/testutil.go
generated
vendored
@ -148,93 +148,96 @@ func testBuild(t *testing.T, controllers ...TestingController) {
|
||||
srcCompression := srcCompression
|
||||
for _, cl := range controllers {
|
||||
cl := cl
|
||||
for _, prefix := range allowedPrefix {
|
||||
prefix := prefix
|
||||
t.Run(tt.name+"-"+fmt.Sprintf("compression=%v-prefix=%q-src=%d", cl, prefix, srcCompression), func(t *testing.T) {
|
||||
tarBlob := buildTarStatic(t, tt.in, prefix)
|
||||
// Test divideEntries()
|
||||
entries, err := sortEntries(tarBlob, nil, nil) // identical order
|
||||
if err != nil {
|
||||
t.Fatalf("faield to parse tar: %v", err)
|
||||
}
|
||||
var merged []*entry
|
||||
for _, part := range divideEntries(entries, 4) {
|
||||
merged = append(merged, part...)
|
||||
}
|
||||
if !reflect.DeepEqual(entries, merged) {
|
||||
for _, e := range entries {
|
||||
t.Logf("Original: %v", e.header)
|
||||
for _, srcTarFormat := range []tar.Format{tar.FormatUSTAR, tar.FormatPAX, tar.FormatGNU} {
|
||||
srcTarFormat := srcTarFormat
|
||||
for _, prefix := range allowedPrefix {
|
||||
prefix := prefix
|
||||
t.Run(tt.name+"-"+fmt.Sprintf("compression=%v,prefix=%q,src=%d,format=%s", cl, prefix, srcCompression, srcTarFormat), func(t *testing.T) {
|
||||
tarBlob := buildTar(t, tt.in, prefix, srcTarFormat)
|
||||
// Test divideEntries()
|
||||
entries, err := sortEntries(tarBlob, nil, nil) // identical order
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse tar: %v", err)
|
||||
}
|
||||
for _, e := range merged {
|
||||
t.Logf("Merged: %v", e.header)
|
||||
var merged []*entry
|
||||
for _, part := range divideEntries(entries, 4) {
|
||||
merged = append(merged, part...)
|
||||
}
|
||||
if !reflect.DeepEqual(entries, merged) {
|
||||
for _, e := range entries {
|
||||
t.Logf("Original: %v", e.header)
|
||||
}
|
||||
for _, e := range merged {
|
||||
t.Logf("Merged: %v", e.header)
|
||||
}
|
||||
t.Errorf("divided entries couldn't be merged")
|
||||
return
|
||||
}
|
||||
t.Errorf("divided entries couldn't be merged")
|
||||
return
|
||||
}
|
||||
|
||||
// Prepare sample data
|
||||
wantBuf := new(bytes.Buffer)
|
||||
sw := NewWriterWithCompressor(wantBuf, cl)
|
||||
sw.ChunkSize = tt.chunkSize
|
||||
if err := sw.AppendTar(tarBlob); err != nil {
|
||||
t.Fatalf("faield to append tar to want stargz: %v", err)
|
||||
}
|
||||
if _, err := sw.Close(); err != nil {
|
||||
t.Fatalf("faield to prepare want stargz: %v", err)
|
||||
}
|
||||
wantData := wantBuf.Bytes()
|
||||
want, err := Open(io.NewSectionReader(
|
||||
bytes.NewReader(wantData), 0, int64(len(wantData))),
|
||||
WithDecompressors(cl),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse the want stargz: %v", err)
|
||||
}
|
||||
// Prepare sample data
|
||||
wantBuf := new(bytes.Buffer)
|
||||
sw := NewWriterWithCompressor(wantBuf, cl)
|
||||
sw.ChunkSize = tt.chunkSize
|
||||
if err := sw.AppendTar(tarBlob); err != nil {
|
||||
t.Fatalf("failed to append tar to want stargz: %v", err)
|
||||
}
|
||||
if _, err := sw.Close(); err != nil {
|
||||
t.Fatalf("failed to prepare want stargz: %v", err)
|
||||
}
|
||||
wantData := wantBuf.Bytes()
|
||||
want, err := Open(io.NewSectionReader(
|
||||
bytes.NewReader(wantData), 0, int64(len(wantData))),
|
||||
WithDecompressors(cl),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse the want stargz: %v", err)
|
||||
}
|
||||
|
||||
// Prepare testing data
|
||||
rc, err := Build(compressBlob(t, tarBlob, srcCompression),
|
||||
WithChunkSize(tt.chunkSize), WithCompression(cl))
|
||||
if err != nil {
|
||||
t.Fatalf("faield to build stargz: %v", err)
|
||||
}
|
||||
defer rc.Close()
|
||||
gotBuf := new(bytes.Buffer)
|
||||
if _, err := io.Copy(gotBuf, rc); err != nil {
|
||||
t.Fatalf("failed to copy built stargz blob: %v", err)
|
||||
}
|
||||
gotData := gotBuf.Bytes()
|
||||
got, err := Open(io.NewSectionReader(
|
||||
bytes.NewReader(gotBuf.Bytes()), 0, int64(len(gotData))),
|
||||
WithDecompressors(cl),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse the got stargz: %v", err)
|
||||
}
|
||||
// Prepare testing data
|
||||
rc, err := Build(compressBlob(t, tarBlob, srcCompression),
|
||||
WithChunkSize(tt.chunkSize), WithCompression(cl))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to build stargz: %v", err)
|
||||
}
|
||||
defer rc.Close()
|
||||
gotBuf := new(bytes.Buffer)
|
||||
if _, err := io.Copy(gotBuf, rc); err != nil {
|
||||
t.Fatalf("failed to copy built stargz blob: %v", err)
|
||||
}
|
||||
gotData := gotBuf.Bytes()
|
||||
got, err := Open(io.NewSectionReader(
|
||||
bytes.NewReader(gotBuf.Bytes()), 0, int64(len(gotData))),
|
||||
WithDecompressors(cl),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse the got stargz: %v", err)
|
||||
}
|
||||
|
||||
// Check DiffID is properly calculated
|
||||
rc.Close()
|
||||
diffID := rc.DiffID()
|
||||
wantDiffID := cl.DiffIDOf(t, gotData)
|
||||
if diffID.String() != wantDiffID {
|
||||
t.Errorf("DiffID = %q; want %q", diffID, wantDiffID)
|
||||
}
|
||||
// Check DiffID is properly calculated
|
||||
rc.Close()
|
||||
diffID := rc.DiffID()
|
||||
wantDiffID := cl.DiffIDOf(t, gotData)
|
||||
if diffID.String() != wantDiffID {
|
||||
t.Errorf("DiffID = %q; want %q", diffID, wantDiffID)
|
||||
}
|
||||
|
||||
// Compare as stargz
|
||||
if !isSameVersion(t, cl, wantData, gotData) {
|
||||
t.Errorf("built stargz hasn't same json")
|
||||
return
|
||||
}
|
||||
if !isSameEntries(t, want, got) {
|
||||
t.Errorf("built stargz isn't same as the original")
|
||||
return
|
||||
}
|
||||
// Compare as stargz
|
||||
if !isSameVersion(t, cl, wantData, gotData) {
|
||||
t.Errorf("built stargz hasn't same json")
|
||||
return
|
||||
}
|
||||
if !isSameEntries(t, want, got) {
|
||||
t.Errorf("built stargz isn't same as the original")
|
||||
return
|
||||
}
|
||||
|
||||
// Compare as tar.gz
|
||||
if !isSameTarGz(t, cl, wantData, gotData) {
|
||||
t.Errorf("built stargz isn't same tar.gz")
|
||||
return
|
||||
}
|
||||
})
|
||||
// Compare as tar.gz
|
||||
if !isSameTarGz(t, cl, wantData, gotData) {
|
||||
t.Errorf("built stargz isn't same tar.gz")
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -526,7 +529,7 @@ func testDigestAndVerify(t *testing.T, controllers ...TestingController) {
|
||||
checks: []check{
|
||||
checkStargzTOC,
|
||||
checkVerifyTOC,
|
||||
checkVerifyInvalidStargzFail(buildTarStatic(t, tarOf(
|
||||
checkVerifyInvalidStargzFail(buildTar(t, tarOf(
|
||||
dir("test2/"), // modified
|
||||
), allowedPrefix[0])),
|
||||
},
|
||||
@ -544,7 +547,7 @@ func testDigestAndVerify(t *testing.T, controllers ...TestingController) {
|
||||
checks: []check{
|
||||
checkStargzTOC,
|
||||
checkVerifyTOC,
|
||||
checkVerifyInvalidStargzFail(buildTarStatic(t, tarOf(
|
||||
checkVerifyInvalidStargzFail(buildTar(t, tarOf(
|
||||
file("baz.txt", ""),
|
||||
file("foo.txt", "M"), // modified
|
||||
dir("test/"),
|
||||
@ -567,7 +570,7 @@ func testDigestAndVerify(t *testing.T, controllers ...TestingController) {
|
||||
checks: []check{
|
||||
checkStargzTOC,
|
||||
checkVerifyTOC,
|
||||
checkVerifyInvalidStargzFail(buildTarStatic(t, tarOf(
|
||||
checkVerifyInvalidStargzFail(buildTar(t, tarOf(
|
||||
file("baz.txt", "bazbazbazMMMbazbazbaz"), // modified
|
||||
file("foo.txt", "a"),
|
||||
dir("test/"),
|
||||
@ -593,7 +596,7 @@ func testDigestAndVerify(t *testing.T, controllers ...TestingController) {
|
||||
checks: []check{
|
||||
checkStargzTOC,
|
||||
checkVerifyTOC,
|
||||
checkVerifyInvalidStargzFail(buildTarStatic(t, tarOf(
|
||||
checkVerifyInvalidStargzFail(buildTar(t, tarOf(
|
||||
file("baz.txt", "bazbazbazbazbazbazbaz"),
|
||||
file("foo.txt", "a"),
|
||||
symlink("barlink", "test/bar.txt"),
|
||||
@ -615,30 +618,33 @@ func testDigestAndVerify(t *testing.T, controllers ...TestingController) {
|
||||
cl := cl
|
||||
for _, prefix := range allowedPrefix {
|
||||
prefix := prefix
|
||||
t.Run(tt.name+"-"+fmt.Sprintf("compression=%v-prefix=%q", cl, prefix), func(t *testing.T) {
|
||||
// Get original tar file and chunk digests
|
||||
dgstMap := make(map[string]digest.Digest)
|
||||
tarBlob := buildTarStatic(t, tt.tarInit(t, dgstMap), prefix)
|
||||
for _, srcTarFormat := range []tar.Format{tar.FormatUSTAR, tar.FormatPAX, tar.FormatGNU} {
|
||||
srcTarFormat := srcTarFormat
|
||||
t.Run(tt.name+"-"+fmt.Sprintf("compression=%v,prefix=%q,format=%s", cl, prefix, srcTarFormat), func(t *testing.T) {
|
||||
// Get original tar file and chunk digests
|
||||
dgstMap := make(map[string]digest.Digest)
|
||||
tarBlob := buildTar(t, tt.tarInit(t, dgstMap), prefix, srcTarFormat)
|
||||
|
||||
rc, err := Build(compressBlob(t, tarBlob, srcCompression),
|
||||
WithChunkSize(chunkSize), WithCompression(cl))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to convert stargz: %v", err)
|
||||
}
|
||||
tocDigest := rc.TOCDigest()
|
||||
defer rc.Close()
|
||||
buf := new(bytes.Buffer)
|
||||
if _, err := io.Copy(buf, rc); err != nil {
|
||||
t.Fatalf("failed to copy built stargz blob: %v", err)
|
||||
}
|
||||
newStargz := buf.Bytes()
|
||||
// NoPrefetchLandmark is added during `Bulid`, which is expected behaviour.
|
||||
dgstMap[chunkID(NoPrefetchLandmark, 0, int64(len([]byte{landmarkContents})))] = digest.FromBytes([]byte{landmarkContents})
|
||||
rc, err := Build(compressBlob(t, tarBlob, srcCompression),
|
||||
WithChunkSize(chunkSize), WithCompression(cl))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to convert stargz: %v", err)
|
||||
}
|
||||
tocDigest := rc.TOCDigest()
|
||||
defer rc.Close()
|
||||
buf := new(bytes.Buffer)
|
||||
if _, err := io.Copy(buf, rc); err != nil {
|
||||
t.Fatalf("failed to copy built stargz blob: %v", err)
|
||||
}
|
||||
newStargz := buf.Bytes()
|
||||
// NoPrefetchLandmark is added during `Bulid`, which is expected behaviour.
|
||||
dgstMap[chunkID(NoPrefetchLandmark, 0, int64(len([]byte{landmarkContents})))] = digest.FromBytes([]byte{landmarkContents})
|
||||
|
||||
for _, check := range tt.checks {
|
||||
check(t, newStargz, tocDigest, dgstMap, cl)
|
||||
}
|
||||
})
|
||||
for _, check := range tt.checks {
|
||||
check(t, newStargz, tocDigest, dgstMap, cl)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1058,7 +1064,7 @@ func parseStargz(sgz *io.SectionReader, controller TestingController) (decodedJT
|
||||
if _, err := sgz.ReadAt(footer, sgz.Size()-fSize); err != nil {
|
||||
return nil, 0, errors.Wrap(err, "error reading footer")
|
||||
}
|
||||
tocOffset, _, err := controller.ParseFooter(footer[positive(int64(len(footer))-fSize):])
|
||||
_, tocOffset, _, err := controller.ParseFooter(footer[positive(int64(len(footer))-fSize):])
|
||||
if err != nil {
|
||||
return nil, 0, errors.Wrapf(err, "failed to parse footer")
|
||||
}
|
||||
@ -1085,11 +1091,15 @@ func testWriteAndOpen(t *testing.T, controllers ...TestingController) {
|
||||
in []tarEntry
|
||||
want []stargzCheck
|
||||
wantNumGz int // expected number of streams
|
||||
|
||||
wantNumGzLossLess int // expected number of streams (> 0) in lossless mode if it's different from wantNumGz
|
||||
wantFailOnLossLess bool
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
in: tarOf(),
|
||||
wantNumGz: 2, // TOC + footer
|
||||
name: "empty",
|
||||
in: tarOf(),
|
||||
wantNumGz: 2, // empty tar + TOC + footer
|
||||
wantNumGzLossLess: 3, // empty tar + TOC + footer
|
||||
want: checks(
|
||||
numTOCEntries(0),
|
||||
),
|
||||
@ -1224,26 +1234,29 @@ func testWriteAndOpen(t *testing.T, controllers ...TestingController) {
|
||||
{
|
||||
name: "block_char_fifo",
|
||||
in: tarOf(
|
||||
tarEntryFunc(func(w *tar.Writer, prefix string) error {
|
||||
tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error {
|
||||
return w.WriteHeader(&tar.Header{
|
||||
Name: prefix + "b",
|
||||
Typeflag: tar.TypeBlock,
|
||||
Devmajor: 123,
|
||||
Devminor: 456,
|
||||
Format: format,
|
||||
})
|
||||
}),
|
||||
tarEntryFunc(func(w *tar.Writer, prefix string) error {
|
||||
tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error {
|
||||
return w.WriteHeader(&tar.Header{
|
||||
Name: prefix + "c",
|
||||
Typeflag: tar.TypeChar,
|
||||
Devmajor: 111,
|
||||
Devminor: 222,
|
||||
Format: format,
|
||||
})
|
||||
}),
|
||||
tarEntryFunc(func(w *tar.Writer, prefix string) error {
|
||||
tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error {
|
||||
return w.WriteHeader(&tar.Header{
|
||||
Name: prefix + "f",
|
||||
Typeflag: tar.TypeFifo,
|
||||
Format: format,
|
||||
})
|
||||
}),
|
||||
),
|
||||
@ -1278,6 +1291,29 @@ func testWriteAndOpen(t *testing.T, controllers ...TestingController) {
|
||||
hasMode("foo3/bar5", os.FileMode(0755)),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "lossy",
|
||||
in: tarOf(
|
||||
dir("bar/", sampleOwner),
|
||||
dir("foo/", sampleOwner),
|
||||
file("foo/bar.txt", content, sampleOwner),
|
||||
file(TOCTarName, "dummy"), // ignored by the writer. (lossless write returns error)
|
||||
),
|
||||
wantNumGz: 4, // both dirs, foo.txt alone, TOC, footer
|
||||
want: checks(
|
||||
numTOCEntries(3),
|
||||
hasDir("bar/"),
|
||||
hasDir("foo/"),
|
||||
hasFileLen("foo/bar.txt", len(content)),
|
||||
entryHasChildren("", "bar", "foo"),
|
||||
entryHasChildren("foo", "bar.txt"),
|
||||
hasChunkEntries("foo/bar.txt", 1),
|
||||
hasEntryOwner("bar/", sampleOwner),
|
||||
hasEntryOwner("foo/", sampleOwner),
|
||||
hasEntryOwner("foo/bar.txt", sampleOwner),
|
||||
),
|
||||
wantFailOnLossLess: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
@ -1285,47 +1321,90 @@ func testWriteAndOpen(t *testing.T, controllers ...TestingController) {
|
||||
cl := cl
|
||||
for _, prefix := range allowedPrefix {
|
||||
prefix := prefix
|
||||
t.Run(tt.name+"-"+fmt.Sprintf("compression=%v-prefix=%q", cl, prefix), func(t *testing.T) {
|
||||
tr, cancel := buildTar(t, tt.in, prefix)
|
||||
defer cancel()
|
||||
var stargzBuf bytes.Buffer
|
||||
w := NewWriterWithCompressor(&stargzBuf, cl)
|
||||
w.ChunkSize = tt.chunkSize
|
||||
if err := w.AppendTar(tr); err != nil {
|
||||
t.Fatalf("Append: %v", err)
|
||||
}
|
||||
if _, err := w.Close(); err != nil {
|
||||
t.Fatalf("Writer.Close: %v", err)
|
||||
}
|
||||
b := stargzBuf.Bytes()
|
||||
for _, srcTarFormat := range []tar.Format{tar.FormatUSTAR, tar.FormatPAX, tar.FormatGNU} {
|
||||
srcTarFormat := srcTarFormat
|
||||
for _, lossless := range []bool{true, false} {
|
||||
t.Run(tt.name+"-"+fmt.Sprintf("compression=%v,prefix=%q,lossless=%v,format=%s", cl, prefix, lossless, srcTarFormat), func(t *testing.T) {
|
||||
var tr io.Reader = buildTar(t, tt.in, prefix, srcTarFormat)
|
||||
origTarDgstr := digest.Canonical.Digester()
|
||||
tr = io.TeeReader(tr, origTarDgstr.Hash())
|
||||
var stargzBuf bytes.Buffer
|
||||
w := NewWriterWithCompressor(&stargzBuf, cl)
|
||||
w.ChunkSize = tt.chunkSize
|
||||
if lossless {
|
||||
err := w.AppendTarLossLess(tr)
|
||||
if tt.wantFailOnLossLess {
|
||||
if err != nil {
|
||||
return // expected to fail
|
||||
}
|
||||
t.Fatalf("Append wanted to fail on lossless")
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("Append(lossless): %v", err)
|
||||
}
|
||||
} else {
|
||||
if err := w.AppendTar(tr); err != nil {
|
||||
t.Fatalf("Append: %v", err)
|
||||
}
|
||||
}
|
||||
if _, err := w.Close(); err != nil {
|
||||
t.Fatalf("Writer.Close: %v", err)
|
||||
}
|
||||
b := stargzBuf.Bytes()
|
||||
|
||||
diffID := w.DiffID()
|
||||
wantDiffID := cl.DiffIDOf(t, b)
|
||||
if diffID != wantDiffID {
|
||||
t.Errorf("DiffID = %q; want %q", diffID, wantDiffID)
|
||||
}
|
||||
if lossless {
|
||||
// Check if the result blob reserves original tar metadata
|
||||
rc, err := Unpack(io.NewSectionReader(bytes.NewReader(b), 0, int64(len(b))), cl)
|
||||
if err != nil {
|
||||
t.Errorf("failed to decompress blob: %v", err)
|
||||
return
|
||||
}
|
||||
defer rc.Close()
|
||||
resultDgstr := digest.Canonical.Digester()
|
||||
if _, err := io.Copy(resultDgstr.Hash(), rc); err != nil {
|
||||
t.Errorf("failed to read result decompressed blob: %v", err)
|
||||
return
|
||||
}
|
||||
if resultDgstr.Digest() != origTarDgstr.Digest() {
|
||||
t.Errorf("lossy compression occurred: digest=%v; want %v",
|
||||
resultDgstr.Digest(), origTarDgstr.Digest())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
got := cl.CountStreams(t, b)
|
||||
if got != tt.wantNumGz {
|
||||
t.Errorf("number of streams = %d; want %d", got, tt.wantNumGz)
|
||||
}
|
||||
diffID := w.DiffID()
|
||||
wantDiffID := cl.DiffIDOf(t, b)
|
||||
if diffID != wantDiffID {
|
||||
t.Errorf("DiffID = %q; want %q", diffID, wantDiffID)
|
||||
}
|
||||
|
||||
telemetry, checkCalled := newCalledTelemetry()
|
||||
r, err := Open(
|
||||
io.NewSectionReader(bytes.NewReader(b), 0, int64(len(b))),
|
||||
WithDecompressors(cl),
|
||||
WithTelemetry(telemetry),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("stargz.Open: %v", err)
|
||||
got := cl.CountStreams(t, b)
|
||||
wantNumGz := tt.wantNumGz
|
||||
if lossless && tt.wantNumGzLossLess > 0 {
|
||||
wantNumGz = tt.wantNumGzLossLess
|
||||
}
|
||||
if got != wantNumGz {
|
||||
t.Errorf("number of streams = %d; want %d", got, wantNumGz)
|
||||
}
|
||||
|
||||
telemetry, checkCalled := newCalledTelemetry()
|
||||
r, err := Open(
|
||||
io.NewSectionReader(bytes.NewReader(b), 0, int64(len(b))),
|
||||
WithDecompressors(cl),
|
||||
WithTelemetry(telemetry),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("stargz.Open: %v", err)
|
||||
}
|
||||
if err := checkCalled(); err != nil {
|
||||
t.Errorf("telemetry failure: %v", err)
|
||||
}
|
||||
for _, want := range tt.want {
|
||||
want.check(t, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
if err := checkCalled(); err != nil {
|
||||
t.Errorf("telemetry failure: %v", err)
|
||||
}
|
||||
for _, want := range tt.want {
|
||||
want.check(t, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1655,49 +1734,41 @@ func hasEntryOwner(entry string, owner owner) stargzCheck {
|
||||
func tarOf(s ...tarEntry) []tarEntry { return s }
|
||||
|
||||
type tarEntry interface {
|
||||
appendTar(tw *tar.Writer, prefix string) error
|
||||
appendTar(tw *tar.Writer, prefix string, format tar.Format) error
|
||||
}
|
||||
|
||||
type tarEntryFunc func(*tar.Writer, string) error
|
||||
type tarEntryFunc func(*tar.Writer, string, tar.Format) error
|
||||
|
||||
func (f tarEntryFunc) appendTar(tw *tar.Writer, prefix string) error { return f(tw, prefix) }
|
||||
|
||||
func buildTar(t *testing.T, ents []tarEntry, prefix string) (r io.Reader, cancel func()) {
|
||||
pr, pw := io.Pipe()
|
||||
go func() {
|
||||
tw := tar.NewWriter(pw)
|
||||
for _, ent := range ents {
|
||||
if err := ent.appendTar(tw, prefix); err != nil {
|
||||
t.Errorf("building input tar: %v", err)
|
||||
pw.Close()
|
||||
return
|
||||
}
|
||||
}
|
||||
if err := tw.Close(); err != nil {
|
||||
t.Errorf("closing write of input tar: %v", err)
|
||||
}
|
||||
pw.Close()
|
||||
}()
|
||||
return pr, func() { go pr.Close(); go pw.Close() }
|
||||
func (f tarEntryFunc) appendTar(tw *tar.Writer, prefix string, format tar.Format) error {
|
||||
return f(tw, prefix, format)
|
||||
}
|
||||
|
||||
func buildTarStatic(t *testing.T, ents []tarEntry, prefix string) *io.SectionReader {
|
||||
func buildTar(t *testing.T, ents []tarEntry, prefix string, opts ...interface{}) *io.SectionReader {
|
||||
format := tar.FormatUnknown
|
||||
for _, opt := range opts {
|
||||
switch v := opt.(type) {
|
||||
case tar.Format:
|
||||
format = v
|
||||
default:
|
||||
panic(fmt.Errorf("unsupported opt for buildTar: %v", opt))
|
||||
}
|
||||
}
|
||||
buf := new(bytes.Buffer)
|
||||
tw := tar.NewWriter(buf)
|
||||
for _, ent := range ents {
|
||||
if err := ent.appendTar(tw, prefix); err != nil {
|
||||
if err := ent.appendTar(tw, prefix, format); err != nil {
|
||||
t.Fatalf("building input tar: %v", err)
|
||||
}
|
||||
}
|
||||
if err := tw.Close(); err != nil {
|
||||
t.Errorf("closing write of input tar: %v", err)
|
||||
}
|
||||
data := buf.Bytes()
|
||||
data := append(buf.Bytes(), make([]byte, 100)...) // append empty bytes at the tail to see lossless works
|
||||
return io.NewSectionReader(bytes.NewReader(data), 0, int64(len(data)))
|
||||
}
|
||||
|
||||
func dir(name string, opts ...interface{}) tarEntry {
|
||||
return tarEntryFunc(func(tw *tar.Writer, prefix string) error {
|
||||
return tarEntryFunc(func(tw *tar.Writer, prefix string, format tar.Format) error {
|
||||
var o owner
|
||||
mode := os.FileMode(0755)
|
||||
for _, opt := range opts {
|
||||
@ -1723,6 +1794,7 @@ func dir(name string, opts ...interface{}) tarEntry {
|
||||
Mode: tm,
|
||||
Uid: o.uid,
|
||||
Gid: o.gid,
|
||||
Format: format,
|
||||
})
|
||||
})
|
||||
}
|
||||
@ -1737,7 +1809,7 @@ type owner struct {
|
||||
}
|
||||
|
||||
func file(name, contents string, opts ...interface{}) tarEntry {
|
||||
return tarEntryFunc(func(tw *tar.Writer, prefix string) error {
|
||||
return tarEntryFunc(func(tw *tar.Writer, prefix string, format tar.Format) error {
|
||||
var xattrs xAttr
|
||||
var o owner
|
||||
mode := os.FileMode(0644)
|
||||
@ -1760,6 +1832,9 @@ func file(name, contents string, opts ...interface{}) tarEntry {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(xattrs) > 0 {
|
||||
format = tar.FormatPAX // only PAX supports xattrs
|
||||
}
|
||||
if err := tw.WriteHeader(&tar.Header{
|
||||
Typeflag: tar.TypeReg,
|
||||
Name: prefix + name,
|
||||
@ -1768,6 +1843,7 @@ func file(name, contents string, opts ...interface{}) tarEntry {
|
||||
Size: int64(len(contents)),
|
||||
Uid: o.uid,
|
||||
Gid: o.gid,
|
||||
Format: format,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1777,78 +1853,76 @@ func file(name, contents string, opts ...interface{}) tarEntry {
|
||||
}
|
||||
|
||||
func symlink(name, target string) tarEntry {
|
||||
return tarEntryFunc(func(tw *tar.Writer, prefix string) error {
|
||||
return tarEntryFunc(func(tw *tar.Writer, prefix string, format tar.Format) error {
|
||||
return tw.WriteHeader(&tar.Header{
|
||||
Typeflag: tar.TypeSymlink,
|
||||
Name: prefix + name,
|
||||
Linkname: target,
|
||||
Mode: 0644,
|
||||
Format: format,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func link(name string, linkname string) tarEntry {
|
||||
now := time.Now()
|
||||
return tarEntryFunc(func(w *tar.Writer, prefix string) error {
|
||||
return tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error {
|
||||
return w.WriteHeader(&tar.Header{
|
||||
Typeflag: tar.TypeLink,
|
||||
Name: prefix + name,
|
||||
Linkname: linkname,
|
||||
ModTime: now,
|
||||
AccessTime: now,
|
||||
ChangeTime: now,
|
||||
Typeflag: tar.TypeLink,
|
||||
Name: prefix + name,
|
||||
Linkname: linkname,
|
||||
ModTime: now,
|
||||
Format: format,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func chardev(name string, major, minor int64) tarEntry {
|
||||
now := time.Now()
|
||||
return tarEntryFunc(func(w *tar.Writer, prefix string) error {
|
||||
return tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error {
|
||||
return w.WriteHeader(&tar.Header{
|
||||
Typeflag: tar.TypeChar,
|
||||
Name: prefix + name,
|
||||
Devmajor: major,
|
||||
Devminor: minor,
|
||||
ModTime: now,
|
||||
AccessTime: now,
|
||||
ChangeTime: now,
|
||||
Typeflag: tar.TypeChar,
|
||||
Name: prefix + name,
|
||||
Devmajor: major,
|
||||
Devminor: minor,
|
||||
ModTime: now,
|
||||
Format: format,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func blockdev(name string, major, minor int64) tarEntry {
|
||||
now := time.Now()
|
||||
return tarEntryFunc(func(w *tar.Writer, prefix string) error {
|
||||
return tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error {
|
||||
return w.WriteHeader(&tar.Header{
|
||||
Typeflag: tar.TypeBlock,
|
||||
Name: prefix + name,
|
||||
Devmajor: major,
|
||||
Devminor: minor,
|
||||
ModTime: now,
|
||||
AccessTime: now,
|
||||
ChangeTime: now,
|
||||
Typeflag: tar.TypeBlock,
|
||||
Name: prefix + name,
|
||||
Devmajor: major,
|
||||
Devminor: minor,
|
||||
ModTime: now,
|
||||
Format: format,
|
||||
})
|
||||
})
|
||||
}
|
||||
func fifo(name string) tarEntry {
|
||||
now := time.Now()
|
||||
return tarEntryFunc(func(w *tar.Writer, prefix string) error {
|
||||
return tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error {
|
||||
return w.WriteHeader(&tar.Header{
|
||||
Typeflag: tar.TypeFifo,
|
||||
Name: prefix + name,
|
||||
ModTime: now,
|
||||
AccessTime: now,
|
||||
ChangeTime: now,
|
||||
Typeflag: tar.TypeFifo,
|
||||
Name: prefix + name,
|
||||
ModTime: now,
|
||||
Format: format,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func prefetchLandmark() tarEntry {
|
||||
return tarEntryFunc(func(w *tar.Writer, prefix string) error {
|
||||
return tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error {
|
||||
if err := w.WriteHeader(&tar.Header{
|
||||
Name: PrefetchLandmark,
|
||||
Typeflag: tar.TypeReg,
|
||||
Size: int64(len([]byte{landmarkContents})),
|
||||
Format: format,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1861,11 +1935,12 @@ func prefetchLandmark() tarEntry {
|
||||
}
|
||||
|
||||
func noPrefetchLandmark() tarEntry {
|
||||
return tarEntryFunc(func(w *tar.Writer, prefix string) error {
|
||||
return tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error {
|
||||
if err := w.WriteHeader(&tar.Header{
|
||||
Name: NoPrefetchLandmark,
|
||||
Typeflag: tar.TypeReg,
|
||||
Size: int64(len([]byte{landmarkContents})),
|
||||
Format: format,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1899,11 +1974,12 @@ func regDigest(t *testing.T, name string, contentStr string, digestMap map[strin
|
||||
n += size
|
||||
}
|
||||
|
||||
return tarEntryFunc(func(w *tar.Writer, prefix string) error {
|
||||
return tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error {
|
||||
if err := w.WriteHeader(&tar.Header{
|
||||
Typeflag: tar.TypeReg,
|
||||
Name: prefix + name,
|
||||
Size: int64(len(content)),
|
||||
Format: format,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
6
vendor/github.com/containerd/stargz-snapshotter/estargz/types.go
generated
vendored
6
vendor/github.com/containerd/stargz-snapshotter/estargz/types.go
generated
vendored
@ -290,7 +290,7 @@ type Compressor interface {
|
||||
WriteTOCAndFooter(w io.Writer, off int64, toc *JTOC, diffHash hash.Hash) (tocDgst digest.Digest, err error)
|
||||
}
|
||||
|
||||
// Deompressor represents the helper mothods to be used for parsing eStargz.
|
||||
// Decompressor represents the helper mothods to be used for parsing eStargz.
|
||||
type Decompressor interface {
|
||||
// Reader returns ReadCloser to be used for decompressing file payload.
|
||||
Reader(r io.Reader) (io.ReadCloser, error)
|
||||
@ -299,10 +299,12 @@ type Decompressor interface {
|
||||
FooterSize() int64
|
||||
|
||||
// ParseFooter parses the footer and returns the offset and (compressed) size of TOC.
|
||||
// payloadBlobSize is the (compressed) size of the blob payload (i.e. the size between
|
||||
// the top until the TOC JSON).
|
||||
//
|
||||
// Here, tocSize is optional. If tocSize <= 0, it's by default the size of the range
|
||||
// from tocOffset until the beginning of the footer (blob size - tocOff - FooterSize).
|
||||
ParseFooter(p []byte) (tocOffset, tocSize int64, err error)
|
||||
ParseFooter(p []byte) (blobPayloadSize, tocOffset, tocSize int64, err error)
|
||||
|
||||
// ParseTOC parses TOC from the passed reader. The reader provides the partial contents
|
||||
// of the underlying blob that has the range specified by ParseFooter method.
|
||||
|
15
vendor/github.com/containers/storage/.cirrus.yml
generated
vendored
15
vendor/github.com/containers/storage/.cirrus.yml
generated
vendored
@ -20,16 +20,14 @@ env:
|
||||
FEDORA_NAME: "fedora-34"
|
||||
PRIOR_FEDORA_NAME: "fedora-33"
|
||||
UBUNTU_NAME: "ubuntu-2104"
|
||||
PRIOR_UBUNTU_NAME: "ubuntu-2010"
|
||||
|
||||
# GCE project where images live
|
||||
IMAGE_PROJECT: "libpod-218412"
|
||||
# VM Image built in containers/automation_images
|
||||
_BUILT_IMAGE_SUFFIX: "c6248193773010944"
|
||||
_BUILT_IMAGE_SUFFIX: "c6431352024203264"
|
||||
FEDORA_CACHE_IMAGE_NAME: "fedora-${_BUILT_IMAGE_SUFFIX}"
|
||||
PRIOR_FEDORA_CACHE_IMAGE_NAME: "prior-fedora-${_BUILT_IMAGE_SUFFIX}"
|
||||
UBUNTU_CACHE_IMAGE_NAME: "ubuntu-${_BUILT_IMAGE_SUFFIX}"
|
||||
PRIOR_UBUNTU_CACHE_IMAGE_NAME: "prior-ubuntu-${_BUILT_IMAGE_SUFFIX}"
|
||||
|
||||
####
|
||||
#### Command variables to help avoid duplication
|
||||
@ -115,15 +113,6 @@ ubuntu_testing_task: &ubuntu_testing
|
||||
TEST_DRIVER: "overlay"
|
||||
|
||||
|
||||
prior_ubuntu_testing_task:
|
||||
<<: *ubuntu_testing
|
||||
alias: prior_ubuntu_testing
|
||||
name: *std_test_name
|
||||
env:
|
||||
OS_NAME: "${PRIOR_UBUNTU_NAME}"
|
||||
VM_IMAGE: "${PRIOR_UBUNTU_CACHE_IMAGE_NAME}"
|
||||
|
||||
|
||||
lint_task:
|
||||
env:
|
||||
CIRRUS_WORKING_DIR: "/go/src/github.com/containers/storage"
|
||||
@ -153,7 +142,6 @@ meta_task:
|
||||
${FEDORA_CACHE_IMAGE_NAME}
|
||||
${PRIOR_FEDORA_CACHE_IMAGE_NAME}
|
||||
${UBUNTU_CACHE_IMAGE_NAME}
|
||||
${PRIOR_UBUNTU_CACHE_IMAGE_NAME}
|
||||
BUILDID: "${CIRRUS_BUILD_ID}"
|
||||
REPOREF: "${CIRRUS_CHANGE_IN_REPO}"
|
||||
GCPJSON: ENCRYPTED[244a93fe8b386b48b96f748342bf741350e43805eee81dd04b45093bdf737e540b993fc735df41f131835fa0f9b65826]
|
||||
@ -181,7 +169,6 @@ success_task:
|
||||
- fedora_testing
|
||||
- prior_fedora_testing
|
||||
- ubuntu_testing
|
||||
- prior_ubuntu_testing
|
||||
- meta
|
||||
- vendor
|
||||
container:
|
||||
|
2
vendor/github.com/containers/storage/VERSION
generated
vendored
2
vendor/github.com/containers/storage/VERSION
generated
vendored
@ -1 +1 @@
|
||||
1.36.0
|
||||
1.37.0
|
||||
|
6
vendor/github.com/containers/storage/drivers/aufs/aufs.go
generated
vendored
6
vendor/github.com/containers/storage/drivers/aufs/aufs.go
generated
vendored
@ -730,14 +730,14 @@ func useDirperm() bool {
|
||||
enableDirpermLock.Do(func() {
|
||||
base, err := ioutil.TempDir("", "storage-aufs-base")
|
||||
if err != nil {
|
||||
logrus.Errorf("error checking dirperm1: %v", err)
|
||||
logrus.Errorf("Checking dirperm1: %v", err)
|
||||
return
|
||||
}
|
||||
defer os.RemoveAll(base)
|
||||
|
||||
union, err := ioutil.TempDir("", "storage-aufs-union")
|
||||
if err != nil {
|
||||
logrus.Errorf("error checking dirperm1: %v", err)
|
||||
logrus.Errorf("Checking dirperm1: %v", err)
|
||||
return
|
||||
}
|
||||
defer os.RemoveAll(union)
|
||||
@ -748,7 +748,7 @@ func useDirperm() bool {
|
||||
}
|
||||
enableDirperm = true
|
||||
if err := Unmount(union); err != nil {
|
||||
logrus.Errorf("error checking dirperm1: failed to unmount %v", err)
|
||||
logrus.Errorf("Checking dirperm1: failed to unmount %v", err)
|
||||
}
|
||||
})
|
||||
return enableDirperm
|
||||
|
34
vendor/github.com/containers/storage/drivers/driver_linux.go
generated
vendored
34
vendor/github.com/containers/storage/drivers/driver_linux.go
generated
vendored
@ -50,6 +50,40 @@ const (
|
||||
FsMagicOverlay = FsMagic(0x794C7630)
|
||||
// FsMagicFUSE filesystem id for FUSE
|
||||
FsMagicFUSE = FsMagic(0x65735546)
|
||||
// FsMagicAcfs filesystem id for Acfs
|
||||
FsMagicAcfs = FsMagic(0x61636673)
|
||||
// FsMagicAfs filesystem id for Afs
|
||||
FsMagicAfs = FsMagic(0x5346414f)
|
||||
// FsMagicCephFs filesystem id for Ceph
|
||||
FsMagicCephFs = FsMagic(0x00C36400)
|
||||
// FsMagicCIFS filesystem id for CIFS
|
||||
FsMagicCIFS = FsMagic(0xFF534D42)
|
||||
// FsMagicFHGFS filesystem id for FHGFS
|
||||
FsMagicFHGFSFs = FsMagic(0x19830326)
|
||||
// FsMagicIBRIX filesystem id for IBRIX
|
||||
FsMagicIBRIX = FsMagic(0x013111A8)
|
||||
// FsMagicKAFS filesystem id for KAFS
|
||||
FsMagicKAFS = FsMagic(0x6B414653)
|
||||
// FsMagicLUSTRE filesystem id for LUSTRE
|
||||
FsMagicLUSTRE = FsMagic(0x0BD00BD0)
|
||||
// FsMagicNCP filesystem id for NCP
|
||||
FsMagicNCP = FsMagic(0x564C)
|
||||
// FsMagicNFSD filesystem id for NFSD
|
||||
FsMagicNFSD = FsMagic(0x6E667364)
|
||||
// FsMagicOCFS2 filesystem id for OCFS2
|
||||
FsMagicOCFS2 = FsMagic(0x7461636F)
|
||||
// FsMagicPANFS filesystem id for PANFS
|
||||
FsMagicPANFS = FsMagic(0xAAD7AAEA)
|
||||
// FsMagicPRLFS filesystem id for PRLFS
|
||||
FsMagicPRLFS = FsMagic(0x7C7C6673)
|
||||
// FsMagicSMB2 filesystem id for SMB2
|
||||
FsMagicSMB2 = FsMagic(0xFE534D42)
|
||||
// FsMagicSNFS filesystem id for SNFS
|
||||
FsMagicSNFS = FsMagic(0xBEEFDEAD)
|
||||
// FsMagicVBOXSF filesystem id for VBOXSF
|
||||
FsMagicVBOXSF = FsMagic(0x786F4256)
|
||||
// FsMagicVXFS filesystem id for VXFS
|
||||
FsMagicVXFS = FsMagic(0xA501FCF5)
|
||||
)
|
||||
|
||||
var (
|
||||
|
2
vendor/github.com/containers/storage/drivers/fsdiff.go
generated
vendored
2
vendor/github.com/containers/storage/drivers/fsdiff.go
generated
vendored
@ -180,7 +180,7 @@ func (gdw *NaiveDiffDriver) ApplyDiff(id, parent string, options ApplyDiffOpts)
|
||||
start := time.Now().UTC()
|
||||
logrus.Debug("Start untar layer")
|
||||
if size, err = ApplyUncompressedLayer(layerFs, options.Diff, tarOptions); err != nil {
|
||||
logrus.Errorf("Error while applying layer: %s", err)
|
||||
logrus.Errorf("While applying layer: %s", err)
|
||||
return
|
||||
}
|
||||
logrus.Debugf("Untar time: %vs", time.Now().UTC().Sub(start).Seconds())
|
||||
|
124
vendor/github.com/containers/storage/drivers/overlay/overlay.go
generated
vendored
124
vendor/github.com/containers/storage/drivers/overlay/overlay.go
generated
vendored
@ -174,21 +174,21 @@ func checkSupportVolatile(home, runhome string) (bool, error) {
|
||||
var usingVolatile bool
|
||||
if err == nil {
|
||||
if volatileCacheResult {
|
||||
logrus.Debugf("cached value indicated that volatile is being used")
|
||||
logrus.Debugf("Cached value indicated that volatile is being used")
|
||||
} else {
|
||||
logrus.Debugf("cached value indicated that volatile is not being used")
|
||||
logrus.Debugf("Cached value indicated that volatile is not being used")
|
||||
}
|
||||
usingVolatile = volatileCacheResult
|
||||
} else {
|
||||
usingVolatile, err = doesVolatile(home)
|
||||
if err == nil {
|
||||
if usingVolatile {
|
||||
logrus.Debugf("overlay test mount indicated that volatile is being used")
|
||||
logrus.Debugf("overlay: test mount indicated that volatile is being used")
|
||||
} else {
|
||||
logrus.Debugf("overlay test mount indicated that volatile is not being used")
|
||||
logrus.Debugf("overlay: test mount indicated that volatile is not being used")
|
||||
}
|
||||
if err = cachedFeatureRecord(runhome, feature, usingVolatile, ""); err != nil {
|
||||
return false, errors.Wrap(err, "error recording volatile-being-used status")
|
||||
return false, errors.Wrap(err, "recording volatile-being-used status")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -206,9 +206,9 @@ func checkAndRecordOverlaySupport(fsMagic graphdriver.FsMagic, home, runhome str
|
||||
overlayCacheResult, overlayCacheText, err := cachedFeatureCheck(runhome, feature)
|
||||
if err == nil {
|
||||
if overlayCacheResult {
|
||||
logrus.Debugf("cached value indicated that overlay is supported")
|
||||
logrus.Debugf("Cached value indicated that overlay is supported")
|
||||
} else {
|
||||
logrus.Debugf("cached value indicated that overlay is not supported")
|
||||
logrus.Debugf("Cached value indicated that overlay is not supported")
|
||||
}
|
||||
supportsDType = overlayCacheResult
|
||||
if !supportsDType {
|
||||
@ -225,12 +225,12 @@ func checkAndRecordOverlaySupport(fsMagic graphdriver.FsMagic, home, runhome str
|
||||
}
|
||||
err = errors.Wrap(err, "kernel does not support overlay fs")
|
||||
if err2 := cachedFeatureRecord(runhome, feature, false, err.Error()); err2 != nil {
|
||||
return false, errors.Wrapf(err2, "error recording overlay not being supported (%v)", err)
|
||||
return false, errors.Wrapf(err2, "recording overlay not being supported (%v)", err)
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
if err = cachedFeatureRecord(runhome, feature, supportsDType, ""); err != nil {
|
||||
return false, errors.Wrap(err, "error recording overlay support status")
|
||||
return false, errors.Wrap(err, "recording overlay support status")
|
||||
}
|
||||
}
|
||||
return supportsDType, nil
|
||||
@ -248,6 +248,23 @@ func (d *Driver) getSupportsVolatile() (bool, error) {
|
||||
return supportsVolatile, nil
|
||||
}
|
||||
|
||||
// isNetworkFileSystem checks if the specified file system is supported by native overlay
|
||||
// as backing store when running in a user namespace.
|
||||
func isNetworkFileSystem(fsMagic graphdriver.FsMagic) bool {
|
||||
switch fsMagic {
|
||||
// a bunch of network file systems...
|
||||
case graphdriver.FsMagicNfsFs, graphdriver.FsMagicSmbFs, graphdriver.FsMagicAcfs,
|
||||
graphdriver.FsMagicAfs, graphdriver.FsMagicCephFs, graphdriver.FsMagicCIFS,
|
||||
graphdriver.FsMagicFHGFSFs, graphdriver.FsMagicGPFS, graphdriver.FsMagicIBRIX,
|
||||
graphdriver.FsMagicKAFS, graphdriver.FsMagicLUSTRE, graphdriver.FsMagicNCP,
|
||||
graphdriver.FsMagicNFSD, graphdriver.FsMagicOCFS2, graphdriver.FsMagicPANFS,
|
||||
graphdriver.FsMagicPRLFS, graphdriver.FsMagicSMB2, graphdriver.FsMagicSNFS,
|
||||
graphdriver.FsMagicVBOXSF, graphdriver.FsMagicVXFS:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Init returns the a native diff driver for overlay filesystem.
|
||||
// If overlay filesystem is not supported on the host, a wrapped graphdriver.ErrNotSupported is returned as error.
|
||||
// If an overlay filesystem is not supported over an existing filesystem then a wrapped graphdriver.ErrIncompatibleFS is returned.
|
||||
@ -266,18 +283,27 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error)
|
||||
}
|
||||
|
||||
if opts.mountProgram != "" {
|
||||
if unshare.IsRootless() && isNetworkFileSystem(fsMagic) && opts.forceMask == nil {
|
||||
m := os.FileMode(0700)
|
||||
opts.forceMask = &m
|
||||
logrus.Warnf("Network file system detected as backing store. Enforcing overlay option `force_mask=\"%o\"`. Add it to storage.conf to silence this warning", m)
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(getMountProgramFlagFile(home), []byte("true"), 0600); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
// check if they are running over btrfs, aufs, zfs, overlay, or ecryptfs
|
||||
if opts.forceMask != nil {
|
||||
return nil, errors.New("'force_mask' is supported only with 'mount_program'")
|
||||
}
|
||||
// check if they are running over btrfs, aufs, zfs, overlay, or ecryptfs
|
||||
switch fsMagic {
|
||||
case graphdriver.FsMagicAufs, graphdriver.FsMagicZfs, graphdriver.FsMagicOverlay, graphdriver.FsMagicEcryptfs:
|
||||
return nil, errors.Wrapf(graphdriver.ErrIncompatibleFS, "'overlay' is not supported over %s, a mount_program is required", backingFs)
|
||||
}
|
||||
if unshare.IsRootless() && isNetworkFileSystem(fsMagic) {
|
||||
return nil, errors.Wrapf(graphdriver.ErrIncompatibleFS, "A network file system with user namespaces is not supported. Please use a mount_program")
|
||||
}
|
||||
}
|
||||
|
||||
rootUID, rootGID, err := idtools.GetRootUIDGID(options.UIDMaps, options.GIDMaps)
|
||||
@ -310,24 +336,24 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error)
|
||||
metacopyCacheResult, _, err := cachedFeatureCheck(runhome, feature)
|
||||
if err == nil {
|
||||
if metacopyCacheResult {
|
||||
logrus.Debugf("cached value indicated that metacopy is being used")
|
||||
logrus.Debugf("Cached value indicated that metacopy is being used")
|
||||
} else {
|
||||
logrus.Debugf("cached value indicated that metacopy is not being used")
|
||||
logrus.Debugf("Cached value indicated that metacopy is not being used")
|
||||
}
|
||||
usingMetacopy = metacopyCacheResult
|
||||
} else {
|
||||
usingMetacopy, err = doesMetacopy(home, opts.mountOptions)
|
||||
if err == nil {
|
||||
if usingMetacopy {
|
||||
logrus.Debugf("overlay test mount indicated that metacopy is being used")
|
||||
logrus.Debugf("overlay: test mount indicated that metacopy is being used")
|
||||
} else {
|
||||
logrus.Debugf("overlay test mount indicated that metacopy is not being used")
|
||||
logrus.Debugf("overlay: test mount indicated that metacopy is not being used")
|
||||
}
|
||||
if err = cachedFeatureRecord(runhome, feature, usingMetacopy, ""); err != nil {
|
||||
return nil, errors.Wrap(err, "error recording metacopy-being-used status")
|
||||
return nil, errors.Wrap(err, "recording metacopy-being-used status")
|
||||
}
|
||||
} else {
|
||||
logrus.Infof("overlay test mount did not indicate whether or not metacopy is being used: %v", err)
|
||||
logrus.Infof("overlay: test mount did not indicate whether or not metacopy is being used: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@ -548,7 +574,7 @@ func SupportsNativeOverlay(graphroot, rundir string) (bool, error) {
|
||||
}
|
||||
switch contents {
|
||||
case "true":
|
||||
logrus.Debugf("overlay storage already configured with a mount-program")
|
||||
logrus.Debugf("overlay: storage already configured with a mount-program")
|
||||
return false, nil
|
||||
default:
|
||||
needsMountProgram, err := scanForMountProgramIndicators(home)
|
||||
@ -640,17 +666,17 @@ func supportsOverlay(home string, homeMagic graphdriver.FsMagic, rootUID, rootGI
|
||||
flags = fmt.Sprintf("%s,userxattr", flags)
|
||||
}
|
||||
if err := syscall.Mknod(filepath.Join(upperDir, "whiteout"), syscall.S_IFCHR|0600, int(unix.Mkdev(0, 0))); err != nil {
|
||||
logrus.Debugf("unable to create kernel-style whiteout: %v", err)
|
||||
logrus.Debugf("Unable to create kernel-style whiteout: %v", err)
|
||||
return supportsDType, errors.Wrapf(err, "unable to create kernel-style whiteout")
|
||||
}
|
||||
|
||||
if len(flags) < unix.Getpagesize() {
|
||||
err := unix.Mount("overlay", mergedDir, "overlay", 0, flags)
|
||||
if err == nil {
|
||||
logrus.Debugf("overlay test mount with multiple lowers succeeded")
|
||||
logrus.Debugf("overlay: test mount with multiple lowers succeeded")
|
||||
return supportsDType, nil
|
||||
}
|
||||
logrus.Debugf("overlay test mount with multiple lowers failed %v", err)
|
||||
logrus.Debugf("overlay: test mount with multiple lowers failed %v", err)
|
||||
}
|
||||
flags = fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", lower1Dir, upperDir, workDir)
|
||||
if selinux.GetEnabled() {
|
||||
@ -659,10 +685,10 @@ func supportsOverlay(home string, homeMagic graphdriver.FsMagic, rootUID, rootGI
|
||||
if len(flags) < unix.Getpagesize() {
|
||||
err := unix.Mount("overlay", mergedDir, "overlay", 0, flags)
|
||||
if err == nil {
|
||||
logrus.StandardLogger().Logf(logLevel, "overlay test mount with multiple lowers failed, but succeeded with a single lower")
|
||||
logrus.StandardLogger().Logf(logLevel, "overlay: test mount with multiple lowers failed, but succeeded with a single lower")
|
||||
return supportsDType, errors.Wrap(graphdriver.ErrNotSupported, "kernel too old to provide multiple lowers feature for overlay")
|
||||
}
|
||||
logrus.Debugf("overlay test mount with a single lower failed %v", err)
|
||||
logrus.Debugf("overlay: test mount with a single lower failed %v", err)
|
||||
}
|
||||
logrus.StandardLogger().Logf(logLevel, "'overlay' is not supported over %s at %q", backingFs, home)
|
||||
return supportsDType, errors.Wrapf(graphdriver.ErrIncompatibleFS, "'overlay' is not supported over %s at %q", backingFs, home)
|
||||
@ -682,9 +708,9 @@ func (d *Driver) useNaiveDiff() bool {
|
||||
nativeDiffCacheResult, nativeDiffCacheText, err := cachedFeatureCheck(d.runhome, feature)
|
||||
if err == nil {
|
||||
if nativeDiffCacheResult {
|
||||
logrus.Debugf("cached value indicated that native-diff is usable")
|
||||
logrus.Debugf("Cached value indicated that native-diff is usable")
|
||||
} else {
|
||||
logrus.Debugf("cached value indicated that native-diff is not being used")
|
||||
logrus.Debugf("Cached value indicated that native-diff is not being used")
|
||||
logrus.Info(nativeDiffCacheText)
|
||||
}
|
||||
useNaiveDiffOnly = !nativeDiffCacheResult
|
||||
@ -821,7 +847,7 @@ func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts
|
||||
opts.StorageOpt["inodes"] = strconv.FormatUint(d.options.quota.Inodes, 10)
|
||||
}
|
||||
|
||||
return d.create(id, parent, opts)
|
||||
return d.create(id, parent, opts, false)
|
||||
}
|
||||
|
||||
// Create is used to create the upper, lower, and merge directories required for overlay fs for a given id.
|
||||
@ -831,15 +857,16 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) (retErr
|
||||
if _, ok := opts.StorageOpt["size"]; ok {
|
||||
return fmt.Errorf("--storage-opt size is only supported for ReadWrite Layers")
|
||||
}
|
||||
|
||||
if _, ok := opts.StorageOpt["inodes"]; ok {
|
||||
return fmt.Errorf("--storage-opt inodes is only supported for ReadWrite Layers")
|
||||
}
|
||||
}
|
||||
|
||||
return d.create(id, parent, opts)
|
||||
return d.create(id, parent, opts, true)
|
||||
}
|
||||
|
||||
func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr error) {
|
||||
func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, disableQuota bool) (retErr error) {
|
||||
dir := d.dir(id)
|
||||
|
||||
uidMaps := d.uidMaps
|
||||
@ -880,7 +907,7 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr
|
||||
}
|
||||
}()
|
||||
|
||||
if d.quotaCtl != nil {
|
||||
if d.quotaCtl != nil && !disableQuota {
|
||||
quota := quota.Quota{}
|
||||
if opts != nil && len(opts.StorageOpt) > 0 {
|
||||
driver := &Driver{}
|
||||
@ -994,7 +1021,7 @@ func (d *Driver) getLower(parent string) (string, error) {
|
||||
}
|
||||
logrus.Warnf("Can't read parent link %q because it does not exist. Going through storage to recreate the missing links.", path.Join(parentDir, "link"))
|
||||
if err := d.recreateSymlinks(); err != nil {
|
||||
return "", errors.Wrap(err, "error recreating the links")
|
||||
return "", errors.Wrap(err, "recreating the links")
|
||||
}
|
||||
parentLink, err = ioutil.ReadFile(path.Join(parentDir, "link"))
|
||||
if err != nil {
|
||||
@ -1038,7 +1065,7 @@ func (d *Driver) getLowerDirs(id string) ([]string, error) {
|
||||
if os.IsNotExist(err) {
|
||||
logrus.Warnf("Can't read link %q because it does not exist. A storage corruption might have occurred, attempting to recreate the missing symlinks. It might be best wipe the storage to avoid further errors due to storage corruption.", lower)
|
||||
if err := d.recreateSymlinks(); err != nil {
|
||||
return nil, fmt.Errorf("error recreating the missing symlinks: %v", err)
|
||||
return nil, fmt.Errorf("recreating the missing symlinks: %v", err)
|
||||
}
|
||||
// let's call Readlink on lower again now that we have recreated the missing symlinks
|
||||
lp, err = os.Readlink(lower)
|
||||
@ -1121,7 +1148,7 @@ func (d *Driver) recreateSymlinks() error {
|
||||
// List all the directories under the home directory
|
||||
dirs, err := ioutil.ReadDir(d.home)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error reading driver home directory %q: %v", d.home, err)
|
||||
return fmt.Errorf("reading driver home directory %q: %v", d.home, err)
|
||||
}
|
||||
linksDir := filepath.Join(d.home, "l")
|
||||
// This makes the link directory if it doesn't exist
|
||||
@ -1148,7 +1175,7 @@ func (d *Driver) recreateSymlinks() error {
|
||||
// Read the "link" file under each layer to get the name of the symlink
|
||||
data, err := ioutil.ReadFile(path.Join(d.dir(dir.Name()), "link"))
|
||||
if err != nil {
|
||||
errs = multierror.Append(errs, errors.Wrapf(err, "error reading name of symlink for %q", dir))
|
||||
errs = multierror.Append(errs, errors.Wrapf(err, "reading name of symlink for %q", dir))
|
||||
continue
|
||||
}
|
||||
linkPath := path.Join(d.home, linkDir, strings.Trim(string(data), "\n"))
|
||||
@ -1162,7 +1189,7 @@ func (d *Driver) recreateSymlinks() error {
|
||||
}
|
||||
madeProgress = true
|
||||
} else if err != nil {
|
||||
errs = multierror.Append(errs, errors.Wrapf(err, "error trying to stat %q", linkPath))
|
||||
errs = multierror.Append(errs, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
@ -1170,7 +1197,7 @@ func (d *Driver) recreateSymlinks() error {
|
||||
// that each symlink we have corresponds to one.
|
||||
links, err := ioutil.ReadDir(linksDir)
|
||||
if err != nil {
|
||||
errs = multierror.Append(errs, errors.Wrapf(err, "error reading links directory %q", linksDir))
|
||||
errs = multierror.Append(errs, err)
|
||||
continue
|
||||
}
|
||||
// Go through all of the symlinks in the "l" directory
|
||||
@ -1178,7 +1205,7 @@ func (d *Driver) recreateSymlinks() error {
|
||||
// Read the symlink's target, which should be "../$layer/diff"
|
||||
target, err := os.Readlink(filepath.Join(linksDir, link.Name()))
|
||||
if err != nil {
|
||||
errs = multierror.Append(errs, errors.Wrapf(err, "error reading target of link %q", link))
|
||||
errs = multierror.Append(errs, err)
|
||||
continue
|
||||
}
|
||||
targetComponents := strings.Split(target, string(os.PathSeparator))
|
||||
@ -1196,7 +1223,7 @@ func (d *Driver) recreateSymlinks() error {
|
||||
data, err := ioutil.ReadFile(linkFile)
|
||||
if err != nil || string(data) != link.Name() {
|
||||
if err := ioutil.WriteFile(linkFile, []byte(link.Name()), 0644); err != nil {
|
||||
errs = multierror.Append(errs, errors.Wrapf(err, "error correcting link for layer %q", targetID))
|
||||
errs = multierror.Append(errs, errors.Wrapf(err, "correcting link for layer %s", targetID))
|
||||
continue
|
||||
}
|
||||
madeProgress = true
|
||||
@ -1241,7 +1268,7 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
|
||||
if unshare.IsRootless() {
|
||||
logLevel = logrus.DebugLevel
|
||||
}
|
||||
logrus.StandardLogger().Logf(logLevel, "ignoring metacopy option from storage.conf, not supported with booted kernel")
|
||||
logrus.StandardLogger().Logf(logLevel, "Ignoring metacopy option from storage.conf, not supported with booted kernel")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1275,7 +1302,7 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
|
||||
}
|
||||
logrus.Warnf("Can't read parent link %q because it does not exist. Going through storage to recreate the missing links.", path.Join(dir, "link"))
|
||||
if err := d.recreateSymlinks(); err != nil {
|
||||
return "", errors.Wrap(err, "error recreating the links")
|
||||
return "", errors.Wrap(err, "recreating the links")
|
||||
}
|
||||
link, err = ioutil.ReadFile(path.Join(dir, "link"))
|
||||
if err != nil {
|
||||
@ -1330,7 +1357,7 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
|
||||
if lower == "" && os.IsNotExist(err) {
|
||||
logrus.Warnf("Can't stat lower layer %q because it does not exist. Going through storage to recreate the missing symlinks.", newpath)
|
||||
if err := d.recreateSymlinks(); err != nil {
|
||||
return "", fmt.Errorf("error recreating the missing symlinks: %v", err)
|
||||
return "", fmt.Errorf("Recreating the missing symlinks: %v", err)
|
||||
}
|
||||
lower = newpath
|
||||
} else if lower == "" {
|
||||
@ -1381,7 +1408,7 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
|
||||
if retErr != nil {
|
||||
if c := d.ctr.Decrement(mergedDir); c <= 0 {
|
||||
if mntErr := unix.Unmount(mergedDir, 0); mntErr != nil {
|
||||
logrus.Errorf("error unmounting %v: %v", mergedDir, mntErr)
|
||||
logrus.Errorf("Unmounting %v: %v", mergedDir, mntErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1430,6 +1457,11 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
|
||||
label = d.optsAppendMappings(label, options.UidMaps, options.GidMaps)
|
||||
}
|
||||
|
||||
// if forceMask is in place, tell fuse-overlayfs to write the permissions mask to an unprivileged xattr as well.
|
||||
if d.options.forceMask != nil {
|
||||
label = label + ",xattr_permissions=2"
|
||||
}
|
||||
|
||||
mountProgram := exec.Command(d.options.mountProgram, "-o", label, target)
|
||||
mountProgram.Dir = d.home
|
||||
var b bytes.Buffer
|
||||
@ -1473,7 +1505,7 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
|
||||
flags, data := mount.ParseOptions(mountData)
|
||||
logrus.Debugf("overlay: mount_data=%s", mountData)
|
||||
if err := mountFunc("overlay", mountTarget, "overlay", uintptr(flags), data); err != nil {
|
||||
return "", fmt.Errorf("error creating overlay mount to %s, mount_data=%q: %v", mountTarget, mountData, err)
|
||||
return "", fmt.Errorf("creating overlay mount to %s, mount_data=%q: %v", mountTarget, mountData, err)
|
||||
}
|
||||
|
||||
return mergedDir, nil
|
||||
@ -1820,7 +1852,7 @@ func (d *Driver) UpdateLayerIDMap(id string, toContainer, toHost *idtools.IDMapp
|
||||
err = graphdriver.ChownPathByMaps(layerFs, toContainer, toHost)
|
||||
if err != nil {
|
||||
if err2 := d.Put(id); err2 != nil {
|
||||
logrus.Errorf("%v; error unmounting %v: %v", err, id, err2)
|
||||
logrus.Errorf("%v; unmounting %v: %v", err, id, err2)
|
||||
}
|
||||
return err
|
||||
}
|
||||
@ -1923,7 +1955,7 @@ func (d *Driver) releaseAdditionalLayerByID(id string) {
|
||||
if al, err := d.getAdditionalLayerPathByID(id); err == nil {
|
||||
notifyReleaseAdditionalLayer(al)
|
||||
} else if !os.IsNotExist(err) {
|
||||
logrus.Warnf("unexpected error on reading Additional Layer Store pointer %v", err)
|
||||
logrus.Warnf("Unexpected error on reading Additional Layer Store pointer %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -2004,10 +2036,10 @@ func notifyUseAdditionalLayer(al string) {
|
||||
} else if err == nil {
|
||||
f.Close()
|
||||
if err := os.Remove(useFile); err != nil {
|
||||
logrus.Warnf("failed to remove use file")
|
||||
logrus.Warnf("Failed to remove use file")
|
||||
}
|
||||
}
|
||||
logrus.Warnf("unexpected error by Additional Layer Store %v during use; GC doesn't seem to be supported", err)
|
||||
logrus.Warnf("Unexpected error by Additional Layer Store %v during use; GC doesn't seem to be supported", err)
|
||||
}
|
||||
|
||||
// notifyReleaseAdditionalLayer notifies Additional Layer Store that we don't use the specified
|
||||
@ -2024,7 +2056,7 @@ func notifyReleaseAdditionalLayer(al string) {
|
||||
if os.IsNotExist(err) {
|
||||
return
|
||||
}
|
||||
logrus.Warnf("unexpected error by Additional Layer Store %v during release; GC doesn't seem to be supported", err)
|
||||
logrus.Warnf("Unexpected error by Additional Layer Store %v during release; GC doesn't seem to be supported", err)
|
||||
}
|
||||
|
||||
// redirectDiffIfAdditionalLayer checks if the passed diff path is Additional Layer and
|
||||
|
2
vendor/github.com/containers/storage/drivers/overlay/randomid.go
generated
vendored
2
vendor/github.com/containers/storage/drivers/overlay/randomid.go
generated
vendored
@ -47,7 +47,7 @@ func generateID(l int) string {
|
||||
if retryOnError(err) && retries < maxretries {
|
||||
count += n
|
||||
retries++
|
||||
logrus.Errorf("error generating version 4 uuid, retrying: %v", err)
|
||||
logrus.Errorf("Generating version 4 uuid, retrying: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
|
4
vendor/github.com/containers/storage/drivers/template.go
generated
vendored
4
vendor/github.com/containers/storage/drivers/template.go
generated
vendored
@ -31,7 +31,7 @@ func NaiveCreateFromTemplate(d TemplateDriver, id, template string, templateIDMa
|
||||
diff, err := d.Diff(template, templateIDMappings, parent, parentIDMappings, opts.MountLabel)
|
||||
if err != nil {
|
||||
if err2 := d.Remove(id); err2 != nil {
|
||||
logrus.Errorf("error removing layer %q: %v", id, err2)
|
||||
logrus.Errorf("Removing layer %q: %v", id, err2)
|
||||
}
|
||||
return err
|
||||
}
|
||||
@ -44,7 +44,7 @@ func NaiveCreateFromTemplate(d TemplateDriver, id, template string, templateIDMa
|
||||
}
|
||||
if _, err = d.ApplyDiff(id, parent, applyOptions); err != nil {
|
||||
if err2 := d.Remove(id); err2 != nil {
|
||||
logrus.Errorf("error removing layer %q: %v", id, err2)
|
||||
logrus.Errorf("Removing layer %q: %v", id, err2)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
7
vendor/github.com/containers/storage/go.mod
generated
vendored
7
vendor/github.com/containers/storage/go.mod
generated
vendored
@ -6,20 +6,19 @@ require (
|
||||
github.com/BurntSushi/toml v0.4.1
|
||||
github.com/Microsoft/go-winio v0.5.0
|
||||
github.com/Microsoft/hcsshim v0.8.22
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.8.0
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.9.0
|
||||
github.com/docker/go-units v0.4.0
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
|
||||
github.com/google/go-intervals v0.0.2
|
||||
github.com/google/uuid v1.2.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
github.com/json-iterator/go v1.1.11
|
||||
github.com/klauspost/compress v1.13.5
|
||||
github.com/json-iterator/go v1.1.12
|
||||
github.com/klauspost/compress v1.13.6
|
||||
github.com/klauspost/pgzip v1.2.5
|
||||
github.com/mattn/go-shellwords v1.0.12
|
||||
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible
|
||||
github.com/moby/sys/mountinfo v0.4.1
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0
|
||||
github.com/opencontainers/runc v1.0.2
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417
|
||||
|
17
vendor/github.com/containers/storage/go.sum
generated
vendored
17
vendor/github.com/containers/storage/go.sum
generated
vendored
@ -31,8 +31,8 @@ github.com/containerd/containerd v1.4.9/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMX
|
||||
github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM=
|
||||
github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4=
|
||||
github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.8.0 h1:oA1wx8kTFfImfsT5bScbrZd8gK+WtQnn15q82Djvm0Y=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.8.0/go.mod h1:mwIwuwb+D8FX2t45Trwi0hmWmZm5VW7zPP/rekwhWQU=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.9.0 h1:PkB6BSTfOKX23erT2GkoUKkJEcXfNcyKskIViK770v8=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.9.0/go.mod h1:aE5PCyhFMwR8sbrErO5eM2GcvkyXTTJremG883D4qF0=
|
||||
github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y=
|
||||
github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
@ -115,15 +115,15 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.13.5 h1:9O69jUPDcsT9fEm74W92rZL9FQY7rCdaXVneq+yyzl4=
|
||||
github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
|
||||
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
@ -148,9 +148,8 @@ github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2J
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
|
2
vendor/github.com/containers/storage/layers.go
generated
vendored
2
vendor/github.com/containers/storage/layers.go
generated
vendored
@ -1557,7 +1557,7 @@ func (r *layerStore) applyDiffWithOptions(to string, layerOptions *LayerOptions,
|
||||
compressor = pgzip.NewWriter(&tsdata)
|
||||
}
|
||||
if err := compressor.SetConcurrency(1024*1024, 1); err != nil { // 1024*1024 is the hard-coded default; we're not changing that
|
||||
logrus.Infof("error setting compression concurrency threads to 1: %v; ignoring", err)
|
||||
logrus.Infof("Error setting compression concurrency threads to 1: %v; ignoring", err)
|
||||
}
|
||||
metadata := storage.NewJSONPacker(compressor)
|
||||
uncompressed, err := archive.DecompressStream(defragmented)
|
||||
|
2
vendor/github.com/containers/storage/pkg/archive/archive.go
generated
vendored
2
vendor/github.com/containers/storage/pkg/archive/archive.go
generated
vendored
@ -879,7 +879,7 @@ func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error)
|
||||
if include != relFilePath {
|
||||
matches, err := pm.IsMatch(relFilePath)
|
||||
if err != nil {
|
||||
logrus.Errorf("Error matching %s: %v", relFilePath, err)
|
||||
logrus.Errorf("Matching %s: %v", relFilePath, err)
|
||||
return err
|
||||
}
|
||||
skip = matches
|
||||
|
86
vendor/github.com/containers/storage/pkg/chunked/storage_linux.go
generated
vendored
86
vendor/github.com/containers/storage/pkg/chunked/storage_linux.go
generated
vendored
@ -345,6 +345,56 @@ func getFileDigest(f *os.File) (digest.Digest, error) {
|
||||
return digester.Digest(), nil
|
||||
}
|
||||
|
||||
// findFileInOSTreeRepos checks whether the requested file already exist in one of the OSTree repo and copies the file content from there if possible.
|
||||
// file is the file to look for.
|
||||
// ostreeRepos is a list of OSTree repos.
|
||||
// dirfd is an open fd to the destination checkout.
|
||||
// useHardLinks defines whether the deduplication can be performed using hard links.
|
||||
func findFileInOSTreeRepos(file *internal.FileMetadata, ostreeRepos []string, dirfd int, useHardLinks bool) (bool, *os.File, int64, error) {
|
||||
digest, err := digest.Parse(file.Digest)
|
||||
if err != nil {
|
||||
return false, nil, 0, nil
|
||||
}
|
||||
payloadLink := digest.Encoded() + ".payload-link"
|
||||
if len(payloadLink) < 2 {
|
||||
return false, nil, 0, nil
|
||||
}
|
||||
|
||||
for _, repo := range ostreeRepos {
|
||||
sourceFile := filepath.Join(repo, "objects", payloadLink[:2], payloadLink[2:])
|
||||
st, err := os.Stat(sourceFile)
|
||||
if err != nil || !st.Mode().IsRegular() {
|
||||
continue
|
||||
}
|
||||
if st.Size() != file.Size {
|
||||
continue
|
||||
}
|
||||
fd, err := unix.Open(sourceFile, unix.O_RDONLY|unix.O_NONBLOCK, 0)
|
||||
if err != nil {
|
||||
return false, nil, 0, nil
|
||||
}
|
||||
f := os.NewFile(uintptr(fd), "fd")
|
||||
defer f.Close()
|
||||
|
||||
// check if the open file can be deduplicated with hard links
|
||||
if useHardLinks && !canDedupFileWithHardLink(file, fd, st) {
|
||||
continue
|
||||
}
|
||||
|
||||
dstFile, written, err := copyFileContent(fd, file.Name, dirfd, 0, useHardLinks)
|
||||
if err != nil {
|
||||
return false, nil, 0, nil
|
||||
}
|
||||
return true, dstFile, written, nil
|
||||
}
|
||||
// If hard links deduplication was used and it has failed, try again without hard links.
|
||||
if useHardLinks {
|
||||
return findFileInOSTreeRepos(file, ostreeRepos, dirfd, false)
|
||||
}
|
||||
|
||||
return false, nil, 0, nil
|
||||
}
|
||||
|
||||
// findFileOnTheHost checks whether the requested file already exist on the host and copies the file content from there if possible.
|
||||
// It is currently implemented to look only at the file with the same path. Ideally it can detect the same content also at different
|
||||
// paths.
|
||||
@ -873,6 +923,9 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions) (gra
|
||||
// modifies the source file as well.
|
||||
useHardLinks := parseBooleanPullOption(&storeOpts, "use_hard_links", false)
|
||||
|
||||
// List of OSTree repositories to use for deduplication
|
||||
ostreeRepos := strings.Split(storeOpts.PullOptions["ostree_repos"], ":")
|
||||
|
||||
// Generate the manifest
|
||||
var toc internal.TOC
|
||||
if err := json.Unmarshal(c.manifest, &toc); err != nil {
|
||||
@ -1009,18 +1062,35 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions) (gra
|
||||
|
||||
totalChunksSize += r.Size
|
||||
|
||||
finalizeFile := func(dstFile *os.File) error {
|
||||
if dstFile != nil {
|
||||
defer dstFile.Close()
|
||||
if err := setFileAttrs(dstFile, mode, &r, options); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
found, dstFile, _, err := findFileInOtherLayers(&r, dirfd, otherLayersCache, c.layersTarget, useHardLinks)
|
||||
if err != nil {
|
||||
return output, err
|
||||
}
|
||||
if dstFile != nil {
|
||||
if err := setFileAttrs(dstFile, mode, &r, options); err != nil {
|
||||
dstFile.Close()
|
||||
if found {
|
||||
if err := finalizeFile(dstFile); err != nil {
|
||||
return output, err
|
||||
}
|
||||
dstFile.Close()
|
||||
continue
|
||||
}
|
||||
|
||||
found, dstFile, _, err = findFileInOSTreeRepos(&r, ostreeRepos, dirfd, useHardLinks)
|
||||
if err != nil {
|
||||
return output, err
|
||||
}
|
||||
if found {
|
||||
if err := finalizeFile(dstFile); err != nil {
|
||||
return output, err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
@ -1029,14 +1099,10 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions) (gra
|
||||
if err != nil {
|
||||
return output, err
|
||||
}
|
||||
if dstFile != nil {
|
||||
if err := setFileAttrs(dstFile, mode, &r, options); err != nil {
|
||||
dstFile.Close()
|
||||
if found {
|
||||
if err := finalizeFile(dstFile); err != nil {
|
||||
return output, err
|
||||
}
|
||||
dstFile.Close()
|
||||
}
|
||||
if found {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
2
vendor/github.com/containers/storage/pkg/fileutils/fileutils_unix.go
generated
vendored
2
vendor/github.com/containers/storage/pkg/fileutils/fileutils_unix.go
generated
vendored
@ -14,7 +14,7 @@ import (
|
||||
// reading it via /proc filesystem.
|
||||
func GetTotalUsedFds() int {
|
||||
if fds, err := ioutil.ReadDir(fmt.Sprintf("/proc/%d/fd", os.Getpid())); err != nil {
|
||||
logrus.Errorf("Error opening /proc/%d/fd: %s", os.Getpid(), err)
|
||||
logrus.Errorf("%v", err)
|
||||
} else {
|
||||
return len(fds)
|
||||
}
|
||||
|
2
vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go
generated
vendored
2
vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go
generated
vendored
@ -36,7 +36,7 @@ type lockfile struct {
|
||||
// necessary.
|
||||
func openLock(path string, ro bool) (fd int, err error) {
|
||||
if ro {
|
||||
fd, err = unix.Open(path, os.O_RDONLY|unix.O_CLOEXEC, 0)
|
||||
fd, err = unix.Open(path, os.O_RDONLY|unix.O_CLOEXEC|os.O_CREATE, 0)
|
||||
} else {
|
||||
fd, err = unix.Open(path,
|
||||
os.O_RDWR|unix.O_CLOEXEC|os.O_CREATE,
|
||||
|
10
vendor/github.com/containers/storage/pkg/loopback/attach_loopback.go
generated
vendored
10
vendor/github.com/containers/storage/pkg/loopback/attach_loopback.go
generated
vendored
@ -43,7 +43,7 @@ func openNextAvailableLoopback(index int, sparseName string, sparseFile *os.File
|
||||
var st syscall.Stat_t
|
||||
err = syscall.Fstat(int(sparseFile.Fd()), &st)
|
||||
if err != nil {
|
||||
logrus.Errorf("Error reading information about loopback file %s: %v", sparseName, err)
|
||||
logrus.Errorf("Reading information about loopback file %s: %v", sparseName, err)
|
||||
return nil, ErrAttachLoopbackDevice
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ func openNextAvailableLoopback(index int, sparseName string, sparseFile *os.File
|
||||
// OpenFile adds O_CLOEXEC
|
||||
loopFile, err = os.OpenFile(target, os.O_RDWR, 0644)
|
||||
if err != nil {
|
||||
logrus.Errorf("Error opening loopback device: %s", err)
|
||||
logrus.Errorf("Opening loopback device: %s", err)
|
||||
return nil, ErrAttachLoopbackDevice
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ func openNextAvailableLoopback(index int, sparseName string, sparseFile *os.File
|
||||
// device and inode numbers.
|
||||
dev, ino, err := getLoopbackBackingFile(loopFile)
|
||||
if err != nil {
|
||||
logrus.Errorf("Error getting loopback backing file: %s", err)
|
||||
logrus.Errorf("Getting loopback backing file: %s", err)
|
||||
return nil, ErrGetLoopbackBackingFile
|
||||
}
|
||||
if dev != uint64(st.Dev) || ino != st.Ino {
|
||||
@ -125,7 +125,7 @@ func AttachLoopDevice(sparseName string) (loop *os.File, err error) {
|
||||
// OpenFile adds O_CLOEXEC
|
||||
sparseFile, err := os.OpenFile(sparseName, os.O_RDWR, 0644)
|
||||
if err != nil {
|
||||
logrus.Errorf("Error opening sparse file %s: %s", sparseName, err)
|
||||
logrus.Errorf("Opening sparse file: %v", err)
|
||||
return nil, ErrAttachLoopbackDevice
|
||||
}
|
||||
defer sparseFile.Close()
|
||||
@ -147,7 +147,7 @@ func AttachLoopDevice(sparseName string) (loop *os.File, err error) {
|
||||
|
||||
// If the call failed, then free the loopback device
|
||||
if err := ioctlLoopClrFd(loopFile.Fd()); err != nil {
|
||||
logrus.Error("Error while cleaning up the loopback device")
|
||||
logrus.Error("While cleaning up the loopback device")
|
||||
}
|
||||
loopFile.Close()
|
||||
return nil, ErrAttachLoopbackDevice
|
||||
|
4
vendor/github.com/containers/storage/pkg/loopback/loopback.go
generated
vendored
4
vendor/github.com/containers/storage/pkg/loopback/loopback.go
generated
vendored
@ -13,7 +13,7 @@ import (
|
||||
func getLoopbackBackingFile(file *os.File) (uint64, uint64, error) {
|
||||
loopInfo, err := ioctlLoopGetStatus64(file.Fd())
|
||||
if err != nil {
|
||||
logrus.Errorf("Error get loopback backing file: %s", err)
|
||||
logrus.Errorf("Get loopback backing file: %v", err)
|
||||
return 0, 0, ErrGetLoopbackBackingFile
|
||||
}
|
||||
return loopInfo.loDevice, loopInfo.loInode, nil
|
||||
@ -22,7 +22,7 @@ func getLoopbackBackingFile(file *os.File) (uint64, uint64, error) {
|
||||
// SetCapacity reloads the size for the loopback device.
|
||||
func SetCapacity(file *os.File) error {
|
||||
if err := ioctlLoopSetCapacity(file.Fd(), 0); err != nil {
|
||||
logrus.Errorf("Error loopbackSetCapacity: %s", err)
|
||||
logrus.Errorf("loopbackSetCapacity: %s", err)
|
||||
return ErrSetCapacity
|
||||
}
|
||||
return nil
|
||||
|
2
vendor/github.com/containers/storage/pkg/parsers/kernel/kernel_unix.go
generated
vendored
2
vendor/github.com/containers/storage/pkg/parsers/kernel/kernel_unix.go
generated
vendored
@ -35,7 +35,7 @@ func GetKernelVersion() (*VersionInfo, error) {
|
||||
// the given version.
|
||||
func CheckKernelVersion(k, major, minor int) bool {
|
||||
if v, err := GetKernelVersion(); err != nil {
|
||||
logrus.Warnf("error getting kernel version: %s", err)
|
||||
logrus.Warnf("Error getting kernel version: %s", err)
|
||||
} else {
|
||||
if CompareKernelVersion(*v, VersionInfo{Kernel: k, Major: major, Minor: minor}) < 0 {
|
||||
return false
|
||||
|
12
vendor/github.com/containers/storage/pkg/system/syscall_unix.go
generated
vendored
12
vendor/github.com/containers/storage/pkg/system/syscall_unix.go
generated
vendored
@ -1,8 +1,11 @@
|
||||
// +build linux freebsd
|
||||
// +build linux freebsd darwin
|
||||
|
||||
package system
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// Unmount is a platform-specific helper function to call
|
||||
// the unmount syscall.
|
||||
@ -15,3 +18,8 @@ func Unmount(dest string) error {
|
||||
func CommandLineToArgv(commandLine string) ([]string, error) {
|
||||
return []string{commandLine}, nil
|
||||
}
|
||||
|
||||
// IsEBUSY checks if the specified error is EBUSY.
|
||||
func IsEBUSY(err error) bool {
|
||||
return errors.Is(err, unix.EBUSY)
|
||||
}
|
||||
|
5
vendor/github.com/containers/storage/pkg/system/syscall_windows.go
generated
vendored
5
vendor/github.com/containers/storage/pkg/system/syscall_windows.go
generated
vendored
@ -120,3 +120,8 @@ func HasWin32KSupport() bool {
|
||||
// APIs.
|
||||
return ntuserApiset.Load() == nil
|
||||
}
|
||||
|
||||
// IsEBUSY checks if the specified error is EBUSY.
|
||||
func IsEBUSY(err error) bool {
|
||||
return false
|
||||
}
|
||||
|
2
vendor/github.com/containers/storage/pkg/tarlog/tarlogger.go
generated
vendored
2
vendor/github.com/containers/storage/pkg/tarlog/tarlogger.go
generated
vendored
@ -34,7 +34,7 @@ func NewLogger(logger func(*tar.Header)) (io.WriteCloser, error) {
|
||||
}
|
||||
// Make sure to avoid writes after the reader has been closed.
|
||||
if err := reader.Close(); err != nil {
|
||||
logrus.Errorf("error closing tarlogger reader: %v", err)
|
||||
logrus.Errorf("Closing tarlogger reader: %v", err)
|
||||
}
|
||||
// Unblock the Close().
|
||||
t.closeMutex.Unlock()
|
||||
|
30
vendor/github.com/containers/storage/pkg/unshare/unshare_linux.go
generated
vendored
30
vendor/github.com/containers/storage/pkg/unshare/unshare_linux.go
generated
vendored
@ -154,7 +154,7 @@ func (c *Cmd) Start() error {
|
||||
pidString := ""
|
||||
b := new(bytes.Buffer)
|
||||
if _, err := io.Copy(b, pidRead); err != nil {
|
||||
return errors.Wrapf(err, "error reading child PID")
|
||||
return errors.Wrapf(err, "Reading child PID")
|
||||
}
|
||||
pidString = b.String()
|
||||
pid, err := strconv.Atoi(pidString)
|
||||
@ -188,8 +188,8 @@ func (c *Cmd) Start() error {
|
||||
if len(c.UidMappings) == 0 || len(c.GidMappings) == 0 {
|
||||
uidmap, gidmap, err := GetHostIDMappings("")
|
||||
if err != nil {
|
||||
fmt.Fprintf(continueWrite, "error reading ID mappings in parent: %v", err)
|
||||
return errors.Wrapf(err, "error reading ID mappings in parent")
|
||||
fmt.Fprintf(continueWrite, "Reading ID mappings in parent: %v", err)
|
||||
return errors.Wrapf(err, "Reading ID mappings in parent")
|
||||
}
|
||||
if len(c.UidMappings) == 0 {
|
||||
c.UidMappings = uidmap
|
||||
@ -222,8 +222,8 @@ func (c *Cmd) Start() error {
|
||||
if err == nil {
|
||||
gidmapSet = true
|
||||
} else {
|
||||
logrus.Warnf("error running newgidmap: %v: %s", err, g.String())
|
||||
logrus.Warnf("falling back to single mapping")
|
||||
logrus.Warnf("Error running newgidmap: %v: %s", err, g.String())
|
||||
logrus.Warnf("Falling back to single mapping")
|
||||
g.Reset()
|
||||
g.Write([]byte(fmt.Sprintf("0 %d 1\n", os.Getegid())))
|
||||
}
|
||||
@ -271,8 +271,8 @@ func (c *Cmd) Start() error {
|
||||
if err == nil {
|
||||
uidmapSet = true
|
||||
} else {
|
||||
logrus.Warnf("error running newuidmap: %v: %s", err, u.String())
|
||||
logrus.Warnf("falling back to single mapping")
|
||||
logrus.Warnf("Error running newuidmap: %v: %s", err, u.String())
|
||||
logrus.Warnf("Falling back to single mapping")
|
||||
u.Reset()
|
||||
u.Write([]byte(fmt.Sprintf("0 %d 1\n", os.Geteuid())))
|
||||
}
|
||||
@ -407,7 +407,7 @@ func MaybeReexecUsingUserNamespace(evenForRoot bool) {
|
||||
// ID and a range size.
|
||||
uidmap, gidmap, err = GetSubIDMappings(me.Username, me.Username)
|
||||
if err != nil {
|
||||
logrus.Warnf("error reading allowed ID mappings: %v", err)
|
||||
logrus.Warnf("Reading allowed ID mappings: %v", err)
|
||||
}
|
||||
if len(uidmap) == 0 {
|
||||
logrus.Warnf("Found no UID ranges set aside for user %q in /etc/subuid.", me.Username)
|
||||
@ -434,13 +434,13 @@ func MaybeReexecUsingUserNamespace(evenForRoot bool) {
|
||||
// If we have CAP_SYS_ADMIN, then we don't need to create a new namespace in order to be able
|
||||
// to use unshare(), so don't bother creating a new user namespace at this point.
|
||||
capabilities, err := capability.NewPid(0)
|
||||
bailOnError(err, "error reading the current capabilities sets")
|
||||
bailOnError(err, "Reading the current capabilities sets")
|
||||
if capabilities.Get(capability.EFFECTIVE, capability.CAP_SYS_ADMIN) {
|
||||
return
|
||||
}
|
||||
// Read the set of ID mappings that we're currently using.
|
||||
uidmap, gidmap, err = GetHostIDMappings("")
|
||||
bailOnError(err, "error reading current ID mappings")
|
||||
bailOnError(err, "Reading current ID mappings")
|
||||
// Just reuse them.
|
||||
for i := range uidmap {
|
||||
uidmap[i].HostID = uidmap[i].ContainerID
|
||||
@ -463,7 +463,7 @@ func MaybeReexecUsingUserNamespace(evenForRoot bool) {
|
||||
if _, present := os.LookupEnv("BUILDAH_ISOLATION"); !present {
|
||||
if err = os.Setenv("BUILDAH_ISOLATION", "rootless"); err != nil {
|
||||
if err := os.Setenv("BUILDAH_ISOLATION", "rootless"); err != nil {
|
||||
logrus.Errorf("error setting BUILDAH_ISOLATION=rootless in environment: %v", err)
|
||||
logrus.Errorf("Setting BUILDAH_ISOLATION=rootless in environment: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
@ -483,7 +483,7 @@ func MaybeReexecUsingUserNamespace(evenForRoot bool) {
|
||||
cmd.GidMappingsEnableSetgroups = true
|
||||
|
||||
// Finish up.
|
||||
logrus.Debugf("running %+v with environment %+v, UID map %+v, and GID map %+v", cmd.Cmd.Args, os.Environ(), cmd.UidMappings, cmd.GidMappings)
|
||||
logrus.Debugf("Running %+v with environment %+v, UID map %+v, and GID map %+v", cmd.Cmd.Args, os.Environ(), cmd.UidMappings, cmd.GidMappings)
|
||||
ExecRunnable(cmd, nil)
|
||||
}
|
||||
|
||||
@ -512,7 +512,7 @@ func ExecRunnable(cmd Runnable, cleanup func()) {
|
||||
}
|
||||
}
|
||||
logrus.Errorf("%v", err)
|
||||
logrus.Errorf("(unable to determine exit status)")
|
||||
logrus.Errorf("(Unable to determine exit status)")
|
||||
exit(1)
|
||||
}
|
||||
exit(0)
|
||||
@ -523,7 +523,7 @@ func getHostIDMappings(path string) ([]specs.LinuxIDMapping, error) {
|
||||
var mappings []specs.LinuxIDMapping
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error reading ID mappings from %q", path)
|
||||
return nil, errors.Wrapf(err, "Reading ID mappings from %q", path)
|
||||
}
|
||||
defer f.Close()
|
||||
scanner := bufio.NewScanner(f)
|
||||
@ -571,7 +571,7 @@ func GetHostIDMappings(pid string) ([]specs.LinuxIDMapping, []specs.LinuxIDMappi
|
||||
func GetSubIDMappings(user, group string) ([]specs.LinuxIDMapping, []specs.LinuxIDMapping, error) {
|
||||
mappings, err := idtools.NewIDMappings(user, group)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrapf(err, "error reading subuid mappings for user %q and subgid mappings for group %q", user, group)
|
||||
return nil, nil, errors.Wrapf(err, "Reading subuid mappings for user %q and subgid mappings for group %q", user, group)
|
||||
}
|
||||
var uidmap, gidmap []specs.LinuxIDMapping
|
||||
for _, m := range mappings.UIDs() {
|
||||
|
15
vendor/github.com/containers/storage/store.go
generated
vendored
15
vendor/github.com/containers/storage/store.go
generated
vendored
@ -23,6 +23,7 @@ import (
|
||||
"github.com/containers/storage/pkg/parsers"
|
||||
"github.com/containers/storage/pkg/stringid"
|
||||
"github.com/containers/storage/pkg/stringutils"
|
||||
"github.com/containers/storage/pkg/system"
|
||||
"github.com/containers/storage/types"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
@ -1131,10 +1132,6 @@ func (s *store) imageTopLayerForMapping(image *Image, ristore ROImageStore, crea
|
||||
if options.HostGIDMapping && len(layer.GIDMap) != 0 {
|
||||
return false
|
||||
}
|
||||
// If we don't care about the mapping, it's fine.
|
||||
if len(options.UIDMap) == 0 && len(options.GIDMap) == 0 {
|
||||
return true
|
||||
}
|
||||
// Compare the maps.
|
||||
return reflect.DeepEqual(layer.UIDMap, options.UIDMap) && reflect.DeepEqual(layer.GIDMap, options.GIDMap)
|
||||
}
|
||||
@ -2502,7 +2499,15 @@ func (s *store) DeleteContainer(id string) error {
|
||||
gcpath := filepath.Join(s.GraphRoot(), middleDir, container.ID)
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
errChan <- os.RemoveAll(gcpath)
|
||||
var err error
|
||||
for attempts := 0; attempts < 50; attempts++ {
|
||||
err = os.RemoveAll(gcpath)
|
||||
if err == nil || !system.IsEBUSY(err) {
|
||||
break
|
||||
}
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
}
|
||||
errChan <- err
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
|
2
vendor/github.com/containers/storage/types/utils.go
generated
vendored
2
vendor/github.com/containers/storage/types/utils.go
generated
vendored
@ -87,7 +87,7 @@ func getRootlessRuntimeDirIsolated(env rootlessRuntimeDirEnvironment) (string, e
|
||||
if tmpPerUserDir != "" {
|
||||
if _, err := env.systemLstat(tmpPerUserDir); os.IsNotExist(err) {
|
||||
if err := os.Mkdir(tmpPerUserDir, 0700); err != nil {
|
||||
logrus.Errorf("failed to create temp directory for user: %v", err)
|
||||
logrus.Errorf("Failed to create temp directory for user: %v", err)
|
||||
} else {
|
||||
return tmpPerUserDir, nil
|
||||
}
|
||||
|
2
vendor/github.com/containers/storage/userns.go
generated
vendored
2
vendor/github.com/containers/storage/userns.go
generated
vendored
@ -43,7 +43,7 @@ func getAdditionalSubIDs(username string) (*idSet, *idSet, error) {
|
||||
}
|
||||
mappings, err := idtools.NewIDMappings(username, username)
|
||||
if err != nil {
|
||||
logrus.Errorf("cannot find mappings for user %q: %v", username, err)
|
||||
logrus.Errorf("Cannot find mappings for user %q: %v", username, err)
|
||||
} else {
|
||||
uids = getHostIDs(mappings.UIDs())
|
||||
gids = getHostIDs(mappings.GIDs())
|
||||
|
2
vendor/github.com/json-iterator/go/README.md
generated
vendored
2
vendor/github.com/json-iterator/go/README.md
generated
vendored
@ -8,8 +8,6 @@
|
||||
|
||||
A high-performance 100% compatible drop-in replacement of "encoding/json"
|
||||
|
||||
You can also use thrift like JSON using [thrift-iterator](https://github.com/thrift-iterator/go)
|
||||
|
||||
# Benchmark
|
||||
|
||||

|
||||
|
2
vendor/github.com/json-iterator/go/go.mod
generated
vendored
2
vendor/github.com/json-iterator/go/go.mod
generated
vendored
@ -6,6 +6,6 @@ require (
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/google/gofuzz v1.0.0
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742
|
||||
github.com/modern-go/reflect2 v1.0.2
|
||||
github.com/stretchr/testify v1.3.0
|
||||
)
|
||||
|
5
vendor/github.com/json-iterator/go/go.sum
generated
vendored
5
vendor/github.com/json-iterator/go/go.sum
generated
vendored
@ -5,11 +5,10 @@ github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
|
12
vendor/github.com/klauspost/compress/LICENSE
generated
vendored
12
vendor/github.com/klauspost/compress/LICENSE
generated
vendored
@ -290,3 +290,15 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
-----------------
|
||||
|
||||
Files: s2/cmd/internal/filepathx/*
|
||||
|
||||
Copyright 2016 The filepathx Authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
12
vendor/github.com/klauspost/compress/README.md
generated
vendored
12
vendor/github.com/klauspost/compress/README.md
generated
vendored
@ -17,12 +17,17 @@ This package provides various compression algorithms.
|
||||
|
||||
# changelog
|
||||
|
||||
* Aug 30, 2021 (v1.13.5)
|
||||
* gz/zlib/flate: Alias stdlib errors [#425](https://github.com/klauspost/compress/pull/425)
|
||||
* s2: Add block support to commandline tools [#413](https://github.com/klauspost/compress/pull/413)
|
||||
* zstd: pooledZipWriter should return Writers to the same pool [#426](https://github.com/klauspost/compress/pull/426)
|
||||
* Removed golang/snappy as external dependency for tests [#421](https://github.com/klauspost/compress/pull/421)
|
||||
|
||||
* Aug 12, 2021 (v1.13.4)
|
||||
* Add [snappy replacement package](https://github.com/klauspost/compress/tree/master/snappy).
|
||||
* zstd: Fix incorrect encoding in "best" mode [#415](https://github.com/klauspost/compress/pull/415)
|
||||
|
||||
* Aug 3, 2021 (v1.13.3)
|
||||
|
||||
* zstd: Improve Best compression [#404](https://github.com/klauspost/compress/pull/404)
|
||||
* zstd: Fix WriteTo error forwarding [#411](https://github.com/klauspost/compress/pull/411)
|
||||
* gzhttp: Return http.HandlerFunc instead of http.Handler. Unlikely breaking change. [#406](https://github.com/klauspost/compress/pull/406)
|
||||
@ -31,7 +36,6 @@ This package provides various compression algorithms.
|
||||
* zstd: use SpeedBestCompression for level >= 10 [#410](https://github.com/klauspost/compress/pull/410)
|
||||
|
||||
* Jun 14, 2021 (v1.13.1)
|
||||
|
||||
* s2: Add full Snappy output support [#396](https://github.com/klauspost/compress/pull/396)
|
||||
* zstd: Add configurable [Decoder window](https://pkg.go.dev/github.com/klauspost/compress/zstd#WithDecoderMaxWindow) size [#394](https://github.com/klauspost/compress/pull/394)
|
||||
* gzhttp: Add header to skip compression [#389](https://github.com/klauspost/compress/pull/389)
|
||||
@ -64,6 +68,9 @@ This package provides various compression algorithms.
|
||||
* zstd: Reduce memory usage further when using [WithLowerEncoderMem](https://pkg.go.dev/github.com/klauspost/compress/zstd#WithLowerEncoderMem) [#346](https://github.com/klauspost/compress/pull/346)
|
||||
* s2: Fix potential problem with amd64 assembly and profilers [#349](https://github.com/klauspost/compress/pull/349)
|
||||
|
||||
<details>
|
||||
<summary>See changes prior to v1.12.1</summary>
|
||||
|
||||
* Mar 26, 2021 (v1.11.13)
|
||||
* zstd: Big speedup on small dictionary encodes [#344](https://github.com/klauspost/compress/pull/344) [#345](https://github.com/klauspost/compress/pull/345)
|
||||
* zstd: Add [WithLowerEncoderMem](https://pkg.go.dev/github.com/klauspost/compress/zstd#WithLowerEncoderMem) encoder option [#336](https://github.com/klauspost/compress/pull/336)
|
||||
@ -118,6 +125,7 @@ This package provides various compression algorithms.
|
||||
* zstd: Add experimental compression [dictionaries](https://github.com/klauspost/compress/tree/master/zstd#dictionaries) [#281](https://github.com/klauspost/compress/pull/281)
|
||||
* zstd: Fix mixed Write and ReadFrom calls [#282](https://github.com/klauspost/compress/pull/282)
|
||||
* inflate/gz: Limit variable shifts, ~5% faster decompression [#274](https://github.com/klauspost/compress/pull/274)
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>See changes prior to v1.11.0</summary>
|
||||
|
25
vendor/github.com/klauspost/compress/flate/fast_encoder.go
generated
vendored
25
vendor/github.com/klauspost/compress/flate/fast_encoder.go
generated
vendored
@ -215,24 +215,15 @@ func (e *fastGen) Reset() {
|
||||
func matchLen(a, b []byte) int {
|
||||
b = b[:len(a)]
|
||||
var checked int
|
||||
if len(a) >= 4 {
|
||||
// Try 4 bytes first
|
||||
if diff := binary.LittleEndian.Uint32(a) ^ binary.LittleEndian.Uint32(b); diff != 0 {
|
||||
return bits.TrailingZeros32(diff) >> 3
|
||||
}
|
||||
// Switch to 8 byte matching.
|
||||
checked = 4
|
||||
a = a[4:]
|
||||
b = b[4:]
|
||||
for len(a) >= 8 {
|
||||
b = b[:len(a)]
|
||||
if diff := binary.LittleEndian.Uint64(a) ^ binary.LittleEndian.Uint64(b); diff != 0 {
|
||||
return checked + (bits.TrailingZeros64(diff) >> 3)
|
||||
}
|
||||
checked += 8
|
||||
a = a[8:]
|
||||
b = b[8:]
|
||||
|
||||
for len(a) >= 8 {
|
||||
b = b[:len(a)]
|
||||
if diff := binary.LittleEndian.Uint64(a) ^ binary.LittleEndian.Uint64(b); diff != 0 {
|
||||
return checked + (bits.TrailingZeros64(diff) >> 3)
|
||||
}
|
||||
checked += 8
|
||||
a = a[8:]
|
||||
b = b[8:]
|
||||
}
|
||||
b = b[:len(a)]
|
||||
for i := range a {
|
||||
|
267
vendor/github.com/klauspost/compress/huff0/decompress.go
generated
vendored
267
vendor/github.com/klauspost/compress/huff0/decompress.go
generated
vendored
@ -344,35 +344,241 @@ func (d *Decoder) decompress1X8Bit(dst, src []byte) ([]byte, error) {
|
||||
var buf [256]byte
|
||||
var off uint8
|
||||
|
||||
shift := (8 - d.actualTableLog) & 7
|
||||
switch d.actualTableLog {
|
||||
case 8:
|
||||
const shift = 8 - 8
|
||||
for br.off >= 4 {
|
||||
br.fillFast()
|
||||
v := dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+0] = uint8(v.entry >> 8)
|
||||
|
||||
//fmt.Printf("mask: %b, tl:%d\n", mask, d.actualTableLog)
|
||||
for br.off >= 4 {
|
||||
br.fillFast()
|
||||
v := dt[br.peekByteFast()>>shift]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+0] = uint8(v.entry >> 8)
|
||||
v = dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+1] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[br.peekByteFast()>>shift]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+1] = uint8(v.entry >> 8)
|
||||
v = dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+2] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[br.peekByteFast()>>shift]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+2] = uint8(v.entry >> 8)
|
||||
v = dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+3] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[br.peekByteFast()>>shift]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+3] = uint8(v.entry >> 8)
|
||||
|
||||
off += 4
|
||||
if off == 0 {
|
||||
if len(dst)+256 > maxDecodedSize {
|
||||
br.close()
|
||||
return nil, ErrMaxDecodedSizeExceeded
|
||||
off += 4
|
||||
if off == 0 {
|
||||
if len(dst)+256 > maxDecodedSize {
|
||||
br.close()
|
||||
return nil, ErrMaxDecodedSizeExceeded
|
||||
}
|
||||
dst = append(dst, buf[:]...)
|
||||
}
|
||||
dst = append(dst, buf[:]...)
|
||||
}
|
||||
case 7:
|
||||
const shift = 8 - 7
|
||||
for br.off >= 4 {
|
||||
br.fillFast()
|
||||
v := dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+0] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+1] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+2] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+3] = uint8(v.entry >> 8)
|
||||
|
||||
off += 4
|
||||
if off == 0 {
|
||||
if len(dst)+256 > maxDecodedSize {
|
||||
br.close()
|
||||
return nil, ErrMaxDecodedSizeExceeded
|
||||
}
|
||||
dst = append(dst, buf[:]...)
|
||||
}
|
||||
}
|
||||
case 6:
|
||||
const shift = 8 - 6
|
||||
for br.off >= 4 {
|
||||
br.fillFast()
|
||||
v := dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+0] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+1] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+2] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+3] = uint8(v.entry >> 8)
|
||||
|
||||
off += 4
|
||||
if off == 0 {
|
||||
if len(dst)+256 > maxDecodedSize {
|
||||
br.close()
|
||||
return nil, ErrMaxDecodedSizeExceeded
|
||||
}
|
||||
dst = append(dst, buf[:]...)
|
||||
}
|
||||
}
|
||||
case 5:
|
||||
const shift = 8 - 5
|
||||
for br.off >= 4 {
|
||||
br.fillFast()
|
||||
v := dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+0] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+1] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+2] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+3] = uint8(v.entry >> 8)
|
||||
|
||||
off += 4
|
||||
if off == 0 {
|
||||
if len(dst)+256 > maxDecodedSize {
|
||||
br.close()
|
||||
return nil, ErrMaxDecodedSizeExceeded
|
||||
}
|
||||
dst = append(dst, buf[:]...)
|
||||
}
|
||||
}
|
||||
case 4:
|
||||
const shift = 8 - 4
|
||||
for br.off >= 4 {
|
||||
br.fillFast()
|
||||
v := dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+0] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+1] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+2] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+3] = uint8(v.entry >> 8)
|
||||
|
||||
off += 4
|
||||
if off == 0 {
|
||||
if len(dst)+256 > maxDecodedSize {
|
||||
br.close()
|
||||
return nil, ErrMaxDecodedSizeExceeded
|
||||
}
|
||||
dst = append(dst, buf[:]...)
|
||||
}
|
||||
}
|
||||
case 3:
|
||||
const shift = 8 - 3
|
||||
for br.off >= 4 {
|
||||
br.fillFast()
|
||||
v := dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+0] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+1] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+2] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+3] = uint8(v.entry >> 8)
|
||||
|
||||
off += 4
|
||||
if off == 0 {
|
||||
if len(dst)+256 > maxDecodedSize {
|
||||
br.close()
|
||||
return nil, ErrMaxDecodedSizeExceeded
|
||||
}
|
||||
dst = append(dst, buf[:]...)
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
const shift = 8 - 2
|
||||
for br.off >= 4 {
|
||||
br.fillFast()
|
||||
v := dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+0] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+1] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+2] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+3] = uint8(v.entry >> 8)
|
||||
|
||||
off += 4
|
||||
if off == 0 {
|
||||
if len(dst)+256 > maxDecodedSize {
|
||||
br.close()
|
||||
return nil, ErrMaxDecodedSizeExceeded
|
||||
}
|
||||
dst = append(dst, buf[:]...)
|
||||
}
|
||||
}
|
||||
case 1:
|
||||
const shift = 8 - 1
|
||||
for br.off >= 4 {
|
||||
br.fillFast()
|
||||
v := dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+0] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+1] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+2] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[uint8(br.value>>(56+shift))]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+3] = uint8(v.entry >> 8)
|
||||
|
||||
off += 4
|
||||
if off == 0 {
|
||||
if len(dst)+256 > maxDecodedSize {
|
||||
br.close()
|
||||
return nil, ErrMaxDecodedSizeExceeded
|
||||
}
|
||||
dst = append(dst, buf[:]...)
|
||||
}
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid tablelog: %d", d.actualTableLog)
|
||||
}
|
||||
|
||||
if len(dst)+int(off) > maxDecodedSize {
|
||||
@ -383,6 +589,8 @@ func (d *Decoder) decompress1X8Bit(dst, src []byte) ([]byte, error) {
|
||||
|
||||
// br < 4, so uint8 is fine
|
||||
bitsLeft := int8(uint8(br.off)*8 + (64 - br.bitsRead))
|
||||
shift := (8 - d.actualTableLog) & 7
|
||||
|
||||
for bitsLeft > 0 {
|
||||
if br.bitsRead >= 64-8 {
|
||||
for br.off > 0 {
|
||||
@ -423,24 +631,24 @@ func (d *Decoder) decompress1X8BitExactly(dst, src []byte) ([]byte, error) {
|
||||
var buf [256]byte
|
||||
var off uint8
|
||||
|
||||
const shift = 0
|
||||
const shift = 56
|
||||
|
||||
//fmt.Printf("mask: %b, tl:%d\n", mask, d.actualTableLog)
|
||||
for br.off >= 4 {
|
||||
br.fillFast()
|
||||
v := dt[br.peekByteFast()>>shift]
|
||||
v := dt[uint8(br.value>>shift)]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+0] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[br.peekByteFast()>>shift]
|
||||
v = dt[uint8(br.value>>shift)]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+1] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[br.peekByteFast()>>shift]
|
||||
v = dt[uint8(br.value>>shift)]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+2] = uint8(v.entry >> 8)
|
||||
|
||||
v = dt[br.peekByteFast()>>shift]
|
||||
v = dt[uint8(br.value>>shift)]
|
||||
br.advance(uint8(v.entry))
|
||||
buf[off+3] = uint8(v.entry >> 8)
|
||||
|
||||
@ -474,7 +682,7 @@ func (d *Decoder) decompress1X8BitExactly(dst, src []byte) ([]byte, error) {
|
||||
br.close()
|
||||
return nil, ErrMaxDecodedSizeExceeded
|
||||
}
|
||||
v := dt[br.peekByteFast()>>shift]
|
||||
v := dt[br.peekByteFast()]
|
||||
nBits := uint8(v.entry)
|
||||
br.advance(nBits)
|
||||
bitsLeft -= int8(nBits)
|
||||
@ -709,7 +917,6 @@ func (d *Decoder) decompress4X8bit(dst, src []byte) ([]byte, error) {
|
||||
shift := (8 - d.actualTableLog) & 7
|
||||
|
||||
const tlSize = 1 << 8
|
||||
const tlMask = tlSize - 1
|
||||
single := d.dt.single[:tlSize]
|
||||
|
||||
// Use temp table to avoid bound checks/append penalty.
|
||||
|
1
vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash.go
generated
vendored
1
vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash.go
generated
vendored
@ -195,7 +195,6 @@ func (d *Digest) UnmarshalBinary(b []byte) error {
|
||||
b, d.v4 = consumeUint64(b)
|
||||
b, d.total = consumeUint64(b)
|
||||
copy(d.mem[:], b)
|
||||
b = b[len(d.mem):]
|
||||
d.n = int(d.total % uint64(len(d.mem)))
|
||||
return nil
|
||||
}
|
||||
|
2
vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.go
generated
vendored
2
vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.go
generated
vendored
@ -9,4 +9,4 @@ package xxhash
|
||||
func Sum64(b []byte) uint64
|
||||
|
||||
//go:noescape
|
||||
func writeBlocks(*Digest, []byte) int
|
||||
func writeBlocks(d *Digest, b []byte) int
|
||||
|
66
vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.s
generated
vendored
66
vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.s
generated
vendored
@ -6,7 +6,7 @@
|
||||
|
||||
// Register allocation:
|
||||
// AX h
|
||||
// CX pointer to advance through b
|
||||
// SI pointer to advance through b
|
||||
// DX n
|
||||
// BX loop end
|
||||
// R8 v1, k1
|
||||
@ -16,39 +16,39 @@
|
||||
// R12 tmp
|
||||
// R13 prime1v
|
||||
// R14 prime2v
|
||||
// R15 prime4v
|
||||
// DI prime4v
|
||||
|
||||
// round reads from and advances the buffer pointer in CX.
|
||||
// round reads from and advances the buffer pointer in SI.
|
||||
// It assumes that R13 has prime1v and R14 has prime2v.
|
||||
#define round(r) \
|
||||
MOVQ (CX), R12 \
|
||||
ADDQ $8, CX \
|
||||
MOVQ (SI), R12 \
|
||||
ADDQ $8, SI \
|
||||
IMULQ R14, R12 \
|
||||
ADDQ R12, r \
|
||||
ROLQ $31, r \
|
||||
IMULQ R13, r
|
||||
|
||||
// mergeRound applies a merge round on the two registers acc and val.
|
||||
// It assumes that R13 has prime1v, R14 has prime2v, and R15 has prime4v.
|
||||
// It assumes that R13 has prime1v, R14 has prime2v, and DI has prime4v.
|
||||
#define mergeRound(acc, val) \
|
||||
IMULQ R14, val \
|
||||
ROLQ $31, val \
|
||||
IMULQ R13, val \
|
||||
XORQ val, acc \
|
||||
IMULQ R13, acc \
|
||||
ADDQ R15, acc
|
||||
ADDQ DI, acc
|
||||
|
||||
// func Sum64(b []byte) uint64
|
||||
TEXT ·Sum64(SB), NOSPLIT, $0-32
|
||||
// Load fixed primes.
|
||||
MOVQ ·prime1v(SB), R13
|
||||
MOVQ ·prime2v(SB), R14
|
||||
MOVQ ·prime4v(SB), R15
|
||||
MOVQ ·prime4v(SB), DI
|
||||
|
||||
// Load slice.
|
||||
MOVQ b_base+0(FP), CX
|
||||
MOVQ b_base+0(FP), SI
|
||||
MOVQ b_len+8(FP), DX
|
||||
LEAQ (CX)(DX*1), BX
|
||||
LEAQ (SI)(DX*1), BX
|
||||
|
||||
// The first loop limit will be len(b)-32.
|
||||
SUBQ $32, BX
|
||||
@ -65,14 +65,14 @@ TEXT ·Sum64(SB), NOSPLIT, $0-32
|
||||
XORQ R11, R11
|
||||
SUBQ R13, R11
|
||||
|
||||
// Loop until CX > BX.
|
||||
// Loop until SI > BX.
|
||||
blockLoop:
|
||||
round(R8)
|
||||
round(R9)
|
||||
round(R10)
|
||||
round(R11)
|
||||
|
||||
CMPQ CX, BX
|
||||
CMPQ SI, BX
|
||||
JLE blockLoop
|
||||
|
||||
MOVQ R8, AX
|
||||
@ -100,16 +100,16 @@ noBlocks:
|
||||
afterBlocks:
|
||||
ADDQ DX, AX
|
||||
|
||||
// Right now BX has len(b)-32, and we want to loop until CX > len(b)-8.
|
||||
// Right now BX has len(b)-32, and we want to loop until SI > len(b)-8.
|
||||
ADDQ $24, BX
|
||||
|
||||
CMPQ CX, BX
|
||||
CMPQ SI, BX
|
||||
JG fourByte
|
||||
|
||||
wordLoop:
|
||||
// Calculate k1.
|
||||
MOVQ (CX), R8
|
||||
ADDQ $8, CX
|
||||
MOVQ (SI), R8
|
||||
ADDQ $8, SI
|
||||
IMULQ R14, R8
|
||||
ROLQ $31, R8
|
||||
IMULQ R13, R8
|
||||
@ -117,18 +117,18 @@ wordLoop:
|
||||
XORQ R8, AX
|
||||
ROLQ $27, AX
|
||||
IMULQ R13, AX
|
||||
ADDQ R15, AX
|
||||
ADDQ DI, AX
|
||||
|
||||
CMPQ CX, BX
|
||||
CMPQ SI, BX
|
||||
JLE wordLoop
|
||||
|
||||
fourByte:
|
||||
ADDQ $4, BX
|
||||
CMPQ CX, BX
|
||||
CMPQ SI, BX
|
||||
JG singles
|
||||
|
||||
MOVL (CX), R8
|
||||
ADDQ $4, CX
|
||||
MOVL (SI), R8
|
||||
ADDQ $4, SI
|
||||
IMULQ R13, R8
|
||||
XORQ R8, AX
|
||||
|
||||
@ -138,19 +138,19 @@ fourByte:
|
||||
|
||||
singles:
|
||||
ADDQ $4, BX
|
||||
CMPQ CX, BX
|
||||
CMPQ SI, BX
|
||||
JGE finalize
|
||||
|
||||
singlesLoop:
|
||||
MOVBQZX (CX), R12
|
||||
ADDQ $1, CX
|
||||
MOVBQZX (SI), R12
|
||||
ADDQ $1, SI
|
||||
IMULQ ·prime5v(SB), R12
|
||||
XORQ R12, AX
|
||||
|
||||
ROLQ $11, AX
|
||||
IMULQ R13, AX
|
||||
|
||||
CMPQ CX, BX
|
||||
CMPQ SI, BX
|
||||
JL singlesLoop
|
||||
|
||||
finalize:
|
||||
@ -179,13 +179,13 @@ TEXT ·writeBlocks(SB), NOSPLIT, $0-40
|
||||
MOVQ ·prime2v(SB), R14
|
||||
|
||||
// Load slice.
|
||||
MOVQ arg1_base+8(FP), CX
|
||||
MOVQ arg1_len+16(FP), DX
|
||||
LEAQ (CX)(DX*1), BX
|
||||
MOVQ b_base+8(FP), SI
|
||||
MOVQ b_len+16(FP), DX
|
||||
LEAQ (SI)(DX*1), BX
|
||||
SUBQ $32, BX
|
||||
|
||||
// Load vN from d.
|
||||
MOVQ arg+0(FP), AX
|
||||
MOVQ d+0(FP), AX
|
||||
MOVQ 0(AX), R8 // v1
|
||||
MOVQ 8(AX), R9 // v2
|
||||
MOVQ 16(AX), R10 // v3
|
||||
@ -199,7 +199,7 @@ blockLoop:
|
||||
round(R10)
|
||||
round(R11)
|
||||
|
||||
CMPQ CX, BX
|
||||
CMPQ SI, BX
|
||||
JLE blockLoop
|
||||
|
||||
// Copy vN back to d.
|
||||
@ -208,8 +208,8 @@ blockLoop:
|
||||
MOVQ R10, 16(AX)
|
||||
MOVQ R11, 24(AX)
|
||||
|
||||
// The number of bytes written is CX minus the old base pointer.
|
||||
SUBQ arg1_base+8(FP), CX
|
||||
MOVQ CX, ret+32(FP)
|
||||
// The number of bytes written is SI minus the old base pointer.
|
||||
SUBQ b_base+8(FP), SI
|
||||
MOVQ SI, ret+32(FP)
|
||||
|
||||
RET
|
||||
|
2
vendor/github.com/modern-go/reflect2/.travis.yml
generated
vendored
2
vendor/github.com/modern-go/reflect2/.travis.yml
generated
vendored
@ -1,7 +1,7 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- 1.x
|
||||
|
||||
before_install:
|
||||
|
8
vendor/github.com/modern-go/reflect2/Gopkg.lock
generated
vendored
8
vendor/github.com/modern-go/reflect2/Gopkg.lock
generated
vendored
@ -1,15 +1,9 @@
|
||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/modern-go/concurrent"
|
||||
packages = ["."]
|
||||
revision = "e0a39a4cb4216ea8db28e22a69f4ec25610d513a"
|
||||
version = "1.0.0"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "daee8a88b3498b61c5640056665b8b9eea062006f5e596bbb6a3ed9119a11ec7"
|
||||
input-imports = []
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
|
4
vendor/github.com/modern-go/reflect2/Gopkg.toml
generated
vendored
4
vendor/github.com/modern-go/reflect2/Gopkg.toml
generated
vendored
@ -26,10 +26,6 @@
|
||||
|
||||
ignored = []
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/modern-go/concurrent"
|
||||
version = "1.0.0"
|
||||
|
||||
[prune]
|
||||
go-tests = true
|
||||
unused-packages = true
|
||||
|
3
vendor/github.com/modern-go/reflect2/go.mod
generated
vendored
Normal file
3
vendor/github.com/modern-go/reflect2/go.mod
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
module github.com/modern-go/reflect2
|
||||
|
||||
go 1.12
|
23
vendor/github.com/modern-go/reflect2/go_above_118.go
generated
vendored
Normal file
23
vendor/github.com/modern-go/reflect2/go_above_118.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
//+build go1.18
|
||||
|
||||
package reflect2
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// m escapes into the return value, but the caller of mapiterinit
|
||||
// doesn't let the return value escape.
|
||||
//go:noescape
|
||||
//go:linkname mapiterinit reflect.mapiterinit
|
||||
func mapiterinit(rtype unsafe.Pointer, m unsafe.Pointer, it *hiter)
|
||||
|
||||
func (type2 *UnsafeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator {
|
||||
var it hiter
|
||||
mapiterinit(type2.rtype, *(*unsafe.Pointer)(obj), &it)
|
||||
return &UnsafeMapIterator{
|
||||
hiter: &it,
|
||||
pKeyRType: type2.pKeyRType,
|
||||
pElemRType: type2.pElemRType,
|
||||
}
|
||||
}
|
8
vendor/github.com/modern-go/reflect2/go_above_17.go
generated
vendored
8
vendor/github.com/modern-go/reflect2/go_above_17.go
generated
vendored
@ -1,8 +0,0 @@
|
||||
//+build go1.7
|
||||
|
||||
package reflect2
|
||||
|
||||
import "unsafe"
|
||||
|
||||
//go:linkname resolveTypeOff reflect.resolveTypeOff
|
||||
func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer
|
3
vendor/github.com/modern-go/reflect2/go_above_19.go
generated
vendored
3
vendor/github.com/modern-go/reflect2/go_above_19.go
generated
vendored
@ -6,6 +6,9 @@ import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
//go:linkname resolveTypeOff reflect.resolveTypeOff
|
||||
func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer
|
||||
|
||||
//go:linkname makemap reflect.makemap
|
||||
func makemap(rtype unsafe.Pointer, cap int) (m unsafe.Pointer)
|
||||
|
||||
|
21
vendor/github.com/modern-go/reflect2/go_below_118.go
generated
vendored
Normal file
21
vendor/github.com/modern-go/reflect2/go_below_118.go
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
//+build !go1.18
|
||||
|
||||
package reflect2
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// m escapes into the return value, but the caller of mapiterinit
|
||||
// doesn't let the return value escape.
|
||||
//go:noescape
|
||||
//go:linkname mapiterinit reflect.mapiterinit
|
||||
func mapiterinit(rtype unsafe.Pointer, m unsafe.Pointer) (val *hiter)
|
||||
|
||||
func (type2 *UnsafeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator {
|
||||
return &UnsafeMapIterator{
|
||||
hiter: mapiterinit(type2.rtype, *(*unsafe.Pointer)(obj)),
|
||||
pKeyRType: type2.pKeyRType,
|
||||
pElemRType: type2.pElemRType,
|
||||
}
|
||||
}
|
9
vendor/github.com/modern-go/reflect2/go_below_17.go
generated
vendored
9
vendor/github.com/modern-go/reflect2/go_below_17.go
generated
vendored
@ -1,9 +0,0 @@
|
||||
//+build !go1.7
|
||||
|
||||
package reflect2
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer {
|
||||
return nil
|
||||
}
|
14
vendor/github.com/modern-go/reflect2/go_below_19.go
generated
vendored
14
vendor/github.com/modern-go/reflect2/go_below_19.go
generated
vendored
@ -1,14 +0,0 @@
|
||||
//+build !go1.9
|
||||
|
||||
package reflect2
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
//go:linkname makemap reflect.makemap
|
||||
func makemap(rtype unsafe.Pointer) (m unsafe.Pointer)
|
||||
|
||||
func makeMapWithSize(rtype unsafe.Pointer, cap int) unsafe.Pointer {
|
||||
return makemap(rtype)
|
||||
}
|
20
vendor/github.com/modern-go/reflect2/reflect2.go
generated
vendored
20
vendor/github.com/modern-go/reflect2/reflect2.go
generated
vendored
@ -1,8 +1,9 @@
|
||||
package reflect2
|
||||
|
||||
import (
|
||||
"github.com/modern-go/concurrent"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"sync"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
@ -130,13 +131,13 @@ var ConfigSafe = Config{UseSafeImplementation: true}.Froze()
|
||||
|
||||
type frozenConfig struct {
|
||||
useSafeImplementation bool
|
||||
cache *concurrent.Map
|
||||
cache *sync.Map
|
||||
}
|
||||
|
||||
func (cfg Config) Froze() *frozenConfig {
|
||||
return &frozenConfig{
|
||||
useSafeImplementation: cfg.UseSafeImplementation,
|
||||
cache: concurrent.NewMap(),
|
||||
cache: new(sync.Map),
|
||||
}
|
||||
}
|
||||
|
||||
@ -288,11 +289,12 @@ func NoEscape(p unsafe.Pointer) unsafe.Pointer {
|
||||
}
|
||||
|
||||
func UnsafeCastString(str string) []byte {
|
||||
bytes := make([]byte, 0)
|
||||
stringHeader := (*reflect.StringHeader)(unsafe.Pointer(&str))
|
||||
sliceHeader := &reflect.SliceHeader{
|
||||
Data: stringHeader.Data,
|
||||
Cap: stringHeader.Len,
|
||||
Len: stringHeader.Len,
|
||||
}
|
||||
return *(*[]byte)(unsafe.Pointer(sliceHeader))
|
||||
sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&bytes))
|
||||
sliceHeader.Data = stringHeader.Data
|
||||
sliceHeader.Cap = stringHeader.Len
|
||||
sliceHeader.Len = stringHeader.Len
|
||||
runtime.KeepAlive(str)
|
||||
return bytes
|
||||
}
|
||||
|
12
vendor/github.com/modern-go/reflect2/test.sh
generated
vendored
12
vendor/github.com/modern-go/reflect2/test.sh
generated
vendored
@ -1,12 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
echo "" > coverage.txt
|
||||
|
||||
for d in $(go list github.com/modern-go/reflect2-tests/... | grep -v vendor); do
|
||||
go test -coverprofile=profile.out -coverpkg=github.com/modern-go/reflect2 $d
|
||||
if [ -f profile.out ]; then
|
||||
cat profile.out >> coverage.txt
|
||||
rm profile.out
|
||||
fi
|
||||
done
|
51
vendor/github.com/modern-go/reflect2/type_map.go
generated
vendored
51
vendor/github.com/modern-go/reflect2/type_map.go
generated
vendored
@ -1,17 +1,13 @@
|
||||
// +build !gccgo
|
||||
|
||||
package reflect2
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// typelinks1 for 1.5 ~ 1.6
|
||||
//go:linkname typelinks1 reflect.typelinks
|
||||
func typelinks1() [][]unsafe.Pointer
|
||||
|
||||
// typelinks2 for 1.7 ~
|
||||
//go:linkname typelinks2 reflect.typelinks
|
||||
func typelinks2() (sections []unsafe.Pointer, offset [][]int32)
|
||||
@ -27,49 +23,10 @@ func discoverTypes() {
|
||||
types = make(map[string]reflect.Type)
|
||||
packages = make(map[string]map[string]reflect.Type)
|
||||
|
||||
ver := runtime.Version()
|
||||
if ver == "go1.5" || strings.HasPrefix(ver, "go1.5.") {
|
||||
loadGo15Types()
|
||||
} else if ver == "go1.6" || strings.HasPrefix(ver, "go1.6.") {
|
||||
loadGo15Types()
|
||||
} else {
|
||||
loadGo17Types()
|
||||
}
|
||||
loadGoTypes()
|
||||
}
|
||||
|
||||
func loadGo15Types() {
|
||||
var obj interface{} = reflect.TypeOf(0)
|
||||
typePtrss := typelinks1()
|
||||
for _, typePtrs := range typePtrss {
|
||||
for _, typePtr := range typePtrs {
|
||||
(*emptyInterface)(unsafe.Pointer(&obj)).word = typePtr
|
||||
typ := obj.(reflect.Type)
|
||||
if typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct {
|
||||
loadedType := typ.Elem()
|
||||
pkgTypes := packages[loadedType.PkgPath()]
|
||||
if pkgTypes == nil {
|
||||
pkgTypes = map[string]reflect.Type{}
|
||||
packages[loadedType.PkgPath()] = pkgTypes
|
||||
}
|
||||
types[loadedType.String()] = loadedType
|
||||
pkgTypes[loadedType.Name()] = loadedType
|
||||
}
|
||||
if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Ptr &&
|
||||
typ.Elem().Elem().Kind() == reflect.Struct {
|
||||
loadedType := typ.Elem().Elem()
|
||||
pkgTypes := packages[loadedType.PkgPath()]
|
||||
if pkgTypes == nil {
|
||||
pkgTypes = map[string]reflect.Type{}
|
||||
packages[loadedType.PkgPath()] = pkgTypes
|
||||
}
|
||||
types[loadedType.String()] = loadedType
|
||||
pkgTypes[loadedType.Name()] = loadedType
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func loadGo17Types() {
|
||||
func loadGoTypes() {
|
||||
var obj interface{} = reflect.TypeOf(0)
|
||||
sections, offset := typelinks2()
|
||||
for i, offs := range offset {
|
||||
|
26
vendor/github.com/modern-go/reflect2/unsafe_link.go
generated
vendored
26
vendor/github.com/modern-go/reflect2/unsafe_link.go
generated
vendored
@ -19,18 +19,12 @@ func typedslicecopy(elemType unsafe.Pointer, dst, src sliceHeader) int
|
||||
|
||||
//go:linkname mapassign reflect.mapassign
|
||||
//go:noescape
|
||||
func mapassign(rtype unsafe.Pointer, m unsafe.Pointer, key, val unsafe.Pointer)
|
||||
func mapassign(rtype unsafe.Pointer, m unsafe.Pointer, key unsafe.Pointer, val unsafe.Pointer)
|
||||
|
||||
//go:linkname mapaccess reflect.mapaccess
|
||||
//go:noescape
|
||||
func mapaccess(rtype unsafe.Pointer, m unsafe.Pointer, key unsafe.Pointer) (val unsafe.Pointer)
|
||||
|
||||
// m escapes into the return value, but the caller of mapiterinit
|
||||
// doesn't let the return value escape.
|
||||
//go:noescape
|
||||
//go:linkname mapiterinit reflect.mapiterinit
|
||||
func mapiterinit(rtype unsafe.Pointer, m unsafe.Pointer) *hiter
|
||||
|
||||
//go:noescape
|
||||
//go:linkname mapiternext reflect.mapiternext
|
||||
func mapiternext(it *hiter)
|
||||
@ -42,9 +36,21 @@ func ifaceE2I(rtype unsafe.Pointer, src interface{}, dst unsafe.Pointer)
|
||||
// If you modify hiter, also change cmd/internal/gc/reflect.go to indicate
|
||||
// the layout of this structure.
|
||||
type hiter struct {
|
||||
key unsafe.Pointer // Must be in first position. Write nil to indicate iteration end (see cmd/internal/gc/range.go).
|
||||
value unsafe.Pointer // Must be in second position (see cmd/internal/gc/range.go).
|
||||
// rest fields are ignored
|
||||
key unsafe.Pointer
|
||||
value unsafe.Pointer
|
||||
t unsafe.Pointer
|
||||
h unsafe.Pointer
|
||||
buckets unsafe.Pointer
|
||||
bptr unsafe.Pointer
|
||||
overflow *[]unsafe.Pointer
|
||||
oldoverflow *[]unsafe.Pointer
|
||||
startBucket uintptr
|
||||
offset uint8
|
||||
wrapped bool
|
||||
B uint8
|
||||
i uint8
|
||||
bucket uintptr
|
||||
checkBucket uintptr
|
||||
}
|
||||
|
||||
// add returns p+x.
|
||||
|
8
vendor/github.com/modern-go/reflect2/unsafe_map.go
generated
vendored
8
vendor/github.com/modern-go/reflect2/unsafe_map.go
generated
vendored
@ -107,14 +107,6 @@ func (type2 *UnsafeMapType) Iterate(obj interface{}) MapIterator {
|
||||
return type2.UnsafeIterate(objEFace.data)
|
||||
}
|
||||
|
||||
func (type2 *UnsafeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator {
|
||||
return &UnsafeMapIterator{
|
||||
hiter: mapiterinit(type2.rtype, *(*unsafe.Pointer)(obj)),
|
||||
pKeyRType: type2.pKeyRType,
|
||||
pElemRType: type2.pElemRType,
|
||||
}
|
||||
}
|
||||
|
||||
type UnsafeMapIterator struct {
|
||||
*hiter
|
||||
pKeyRType unsafe.Pointer
|
||||
|
10
vendor/modules.txt
vendored
10
vendor/modules.txt
vendored
@ -44,7 +44,7 @@ github.com/containerd/cgroups/stats/v1
|
||||
github.com/containerd/containerd/errdefs
|
||||
github.com/containerd/containerd/log
|
||||
github.com/containerd/containerd/platforms
|
||||
# github.com/containerd/stargz-snapshotter/estargz v0.8.0
|
||||
# github.com/containerd/stargz-snapshotter/estargz v0.9.0
|
||||
github.com/containerd/stargz-snapshotter/estargz
|
||||
github.com/containerd/stargz-snapshotter/estargz/errorutil
|
||||
# github.com/containers/common v0.46.0
|
||||
@ -118,7 +118,7 @@ github.com/containers/ocicrypt/keywrap/pkcs7
|
||||
github.com/containers/ocicrypt/spec
|
||||
github.com/containers/ocicrypt/utils
|
||||
github.com/containers/ocicrypt/utils/keyprovider
|
||||
# github.com/containers/storage v1.36.0
|
||||
# github.com/containers/storage v1.37.0
|
||||
github.com/containers/storage
|
||||
github.com/containers/storage/drivers
|
||||
github.com/containers/storage/drivers/aufs
|
||||
@ -236,9 +236,9 @@ github.com/hashicorp/go-multierror
|
||||
github.com/imdario/mergo
|
||||
# github.com/inconshreveable/mousetrap v1.0.0
|
||||
github.com/inconshreveable/mousetrap
|
||||
# github.com/json-iterator/go v1.1.11
|
||||
# github.com/json-iterator/go v1.1.12
|
||||
github.com/json-iterator/go
|
||||
# github.com/klauspost/compress v1.13.5
|
||||
# github.com/klauspost/compress v1.13.6
|
||||
github.com/klauspost/compress
|
||||
github.com/klauspost/compress/flate
|
||||
github.com/klauspost/compress/fse
|
||||
@ -266,7 +266,7 @@ github.com/mistifyio/go-zfs
|
||||
github.com/moby/sys/mountinfo
|
||||
# github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
|
||||
github.com/modern-go/concurrent
|
||||
# github.com/modern-go/reflect2 v1.0.1
|
||||
# github.com/modern-go/reflect2 v1.0.2
|
||||
github.com/modern-go/reflect2
|
||||
# github.com/mtrmac/gpgme v0.1.2
|
||||
github.com/mtrmac/gpgme
|
||||
|
Loading…
Reference in New Issue
Block a user