diff --git a/README.md b/README.md index 7d8fcfb4ffea5..3b3bc58cc8d0b 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ The `tonistiigi/buildkit:standalone` image can be built locally using the Docker #### Supported runc version -During development buildkit is tested with the version of runc that is being used by the containerd repository. Please refer to [runc.md](https://github.com/containerd/containerd/blob/d1e11f17ec7b325f89608dd46c128300b8727d50/RUNC.md) for more information. +During development buildkit is tested with the version of runc that is being used by the containerd repository. Please refer to [runc.md](https://github.com/containerd/containerd/blob/ab67fd50dcb4c5b7ddb0c482c1ee542b0ed87e33/RUNC.md) for more information. #### Contributing diff --git a/cache/blobs/blobs.go b/cache/blobs/blobs.go index d12696a47f218..91d4fb1e16f01 100644 --- a/cache/blobs/blobs.go +++ b/cache/blobs/blobs.go @@ -3,8 +3,8 @@ package blobs import ( gocontext "context" + "github.com/containerd/containerd/diff" "github.com/containerd/containerd/mount" - "github.com/containerd/containerd/rootfs" "github.com/moby/buildkit/cache" "github.com/moby/buildkit/snapshot" "github.com/moby/buildkit/util/flightcontrol" @@ -27,7 +27,7 @@ type blobmapper interface { SetBlob(ctx gocontext.Context, key string, diffID, blob digest.Digest) error } -func GetDiffPairs(ctx context.Context, snapshotter snapshot.Snapshotter, differ rootfs.MountDiffer, ref cache.ImmutableRef) ([]DiffPair, error) { +func GetDiffPairs(ctx context.Context, snapshotter snapshot.Snapshotter, differ diff.Differ, ref cache.ImmutableRef) ([]DiffPair, error) { blobmap, ok := snapshotter.(blobmapper) if !ok { return nil, errors.Errorf("image exporter requires snapshotter with blobs mapping support") @@ -71,7 +71,9 @@ func GetDiffPairs(ctx context.Context, snapshotter snapshot.Snapshotter, differ if err != nil { return nil, err } - descr, err := differ.DiffMounts(ctx, lower, upper, ocispec.MediaTypeImageLayer, ref.ID()) + descr, err := differ.DiffMounts(ctx, lower, upper, + diff.WithMediaType(ocispec.MediaTypeImageLayer), + diff.WithReference(ref.ID())) if err != nil { return nil, err } diff --git a/cache/cacheimport/export.go b/cache/cacheimport/export.go index 01a9cb3936620..d2dadec244401 100644 --- a/cache/cacheimport/export.go +++ b/cache/cacheimport/export.go @@ -6,8 +6,8 @@ import ( "encoding/json" "github.com/containerd/containerd/content" + "github.com/containerd/containerd/diff" "github.com/containerd/containerd/images" - "github.com/containerd/containerd/rootfs" "github.com/docker/distribution/manifest" "github.com/docker/distribution/manifest/schema2" "github.com/moby/buildkit/cache" @@ -38,7 +38,7 @@ type CacheRecord struct { type ExporterOpt struct { Snapshotter snapshot.Snapshotter ContentStore content.Store - Differ rootfs.MountDiffer + Differ diff.Differ SessionManager *session.Manager } diff --git a/cache/cacheimport/import.go b/cache/cacheimport/import.go index d687eacdd4982..8bb2848a434d3 100644 --- a/cache/cacheimport/import.go +++ b/cache/cacheimport/import.go @@ -7,9 +7,11 @@ import ( "time" "github.com/containerd/containerd/content" + "github.com/containerd/containerd/diff" "github.com/containerd/containerd/remotes" "github.com/containerd/containerd/remotes/docker" "github.com/containerd/containerd/rootfs" + cdsnapshot "github.com/containerd/containerd/snapshot" "github.com/moby/buildkit/cache" "github.com/moby/buildkit/cache/blobs" "github.com/moby/buildkit/client" @@ -30,7 +32,7 @@ type ImportOpt struct { SessionManager *session.Manager ContentStore content.Store Snapshotter snapshot.Snapshotter - Applier rootfs.Applier + Applier diff.Differ CacheAccessor cache.Accessor } @@ -77,7 +79,7 @@ func (ci *CacheImporter) pull(ctx context.Context, ref string) (*ocispec.Descrip return nil, nil, err } - if _, err := remotes.FetchHandler(ci.opt.ContentStore, fetcher)(ctx, desc); err != nil { + if _, err := remotes.FetchHandler(ci.opt.ContentStore, fetcher, desc)(ctx, desc); err != nil { return nil, nil, err } @@ -119,7 +121,7 @@ func (ci *CacheImporter) Import(ctx context.Context, ref string) (InstructionCac return nil, errors.Errorf("invalid build cache: %s", ref) } - if _, err := remotes.FetchHandler(ci.opt.ContentStore, fetcher)(ctx, configDesc); err != nil { + if _, err := remotes.FetchHandler(ci.opt.ContentStore, fetcher, configDesc)(ctx, configDesc); err != nil { return nil, err } @@ -238,7 +240,7 @@ func (ii *importInfo) fetch(ctx context.Context, chain []blobs.DiffPair) (cache. if !ok { return errors.Errorf("failed to find %s for fetch", dp.Blobsum) } - if _, err := remotes.FetchHandler(ii.opt.ContentStore, ii.fetcher)(ctx, desc); err != nil { + if _, err := remotes.FetchHandler(ii.opt.ContentStore, ii.fetcher, desc)(ctx, desc); err != nil { return err } return nil @@ -263,10 +265,18 @@ func (ii *importInfo) unpack(ctx context.Context, dpairs []blobs.DiffPair) (stri return "", err } - chainID, err := rootfs.ApplyLayers(ctx, layers, ii.opt.Snapshotter, ii.opt.Applier) - if err != nil { - return "", err + var chain []digest.Digest + for _, layer := range layers { + labels := map[string]string{ + "containerd.io/gc.root": time.Now().UTC().Format(time.RFC3339), + "containerd.io/uncompressed": layer.Diff.Digest.String(), + } + if _, err := rootfs.ApplyLayer(ctx, layer, chain, ii.opt.Snapshotter, ii.opt.Applier, cdsnapshot.WithLabels(labels)); err != nil { + return "", err + } + chain = append(chain, layer.Diff.Digest) } + chainID := identity.ChainID(chain) if err := ii.fillBlobMapping(ctx, layers); err != nil { return "", err diff --git a/cache/manager.go b/cache/manager.go index 3cb93f0ae89f7..59f805075d365 100644 --- a/cache/manager.go +++ b/cache/manager.go @@ -188,7 +188,10 @@ func (cm *cacheManager) New(ctx context.Context, s ImmutableRef, opts ...RefOpti parentID = parent.ID() } - if _, err := cm.Snapshotter.Prepare(ctx, id, parentID); err != nil { + labels := map[string]string{ + "containerd.io/gc.root": time.Now().UTC().Format(time.RFC3339), + } + if _, err := cm.Snapshotter.Prepare(ctx, id, parentID, cdsnapshot.WithLabels(labels)); err != nil { if parent != nil { parent.Release(context.TODO()) } diff --git a/cache/manager_test.go b/cache/manager_test.go index fc1b150d01659..3efee5b01df8e 100644 --- a/cache/manager_test.go +++ b/cache/manager_test.go @@ -24,7 +24,9 @@ func TestManager(t *testing.T) { require.NoError(t, err) defer os.RemoveAll(tmpdir) - cm := getCacheManager(t, tmpdir) + snapshotter, err := naive.NewSnapshotter(filepath.Join(tmpdir, "snapshots")) + require.NoError(t, err) + cm := getCacheManager(t, tmpdir, snapshotter) _, err = cm.Get(ctx, "foobar") require.Error(t, err) @@ -132,7 +134,9 @@ func TestLazyCommit(t *testing.T) { require.NoError(t, err) defer os.RemoveAll(tmpdir) - cm := getCacheManager(t, tmpdir) + snapshotter, err := naive.NewSnapshotter(filepath.Join(tmpdir, "snapshots")) + require.NoError(t, err) + cm := getCacheManager(t, tmpdir, snapshotter) active, err := cm.New(ctx, nil, CachePolicyRetain) require.NoError(t, err) @@ -213,7 +217,8 @@ func TestLazyCommit(t *testing.T) { err = cm.Close() require.NoError(t, err) - cm = getCacheManager(t, tmpdir) + // we can't close snapshotter and open it twice (especially, its internal boltdb store) + cm = getCacheManager(t, tmpdir, snapshotter) snap2, err = cm.Get(ctx, snap.ID()) require.NoError(t, err) @@ -234,7 +239,7 @@ func TestLazyCommit(t *testing.T) { err = cm.Close() require.NoError(t, err) - cm = getCacheManager(t, tmpdir) + cm = getCacheManager(t, tmpdir, snapshotter) snap2, err = cm.Get(ctx, snap.ID()) require.NoError(t, err) @@ -250,10 +255,7 @@ func TestLazyCommit(t *testing.T) { require.Equal(t, errNotFound, errors.Cause(err)) } -func getCacheManager(t *testing.T, tmpdir string) Manager { - snapshotter, err := naive.NewSnapshotter(filepath.Join(tmpdir, "snapshots")) - require.NoError(t, err) - +func getCacheManager(t *testing.T, tmpdir string, snapshotter snapshot.Snapshotter) Manager { md, err := metadata.NewStore(filepath.Join(tmpdir, "metadata.db")) require.NoError(t, err) diff --git a/cache/refs.go b/cache/refs.go index 71ef9048c8352..cd60e04dc1a5c 100644 --- a/cache/refs.go +++ b/cache/refs.go @@ -2,8 +2,10 @@ package cache import ( "sync" + "time" "github.com/containerd/containerd/mount" + cdsnapshot "github.com/containerd/containerd/snapshot" "github.com/moby/buildkit/cache/metadata" "github.com/moby/buildkit/identity" "github.com/moby/buildkit/util/flightcontrol" @@ -134,7 +136,10 @@ func (cr *cacheRecord) Mount(ctx context.Context, readonly bool) ([]mount.Mount, } if cr.viewMount == nil { // TODO: handle this better cr.view = identity.NewID() - m, err := cr.cm.Snapshotter.View(ctx, cr.view, cr.ID()) + labels := map[string]string{ + "containerd.io/gc.root": time.Now().UTC().Format(time.RFC3339), + } + m, err := cr.cm.Snapshotter.View(ctx, cr.view, cr.ID(), cdsnapshot.WithLabels(labels)) if err != nil { cr.view = "" return nil, errors.Wrapf(err, "failed to mount %s", cr.ID()) diff --git a/control/control_default.go b/control/control_default.go index 078bc36038851..cece5f91973e0 100644 --- a/control/control_default.go +++ b/control/control_default.go @@ -6,8 +6,8 @@ import ( "path/filepath" "github.com/containerd/containerd/content" + "github.com/containerd/containerd/diff" "github.com/containerd/containerd/images" - "github.com/containerd/containerd/rootfs" ctdsnapshot "github.com/containerd/containerd/snapshot" "github.com/moby/buildkit/cache" "github.com/moby/buildkit/cache/cacheimport" @@ -31,8 +31,8 @@ import ( type pullDeps struct { Snapshotter ctdsnapshot.Snapshotter ContentStore content.Store - Applier rootfs.Applier - Differ rootfs.MountDiffer + Applier diff.Differ + Differ diff.Differ Images images.Store } diff --git a/control/control_standalone.go b/control/control_standalone.go index 3b3ebf3835082..4dc92113ee470 100644 --- a/control/control_standalone.go +++ b/control/control_standalone.go @@ -8,7 +8,7 @@ import ( "path/filepath" "github.com/containerd/containerd/content/local" - "github.com/containerd/containerd/differ" + "github.com/containerd/containerd/diff/walking" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/namespaces" ctdsnapshot "github.com/containerd/containerd/snapshot" @@ -55,7 +55,7 @@ func newStandalonePullDeps(root string) (*pullDeps, error) { return nil, err } - df, err := differ.NewWalkingDiff(c) + df, err := walking.NewWalkingDiff(c) if err != nil { return nil, err } diff --git a/examples/buildkit0/buildkit.go b/examples/buildkit0/buildkit.go index e15570255759e..2cb31b0fdd464 100644 --- a/examples/buildkit0/buildkit.go +++ b/examples/buildkit0/buildkit.go @@ -17,8 +17,8 @@ type buildOpt struct { func main() { var opt buildOpt flag.StringVar(&opt.target, "target", "containerd", "target (standalone, containerd)") - flag.StringVar(&opt.containerd, "containerd", "v1.0.0-beta.1", "containerd version") - flag.StringVar(&opt.runc, "runc", "v1.0.0-rc4", "runc version") + flag.StringVar(&opt.containerd, "containerd", "ab67fd50dcb4c5b7ddb0c482c1ee542b0ed87e33", "containerd version") + flag.StringVar(&opt.runc, "runc", "74a17296470088de3805e138d3d87c62e613dfc4", "runc version") flag.Parse() bk := buildkit(opt) diff --git a/examples/buildkit1/buildkit.go b/examples/buildkit1/buildkit.go index f4b5493b34377..4e6313a316cfa 100644 --- a/examples/buildkit1/buildkit.go +++ b/examples/buildkit1/buildkit.go @@ -17,8 +17,8 @@ type buildOpt struct { func main() { var opt buildOpt flag.StringVar(&opt.target, "target", "containerd", "target (standalone, containerd)") - flag.StringVar(&opt.containerd, "containerd", "v1.0.0-beta.1", "containerd version") - flag.StringVar(&opt.runc, "runc", "v1.0.0-rc4", "runc version") + flag.StringVar(&opt.containerd, "containerd", "ab67fd50dcb4c5b7ddb0c482c1ee542b0ed87e33", "containerd version") + flag.StringVar(&opt.runc, "runc", "74a17296470088de3805e138d3d87c62e613dfc4", "runc version") flag.Parse() bk := buildkit(opt) diff --git a/examples/buildkit2/buildkit.go b/examples/buildkit2/buildkit.go index 5334fa640e6b6..548883cfe601d 100644 --- a/examples/buildkit2/buildkit.go +++ b/examples/buildkit2/buildkit.go @@ -17,8 +17,8 @@ type buildOpt struct { func main() { var opt buildOpt flag.StringVar(&opt.target, "target", "containerd", "target (standalone, containerd)") - flag.StringVar(&opt.containerd, "containerd", "v1.0.0-beta.1", "containerd version") - flag.StringVar(&opt.runc, "runc", "v1.0.0-rc4", "runc version") + flag.StringVar(&opt.containerd, "containerd", "ab67fd50dcb4c5b7ddb0c482c1ee542b0ed87e33", "containerd version") + flag.StringVar(&opt.runc, "runc", "74a17296470088de3805e138d3d87c62e613dfc4", "runc version") flag.Parse() bk := buildkit(opt) diff --git a/examples/buildkit3/buildkit.go b/examples/buildkit3/buildkit.go index cd2d0b24bbc39..fd1f6b97e1e22 100644 --- a/examples/buildkit3/buildkit.go +++ b/examples/buildkit3/buildkit.go @@ -18,8 +18,8 @@ type buildOpt struct { func main() { var opt buildOpt flag.StringVar(&opt.target, "target", "containerd", "target (standalone, containerd)") - flag.StringVar(&opt.containerd, "containerd", "v1.0.0-beta.1", "containerd version") - flag.StringVar(&opt.runc, "runc", "v1.0.0-rc4", "runc version") + flag.StringVar(&opt.containerd, "containerd", "ab67fd50dcb4c5b7ddb0c482c1ee542b0ed87e33", "containerd version") + flag.StringVar(&opt.runc, "runc", "74a17296470088de3805e138d3d87c62e613dfc4", "runc version") flag.StringVar(&opt.buildkit, "buildkit", "master", "buildkit version") flag.Parse() diff --git a/exporter/containerimage/export.go b/exporter/containerimage/export.go index fd75e7f436595..b8a6fe5f9e0a1 100644 --- a/exporter/containerimage/export.go +++ b/exporter/containerimage/export.go @@ -7,9 +7,9 @@ import ( "time" "github.com/containerd/containerd/content" + "github.com/containerd/containerd/diff" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" - "github.com/containerd/containerd/rootfs" "github.com/docker/distribution" "github.com/docker/distribution/manifest/schema2" "github.com/moby/buildkit/cache" @@ -38,7 +38,7 @@ type Opt struct { SessionManager *session.Manager Snapshotter snapshot.Snapshotter ContentStore content.Store - Differ rootfs.MountDiffer + Differ diff.Differ Images images.Store } diff --git a/hack/dockerfiles/test.Dockerfile b/hack/dockerfiles/test.Dockerfile index d03ff60419365..d0f112c5c9c16 100644 --- a/hack/dockerfiles/test.Dockerfile +++ b/hack/dockerfiles/test.Dockerfile @@ -1,5 +1,5 @@ -ARG RUNC_VERSION=e775f0fba3ea329b8b766451c892c41a3d49594d -ARG CONTAINERD_VERSION=d1e11f17ec7b325f89608dd46c128300b8727d50 +ARG RUNC_VERSION=74a17296470088de3805e138d3d87c62e613dfc4 +ARG CONTAINERD_VERSION=ab67fd50dcb4c5b7ddb0c482c1ee542b0ed87e33 ARG BUILDKIT_TARGET=standalone FROM golang:1.9-alpine AS gobuild-base diff --git a/snapshot/localmounter.go b/snapshot/localmounter.go index 09e9e5a1db92a..083139db2f380 100644 --- a/snapshot/localmounter.go +++ b/snapshot/localmounter.go @@ -48,7 +48,7 @@ func (lm *localMounter) Mount() (string, error) { return "", errors.Wrap(err, "failed to create temp dir") } - if err := mount.MountAll(lm.m, dir); err != nil { + if err := mount.All(lm.m, dir); err != nil { os.RemoveAll(dir) return "", err } diff --git a/source/containerimage/pull.go b/source/containerimage/pull.go index b95887de7b290..ea3e5919e1727 100644 --- a/source/containerimage/pull.go +++ b/source/containerimage/pull.go @@ -8,6 +8,7 @@ import ( "time" "github.com/containerd/containerd/content" + "github.com/containerd/containerd/diff" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" "github.com/containerd/containerd/platforms" @@ -35,7 +36,7 @@ type SourceOpt struct { SessionManager *session.Manager Snapshotter snapshot.Snapshotter ContentStore content.Store - Applier rootfs.Applier + Applier diff.Differ CacheAccessor cache.Accessor } @@ -194,8 +195,8 @@ func (p *puller) Snapshot(ctx context.Context) (cache.ImmutableRef, error) { ongoing.add(desc) return nil, nil }), - remotes.FetchHandler(p.is.ContentStore, fetcher), - images.ChildrenHandler(p.is.ContentStore), + remotes.FetchHandler(p.is.ContentStore, fetcher, p.desc), + images.ChildrenHandler(p.is.ContentStore, platforms.Default()), } if err := images.Dispatch(ctx, images.Handlers(handlers...), p.desc); err != nil { stopProgress() @@ -219,7 +220,18 @@ func (is *imageSource) unpack(ctx context.Context, desc ocispec.Descriptor) (str return "", err } - chainID, err := rootfs.ApplyLayers(ctx, layers, is.Snapshotter, is.Applier) + var chain []digest.Digest + for _, layer := range layers { + labels := map[string]string{ + "containerd.io/gc.root": time.Now().UTC().Format(time.RFC3339), + "containerd.io/uncompressed": layer.Diff.Digest.String(), + } + if _, err := rootfs.ApplyLayer(ctx, layer, chain, is.Snapshotter, is.Applier, snapshot.WithLabels(labels)); err != nil { + return "", err + } + chain = append(chain, layer.Diff.Digest) + } + chainID := identity.ChainID(chain) if err != nil { return "", err } @@ -244,12 +256,12 @@ func (is *imageSource) fillBlobMapping(ctx context.Context, layers []rootfs.Laye } func getLayers(ctx context.Context, provider content.Provider, desc ocispec.Descriptor) ([]rootfs.Layer, error) { - manifest, err := images.Manifest(ctx, provider, desc, platforms.Format(platforms.Default())) + manifest, err := images.Manifest(ctx, provider, desc, platforms.Default()) if err != nil { return nil, errors.WithStack(err) } image := images.Image{Target: desc} - diffIDs, err := image.RootFS(ctx, provider, platforms.Format(platforms.Default())) + diffIDs, err := image.RootFS(ctx, provider, platforms.Default()) if err != nil { return nil, errors.Wrap(err, "failed to resolve rootfs") } diff --git a/util/imageutil/config.go b/util/imageutil/config.go index 36bd63be61fc4..cde9d63e49826 100644 --- a/util/imageutil/config.go +++ b/util/imageutil/config.go @@ -55,13 +55,13 @@ func Config(ctx context.Context, str string, resolver remotes.Resolver, ingester } handlers := []images.Handler{ - remotes.FetchHandler(ingester, fetcher), + remotes.FetchHandler(ingester, fetcher, *desc), childrenConfigHandler(ingester), } if err := images.Dispatch(ctx, images.Handlers(handlers...), *desc); err != nil { return "", nil, err } - config, err := images.Config(ctx, ingester, *desc, platforms.Format(platforms.Default())) + config, err := images.Config(ctx, ingester, *desc, platforms.Default()) if err != nil { return "", nil, err } diff --git a/util/push/push.go b/util/push/push.go index 711036ad837e3..0816497523d5e 100644 --- a/util/push/push.go +++ b/util/push/push.go @@ -69,7 +69,7 @@ func Push(ctx context.Context, sm *session.Manager, cs content.Store, dgst diges m.Lock() manifestStack = append(manifestStack, desc) m.Unlock() - return nil, images.StopHandler + return nil, images.ErrStopHandler default: return nil, nil } diff --git a/vendor.conf b/vendor.conf index e567014fdeee5..4a8fb661c559c 100644 --- a/vendor.conf +++ b/vendor.conf @@ -6,7 +6,8 @@ github.com/davecgh/go-spew v1.1.0 github.com/pmezard/go-difflib v1.0.0 golang.org/x/sys 7ddbeae9ae08c6a06a59597f0c9edbc5ff2444ce -github.com/containerd/containerd d1e11f17ec7b325f89608dd46c128300b8727d50 +github.com/containerd/containerd ab67fd50dcb4c5b7ddb0c482c1ee542b0ed87e33 +github.com/containerd/typeurl f6943554a7e7e88b3c14aad190bf05932da84788 golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c github.com/sirupsen/logrus v1.0.0 google.golang.org/grpc v1.3.0 @@ -46,4 +47,4 @@ github.com/docker/distribution 30578ca32960a4d368bf6db67b0a33c2a1f3dc6f github.com/tonistiigi/units 29de085e9400559bd68aea2e7bc21566e7b8281d github.com/docker/cli 99576756eb3303b7af8102c502f21a912e3c1af6 https://github.com/tonistiigi/docker-cli.git -github.com/docker/docker-credential-helpers d68f9aeca33f5fd3f08eeae5e9d175edf4e731d1 \ No newline at end of file +github.com/docker/docker-credential-helpers d68f9aeca33f5fd3f08eeae5e9d175edf4e731d1 diff --git a/vendor/github.com/containerd/containerd/LICENSE.docs b/vendor/github.com/containerd/containerd/LICENSE.docs index e26cd4fc8ed91..2f244ac814036 100644 --- a/vendor/github.com/containerd/containerd/LICENSE.docs +++ b/vendor/github.com/containerd/containerd/LICENSE.docs @@ -1,4 +1,4 @@ -Attribution-ShareAlike 4.0 International +Attribution 4.0 International ======================================================================= @@ -54,18 +54,16 @@ exhaustive, and do not form part of our licenses. ======================================================================= -Creative Commons Attribution-ShareAlike 4.0 International Public -License +Creative Commons Attribution 4.0 International Public License By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons -Attribution-ShareAlike 4.0 International Public License ("Public -License"). To the extent this Public License may be interpreted as a -contract, You are granted the Licensed Rights in consideration of Your -acceptance of these terms and conditions, and the Licensor grants You -such rights in consideration of benefits the Licensor receives from -making the Licensed Material available under these terms and -conditions. +Attribution 4.0 International Public License ("Public License"). To the +extent this Public License may be interpreted as a contract, You are +granted the Licensed Rights in consideration of Your acceptance of +these terms and conditions, and the Licensor grants You such rights in +consideration of benefits the Licensor receives from making the +Licensed Material available under these terms and conditions. Section 1 -- Definitions. @@ -84,11 +82,7 @@ Section 1 -- Definitions. and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License. - c. BY-SA Compatible License means a license listed at - creativecommons.org/compatiblelicenses, approved by Creative - Commons as essentially the equivalent of this Public License. - - d. Copyright and Similar Rights means copyright and/or similar rights + c. Copyright and Similar Rights means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or @@ -96,33 +90,29 @@ Section 1 -- Definitions. specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. - e. Effective Technological Measures means those measures that, in the + d. Effective Technological Measures means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements. - f. Exceptions and Limitations means fair use, fair dealing, and/or + e. Exceptions and Limitations means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material. - g. License Elements means the license attributes listed in the name - of a Creative Commons Public License. The License Elements of this - Public License are Attribution and ShareAlike. - - h. Licensed Material means the artistic or literary work, database, + f. Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public License. - i. Licensed Rights means the rights granted to You subject to the + g. Licensed Rights means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license. - j. Licensor means the individual(s) or entity(ies) granting rights + h. Licensor means the individual(s) or entity(ies) granting rights under this Public License. - k. Share means to provide material to the public by any means or + i. Share means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material @@ -130,13 +120,13 @@ Section 1 -- Definitions. public may access the material from a place and at a time individually chosen by them. - l. Sui Generis Database Rights means rights other than copyright + j. Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world. - m. You means the individual or entity exercising the Licensed Rights + k. You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning. @@ -182,13 +172,7 @@ Section 2 -- Scope. Licensed Rights under the terms and conditions of this Public License. - b. Additional offer from the Licensor -- Adapted Material. - Every recipient of Adapted Material from You - automatically receives an offer from the Licensor to - exercise the Licensed Rights in the Adapted Material - under the conditions of the Adapter's License You apply. - - c. No downstream restrictions. You may not offer or impose + b. No downstream restrictions. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the @@ -270,24 +254,9 @@ following conditions. information required by Section 3(a)(1)(A) to the extent reasonably practicable. - b. ShareAlike. - - In addition to the conditions in Section 3(a), if You Share - Adapted Material You produce, the following conditions also apply. - - 1. The Adapter's License You apply must be a Creative Commons - license with the same License Elements, this version or - later, or a BY-SA Compatible License. - - 2. You must include the text of, or the URI or hyperlink to, the - Adapter's License You apply. You may satisfy this condition - in any reasonable manner based on the medium, means, and - context in which You Share Adapted Material. - - 3. You may not offer or impose any additional or different terms - or conditions on, or apply any Effective Technological - Measures to, Adapted Material that restrict exercise of the - rights granted under the Adapter's License You apply. + 4. If You Share Adapted Material You produce, the Adapter's + License You apply must not prevent recipients of the Adapted + Material from complying with this Public License. Section 4 -- Sui Generis Database Rights. @@ -302,9 +271,8 @@ apply to Your use of the Licensed Material: b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database - Rights (but not its individual contents) is Adapted Material, + Rights (but not its individual contents) is Adapted Material; and - including for purposes of Section 3(b); and c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database. @@ -407,11 +375,13 @@ Section 8 -- Interpretation. ======================================================================= -Creative Commons is not a party to its public licenses. -Notwithstanding, Creative Commons may elect to apply one of its public -licenses to material it publishes and in those instances will be -considered the "Licensor." Except for the limited purpose of indicating -that material is shared under a Creative Commons public license or as +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at creativecommons.org/policies, Creative Commons does not authorize the use of the trademark "Creative Commons" or any other trademark or logo @@ -419,7 +389,7 @@ of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For -the avoidance of doubt, this paragraph does not form part of the public -licenses. +the avoidance of doubt, this paragraph does not form part of the +public licenses. Creative Commons may be contacted at creativecommons.org. diff --git a/vendor/github.com/containerd/containerd/README.md b/vendor/github.com/containerd/containerd/README.md index b7c352c297e7d..3832446b2f3d3 100644 --- a/vendor/github.com/containerd/containerd/README.md +++ b/vendor/github.com/containerd/containerd/README.md @@ -9,6 +9,8 @@ containerd is an industry-standard container runtime with an emphasis on simplic containerd is designed to be embedded into a larger system, rather than being used directly by developers or end-users. +![architecture](design/architecture.png) + ## Getting Started If you are interested in trying out containerd please see our [Getting Started Guide](docs/getting-started.md). @@ -79,7 +81,7 @@ You can specify options when creating a container about how to modify the specif redis, err := client.NewContainer(context, "redis-master", containerd.WithNewSpec(containerd.WithImageConfig(image))) ``` -## Root Filesystems +### Root Filesystems containerd allows you to use overlay or snapshot filesystems with your containers. It comes with builtin support for overlayfs and btrfs. @@ -148,11 +150,11 @@ defer task.Delete(context) err := task.Start(context) ``` -### Developer Quick-Start +## Developer Quick-Start To build the daemon and `ctr` simple test client, the following build system dependencies are required: -* Go 1.8.x or above (requires 1.8 due to use of golang plugin(s)) +* Go 1.9.x or above * Protoc 3.x compiler and headers (download at the [Google protobuf releases page](https://github.com/google/protobuf/releases)) * Btrfs headers and libraries for your distribution. Note that building the btrfs driver can be disabled via build tag removing this dependency. @@ -194,14 +196,12 @@ For sync communication we have a community slack with a #containerd channel that ### Reporting security issues -__If you are reporting a security issue, please follow the responsible -disclosure guidelines and reach out discreetly at containerd-security@googlegroups.com__. +__If you are reporting a security issue, please reach out discreetly at security@containerd.io__. -## Copyright and license +## Licenses -Copyright ©2016-2017 Docker, Inc. All rights reserved, except as follows. Code -is released under the Apache 2.0 license. The README.md file, and files in the -"docs" folder are licensed under the Creative Commons Attribution 4.0 -International License under the terms and conditions set forth in the file -"LICENSE.docs". You may obtain a duplicate copy of the same license, titled -CC-BY-SA-4.0, at http://creativecommons.org/licenses/by/4.0/. +The containerd codebase is released under the [Apache 2.0 license](LICENSE.code). +The README.md file, and files in the "docs" folder are licensed under the +Creative Commons Attribution 4.0 International License under the terms and +conditions set forth in the file "[LICENSE.docs](LICENSE.docs)". You may obtain a duplicate +copy of the same license, titled CC-BY-4.0, at http://creativecommons.org/licenses/by/4.0/. diff --git a/vendor/github.com/containerd/containerd/api/services/containers/v1/containers.pb.go b/vendor/github.com/containerd/containerd/api/services/containers/v1/containers.pb.go index 74b2bbe0734f9..90d30990317a5 100644 --- a/vendor/github.com/containerd/containerd/api/services/containers/v1/containers.pb.go +++ b/vendor/github.com/containerd/containerd/api/services/containers/v1/containers.pb.go @@ -65,6 +65,8 @@ type Container struct { ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // Labels provides an area to include arbitrary data on containers. // + // The combined size of a key/value pair cannot exceed 4096 bytes. + // // Note that to add a new value to this field, read the existing set and // include the entire result in the update call. Labels map[string]string `protobuf:"bytes,2,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` @@ -94,6 +96,16 @@ type Container struct { CreatedAt time.Time `protobuf:"bytes,8,opt,name=created_at,json=createdAt,stdtime" json:"created_at"` // UpdatedAt is the last time the container was mutated. UpdatedAt time.Time `protobuf:"bytes,9,opt,name=updated_at,json=updatedAt,stdtime" json:"updated_at"` + // Extensions allow clients to provide zero or more blobs that are directly + // associated with the container. One may provide protobuf, json, or other + // encoding formats. The primary use of this is to further decorate the + // container object with fields that may be specific to a client integration. + // + // The key portion of this map should identify a "name" for the extension + // that should be unique against other extensions. When updating extension + // data, one should only update the specified extension using field paths + // to select a specific map key. + Extensions map[string]google_protobuf1.Any `protobuf:"bytes,10,rep,name=extensions" json:"extensions" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value"` } func (m *Container) Reset() { *m = Container{} } @@ -518,6 +530,32 @@ func (m *Container) MarshalTo(dAtA []byte) (int, error) { return 0, err } i += n4 + if len(m.Extensions) > 0 { + for k, _ := range m.Extensions { + dAtA[i] = 0x52 + i++ + v := m.Extensions[k] + msgSize := 0 + if (&v) != nil { + msgSize = (&v).Size() + msgSize += 1 + sovContainers(uint64(msgSize)) + } + mapSize := 1 + len(k) + sovContainers(uint64(len(k))) + msgSize + i = encodeVarintContainers(dAtA, i, uint64(mapSize)) + dAtA[i] = 0xa + i++ + i = encodeVarintContainers(dAtA, i, uint64(len(k))) + i += copy(dAtA[i:], k) + dAtA[i] = 0x12 + i++ + i = encodeVarintContainers(dAtA, i, uint64((&v).Size())) + n5, err := (&v).MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n5 + } + } return i, nil } @@ -546,11 +584,11 @@ func (m *Container_Runtime) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintContainers(dAtA, i, uint64(m.Options.Size())) - n5, err := m.Options.MarshalTo(dAtA[i:]) + n6, err := m.Options.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n5 + i += n6 } return i, nil } @@ -597,11 +635,11 @@ func (m *GetContainerResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintContainers(dAtA, i, uint64(m.Container.Size())) - n6, err := m.Container.MarshalTo(dAtA[i:]) + n7, err := m.Container.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n6 + i += n7 return i, nil } @@ -686,11 +724,11 @@ func (m *CreateContainerRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintContainers(dAtA, i, uint64(m.Container.Size())) - n7, err := m.Container.MarshalTo(dAtA[i:]) + n8, err := m.Container.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n7 + i += n8 return i, nil } @@ -712,11 +750,11 @@ func (m *CreateContainerResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintContainers(dAtA, i, uint64(m.Container.Size())) - n8, err := m.Container.MarshalTo(dAtA[i:]) + n9, err := m.Container.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n8 + i += n9 return i, nil } @@ -738,20 +776,20 @@ func (m *UpdateContainerRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintContainers(dAtA, i, uint64(m.Container.Size())) - n9, err := m.Container.MarshalTo(dAtA[i:]) + n10, err := m.Container.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n9 + i += n10 if m.UpdateMask != nil { dAtA[i] = 0x12 i++ i = encodeVarintContainers(dAtA, i, uint64(m.UpdateMask.Size())) - n10, err := m.UpdateMask.MarshalTo(dAtA[i:]) + n11, err := m.UpdateMask.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n10 + i += n11 } return i, nil } @@ -774,11 +812,11 @@ func (m *UpdateContainerResponse) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintContainers(dAtA, i, uint64(m.Container.Size())) - n11, err := m.Container.MarshalTo(dAtA[i:]) + n12, err := m.Container.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n11 + i += n12 return i, nil } @@ -872,6 +910,15 @@ func (m *Container) Size() (n int) { n += 1 + l + sovContainers(uint64(l)) l = github_com_gogo_protobuf_types.SizeOfStdTime(m.UpdatedAt) n += 1 + l + sovContainers(uint64(l)) + if len(m.Extensions) > 0 { + for k, v := range m.Extensions { + _ = k + _ = v + l = v.Size() + mapEntrySize := 1 + len(k) + sovContainers(uint64(len(k))) + 1 + l + sovContainers(uint64(l)) + n += mapEntrySize + 1 + sovContainers(uint64(mapEntrySize)) + } + } return n } @@ -1004,6 +1051,16 @@ func (this *Container) String() string { mapStringForLabels += fmt.Sprintf("%v: %v,", k, this.Labels[k]) } mapStringForLabels += "}" + keysForExtensions := make([]string, 0, len(this.Extensions)) + for k, _ := range this.Extensions { + keysForExtensions = append(keysForExtensions, k) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForExtensions) + mapStringForExtensions := "map[string]google_protobuf1.Any{" + for _, k := range keysForExtensions { + mapStringForExtensions += fmt.Sprintf("%v: %v,", k, this.Extensions[k]) + } + mapStringForExtensions += "}" s := strings.Join([]string{`&Container{`, `ID:` + fmt.Sprintf("%v", this.ID) + `,`, `Labels:` + mapStringForLabels + `,`, @@ -1014,6 +1071,7 @@ func (this *Container) String() string { `SnapshotKey:` + fmt.Sprintf("%v", this.SnapshotKey) + `,`, `CreatedAt:` + strings.Replace(strings.Replace(this.CreatedAt.String(), "Timestamp", "google_protobuf4.Timestamp", 1), `&`, ``, 1) + `,`, `UpdatedAt:` + strings.Replace(strings.Replace(this.UpdatedAt.String(), "Timestamp", "google_protobuf4.Timestamp", 1), `&`, ``, 1) + `,`, + `Extensions:` + mapStringForExtensions + `,`, `}`, }, "") return s @@ -1515,6 +1573,127 @@ func (m *Container) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Extensions", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContainers + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthContainers + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + var keykey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContainers + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + keykey |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContainers + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthContainers + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey := string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + if m.Extensions == nil { + m.Extensions = make(map[string]google_protobuf1.Any) + } + if iNdEx < postIndex { + var valuekey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContainers + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + valuekey |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContainers + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return ErrInvalidLengthContainers + } + postmsgIndex := iNdEx + mapmsglen + if mapmsglen < 0 { + return ErrInvalidLengthContainers + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue := &google_protobuf1.Any{} + if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + m.Extensions[mapkey] = *mapvalue + } else { + var mapvalue google_protobuf1.Any + m.Extensions[mapkey] = mapvalue + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipContainers(dAtA[iNdEx:]) @@ -2509,51 +2688,54 @@ func init() { } var fileDescriptorContainers = []byte{ - // 730 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xcb, 0x72, 0x12, 0x41, - 0x14, 0xcd, 0xc0, 0x04, 0xc2, 0xc5, 0x85, 0xd5, 0x22, 0x8e, 0x63, 0x15, 0x10, 0x56, 0x2c, 0x74, - 0x30, 0x68, 0x69, 0x1e, 0xab, 0x90, 0x57, 0x59, 0x26, 0x56, 0xaa, 0x4b, 0x37, 0xba, 0x88, 0x0d, - 0x74, 0xc8, 0xc8, 0xbc, 0x9c, 0x6e, 0xa8, 0xa2, 0x5c, 0xe8, 0x27, 0xf8, 0x17, 0xfe, 0x4a, 0x96, - 0x2e, 0x5d, 0xc5, 0x84, 0x2f, 0xb1, 0xba, 0x67, 0x26, 0x43, 0x78, 0x94, 0x10, 0x65, 0x77, 0x2f, - 0x7d, 0xcf, 0xbd, 0x67, 0x4e, 0x9f, 0x3b, 0x0c, 0x1c, 0xb6, 0x4d, 0x7e, 0xd6, 0x6d, 0x18, 0x4d, - 0xd7, 0xae, 0x36, 0x5d, 0x87, 0x13, 0xd3, 0xa1, 0x7e, 0x6b, 0x38, 0x24, 0x9e, 0x59, 0x65, 0xd4, - 0xef, 0x99, 0x4d, 0xca, 0xe2, 0xdf, 0x59, 0xb5, 0xb7, 0x36, 0x94, 0x19, 0x9e, 0xef, 0x72, 0x17, - 0xad, 0xc6, 0x38, 0x23, 0xc2, 0x18, 0x43, 0x55, 0xbd, 0x35, 0x3d, 0xd7, 0x76, 0xdb, 0xae, 0xac, - 0xae, 0x8a, 0x28, 0x00, 0xea, 0x0f, 0xdb, 0xae, 0xdb, 0xb6, 0x68, 0x55, 0x66, 0x8d, 0xee, 0x69, - 0x95, 0x38, 0xfd, 0xf0, 0xe8, 0xd1, 0xe8, 0x11, 0xb5, 0x3d, 0x1e, 0x1d, 0x96, 0x46, 0x0f, 0x4f, - 0x4d, 0x6a, 0xb5, 0x4e, 0x6c, 0xc2, 0x3a, 0x61, 0x45, 0x71, 0xb4, 0x82, 0x9b, 0x36, 0x65, 0x9c, - 0xd8, 0x5e, 0x50, 0x50, 0xbe, 0x50, 0x21, 0xb3, 0x13, 0x51, 0x44, 0x79, 0x48, 0x98, 0x2d, 0x4d, - 0x29, 0x29, 0x95, 0x4c, 0x3d, 0x35, 0xb8, 0x28, 0x26, 0x5e, 0xed, 0xe2, 0x84, 0xd9, 0x42, 0xc7, - 0x90, 0xb2, 0x48, 0x83, 0x5a, 0x4c, 0x4b, 0x94, 0x92, 0x95, 0x6c, 0x6d, 0xdd, 0xf8, 0xeb, 0xa3, - 0x1a, 0xd7, 0x5d, 0x8d, 0x43, 0x09, 0xdd, 0x73, 0xb8, 0xdf, 0xc7, 0x61, 0x1f, 0x94, 0x83, 0x65, - 0xd3, 0x26, 0x6d, 0xaa, 0x25, 0xc5, 0x30, 0x1c, 0x24, 0xe8, 0x0d, 0xa4, 0xfd, 0xae, 0x23, 0x38, - 0x6a, 0x6a, 0x49, 0xa9, 0x64, 0x6b, 0xcf, 0xe7, 0x1a, 0x84, 0x03, 0x2c, 0x8e, 0x9a, 0xa0, 0x0a, - 0xa8, 0xcc, 0xa3, 0x4d, 0x6d, 0x59, 0x36, 0xcb, 0x19, 0x81, 0x1a, 0x46, 0xa4, 0x86, 0xb1, 0xed, - 0xf4, 0xb1, 0xac, 0x40, 0x25, 0xc8, 0x32, 0x87, 0x78, 0xec, 0xcc, 0xe5, 0x9c, 0xfa, 0x5a, 0x4a, - 0xb2, 0x1a, 0xfe, 0x09, 0xad, 0xc2, 0x9d, 0x28, 0x3d, 0xe9, 0xd0, 0xbe, 0x96, 0xbe, 0x59, 0xf2, - 0x9a, 0xf6, 0xd1, 0x0e, 0x40, 0xd3, 0xa7, 0x84, 0xd3, 0xd6, 0x09, 0xe1, 0xda, 0x8a, 0x1c, 0xaa, - 0x8f, 0x0d, 0x7d, 0x1b, 0x5d, 0x41, 0x7d, 0xe5, 0xfc, 0xa2, 0xb8, 0xf4, 0xfd, 0x77, 0x51, 0xc1, - 0x99, 0x10, 0xb7, 0xcd, 0x45, 0x93, 0xae, 0xd7, 0x8a, 0x9a, 0x64, 0xe6, 0x69, 0x12, 0xe2, 0xb6, - 0xb9, 0xbe, 0x01, 0xd9, 0x21, 0xd5, 0xd1, 0x5d, 0x48, 0x0a, 0xca, 0xf2, 0x62, 0xb1, 0x08, 0x85, - 0xfe, 0x3d, 0x62, 0x75, 0xa9, 0x96, 0x08, 0xf4, 0x97, 0xc9, 0x66, 0x62, 0x5d, 0xd1, 0x8f, 0x20, - 0x1d, 0xea, 0x88, 0x10, 0xa8, 0x0e, 0xb1, 0x69, 0x88, 0x93, 0x31, 0x32, 0x20, 0xed, 0x7a, 0xdc, - 0x74, 0x1d, 0x26, 0xa1, 0xd3, 0x54, 0x8d, 0x8a, 0xca, 0x4f, 0xe0, 0xde, 0x01, 0xe5, 0xd7, 0x77, - 0x84, 0xe9, 0xe7, 0x2e, 0x65, 0x7c, 0x9a, 0xd3, 0xca, 0x67, 0x90, 0xbb, 0x59, 0xce, 0x3c, 0xd7, - 0x61, 0x14, 0x1d, 0x43, 0xe6, 0xfa, 0xd6, 0x25, 0x2c, 0x5b, 0x7b, 0x3c, 0x8f, 0x37, 0xea, 0xaa, - 0x90, 0x09, 0xc7, 0x4d, 0xca, 0x6b, 0x70, 0xff, 0xd0, 0x64, 0xf1, 0x28, 0x16, 0x51, 0xd3, 0x20, - 0x7d, 0x6a, 0x5a, 0x9c, 0xfa, 0x4c, 0x53, 0x4a, 0xc9, 0x4a, 0x06, 0x47, 0x69, 0xd9, 0x82, 0xfc, - 0x28, 0x24, 0xa4, 0x87, 0x01, 0xe2, 0xc1, 0x12, 0x76, 0x3b, 0x7e, 0x43, 0x5d, 0xca, 0x9f, 0x20, - 0xbf, 0x23, 0x5d, 0x31, 0x26, 0xde, 0xff, 0x17, 0xa3, 0x03, 0x0f, 0xc6, 0x66, 0x2d, 0x4c, 0xf9, - 0x1f, 0x0a, 0xe4, 0xdf, 0x49, 0xab, 0x2e, 0xfe, 0xc9, 0xd0, 0x16, 0x64, 0x83, 0xb5, 0x90, 0xaf, - 0xc5, 0xd0, 0xb3, 0xe3, 0xfb, 0xb4, 0x2f, 0xde, 0x9c, 0x47, 0x84, 0x75, 0x70, 0xb8, 0x7d, 0x22, - 0x16, 0xb2, 0x8c, 0x11, 0x5d, 0x98, 0x2c, 0x4f, 0x21, 0xbf, 0x4b, 0x2d, 0x3a, 0x41, 0x95, 0x29, - 0xcb, 0x52, 0xbb, 0x54, 0x01, 0x62, 0x33, 0xa2, 0x1e, 0x24, 0x0f, 0x28, 0x47, 0x2f, 0x66, 0xa0, - 0x31, 0x61, 0x25, 0xf5, 0x97, 0x73, 0xe3, 0x42, 0x29, 0xbe, 0x80, 0x2a, 0xd6, 0x02, 0xcd, 0xf2, - 0xaf, 0x30, 0x71, 0xe5, 0xf4, 0x8d, 0x5b, 0x20, 0xc3, 0xe1, 0x5f, 0x21, 0x15, 0x38, 0x17, 0xcd, - 0xd2, 0x64, 0xf2, 0x42, 0xe9, 0x9b, 0xb7, 0x81, 0xc6, 0x04, 0x02, 0x8f, 0xcc, 0x44, 0x60, 0xb2, - 0xef, 0x67, 0x22, 0x30, 0xcd, 0x89, 0x1f, 0x20, 0x15, 0xf8, 0x66, 0x26, 0x02, 0x93, 0x2d, 0xa6, - 0xe7, 0xc7, 0x36, 0x62, 0x4f, 0x7c, 0x68, 0xd4, 0x3f, 0x9e, 0x5f, 0x15, 0x96, 0x7e, 0x5d, 0x15, - 0x96, 0xbe, 0x0d, 0x0a, 0xca, 0xf9, 0xa0, 0xa0, 0xfc, 0x1c, 0x14, 0x94, 0xcb, 0x41, 0x41, 0x79, - 0xbf, 0xff, 0x0f, 0xdf, 0x4e, 0x5b, 0x71, 0xd6, 0x48, 0xc9, 0x89, 0xcf, 0xfe, 0x04, 0x00, 0x00, - 0xff, 0xff, 0x7e, 0x6d, 0xca, 0xbd, 0x8c, 0x09, 0x00, 0x00, + // 776 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xcd, 0x72, 0x12, 0x5b, + 0x10, 0xce, 0x00, 0x81, 0xd0, 0xdc, 0xaa, 0x7b, 0xeb, 0x5c, 0x2e, 0x77, 0x1c, 0xab, 0x80, 0xb0, + 0xa2, 0x2c, 0x1d, 0x0c, 0x5a, 0x9a, 0x1f, 0x37, 0x21, 0x7f, 0x65, 0x99, 0x58, 0xa9, 0x51, 0x37, + 0xba, 0x88, 0x03, 0x74, 0xc8, 0xc8, 0xfc, 0x39, 0xe7, 0x40, 0x49, 0xb9, 0xd0, 0x47, 0x70, 0xe7, + 0x23, 0xf8, 0x2a, 0x59, 0xba, 0x74, 0x15, 0x13, 0x9e, 0xc4, 0x9a, 0x33, 0x33, 0xcc, 0x04, 0x06, + 0x85, 0x68, 0x76, 0xa7, 0x39, 0xfd, 0x7d, 0xfd, 0xf1, 0x75, 0xf7, 0x01, 0xd8, 0xef, 0x68, 0xec, + 0xa4, 0xd7, 0x94, 0x5b, 0x96, 0x51, 0x6b, 0x59, 0x26, 0x53, 0x35, 0x13, 0x9d, 0x76, 0xf4, 0xa8, + 0xda, 0x5a, 0x8d, 0xa2, 0xd3, 0xd7, 0x5a, 0x48, 0xc3, 0xcf, 0x69, 0xad, 0xbf, 0x12, 0x89, 0x64, + 0xdb, 0xb1, 0x98, 0x45, 0x96, 0x43, 0x9c, 0x1c, 0x60, 0xe4, 0x48, 0x56, 0x7f, 0x45, 0xca, 0x77, + 0xac, 0x8e, 0xc5, 0xb3, 0x6b, 0xee, 0xc9, 0x03, 0x4a, 0x37, 0x3a, 0x96, 0xd5, 0xd1, 0xb1, 0xc6, + 0xa3, 0x66, 0xef, 0xb8, 0xa6, 0x9a, 0x03, 0xff, 0xea, 0xe6, 0xf8, 0x15, 0x1a, 0x36, 0x0b, 0x2e, + 0xcb, 0xe3, 0x97, 0xc7, 0x1a, 0xea, 0xed, 0x23, 0x43, 0xa5, 0x5d, 0x3f, 0xa3, 0x34, 0x9e, 0xc1, + 0x34, 0x03, 0x29, 0x53, 0x0d, 0xdb, 0x4b, 0xa8, 0x7c, 0x4e, 0x43, 0x76, 0x2b, 0x90, 0x48, 0x0a, + 0x90, 0xd0, 0xda, 0xa2, 0x50, 0x16, 0xaa, 0xd9, 0x46, 0x7a, 0x78, 0x56, 0x4a, 0x3c, 0xde, 0x56, + 0x12, 0x5a, 0x9b, 0x1c, 0x42, 0x5a, 0x57, 0x9b, 0xa8, 0x53, 0x31, 0x51, 0x4e, 0x56, 0x73, 0xf5, + 0x55, 0xf9, 0x97, 0x5f, 0x55, 0x1e, 0xb1, 0xca, 0xfb, 0x1c, 0xba, 0x63, 0x32, 0x67, 0xa0, 0xf8, + 0x3c, 0x24, 0x0f, 0x8b, 0x9a, 0xa1, 0x76, 0x50, 0x4c, 0xba, 0xc5, 0x14, 0x2f, 0x20, 0x4f, 0x21, + 0xe3, 0xf4, 0x4c, 0x57, 0xa3, 0x98, 0x2a, 0x0b, 0xd5, 0x5c, 0xfd, 0xfe, 0x5c, 0x85, 0x14, 0x0f, + 0xab, 0x04, 0x24, 0xa4, 0x0a, 0x29, 0x6a, 0x63, 0x4b, 0x5c, 0xe4, 0x64, 0x79, 0xd9, 0x73, 0x43, + 0x0e, 0xdc, 0x90, 0x37, 0xcd, 0x81, 0xc2, 0x33, 0x48, 0x19, 0x72, 0xd4, 0x54, 0x6d, 0x7a, 0x62, + 0x31, 0x86, 0x8e, 0x98, 0xe6, 0xaa, 0xa2, 0x1f, 0x91, 0x65, 0xf8, 0x2b, 0x08, 0x8f, 0xba, 0x38, + 0x10, 0x33, 0x97, 0x53, 0x9e, 0xe0, 0x80, 0x6c, 0x01, 0xb4, 0x1c, 0x54, 0x19, 0xb6, 0x8f, 0x54, + 0x26, 0x2e, 0xf1, 0xa2, 0xd2, 0x44, 0xd1, 0xe7, 0x41, 0x0b, 0x1a, 0x4b, 0xa7, 0x67, 0xa5, 0x85, + 0x4f, 0xdf, 0x4b, 0x82, 0x92, 0xf5, 0x71, 0x9b, 0xcc, 0x25, 0xe9, 0xd9, 0xed, 0x80, 0x24, 0x3b, + 0x0f, 0x89, 0x8f, 0xdb, 0x64, 0xa4, 0x09, 0x80, 0xef, 0x18, 0x9a, 0x54, 0xb3, 0x4c, 0x2a, 0x02, + 0x6f, 0xda, 0xa3, 0xb9, 0xbc, 0xdc, 0x19, 0xc1, 0x79, 0xe3, 0x1a, 0x29, 0xb7, 0x8c, 0x12, 0x61, + 0x95, 0xd6, 0x20, 0x17, 0xe9, 0x2c, 0xf9, 0x07, 0x92, 0xae, 0x2d, 0x7c, 0x78, 0x14, 0xf7, 0xe8, + 0xf6, 0xb8, 0xaf, 0xea, 0x3d, 0x14, 0x13, 0x5e, 0x8f, 0x79, 0xb0, 0x9e, 0x58, 0x15, 0xa4, 0x03, + 0xc8, 0xf8, 0xbd, 0x22, 0x04, 0x52, 0xa6, 0x6a, 0xa0, 0x8f, 0xe3, 0x67, 0x22, 0x43, 0xc6, 0xb2, + 0x19, 0x97, 0x9e, 0xf8, 0x49, 0xe7, 0x82, 0x24, 0xe9, 0x19, 0xfc, 0x3d, 0x26, 0x37, 0x46, 0xcd, + 0xad, 0xa8, 0x9a, 0x69, 0x94, 0xa1, 0xc6, 0xca, 0x1d, 0xf8, 0x77, 0x0f, 0xd9, 0xc8, 0x10, 0x05, + 0xdf, 0xf6, 0x90, 0xb2, 0x69, 0x2b, 0x52, 0x39, 0x81, 0xfc, 0xe5, 0x74, 0x6a, 0x5b, 0x26, 0x45, + 0x72, 0x08, 0xd9, 0x91, 0xc5, 0x1c, 0x96, 0xab, 0xdf, 0x9e, 0xa7, 0x11, 0xbe, 0xf1, 0x21, 0x49, + 0x65, 0x05, 0xfe, 0xdb, 0xd7, 0x68, 0x58, 0x8a, 0x06, 0xd2, 0x44, 0xc8, 0x1c, 0x6b, 0x3a, 0x43, + 0x87, 0x8a, 0x42, 0x39, 0x59, 0xcd, 0x2a, 0x41, 0x58, 0xd1, 0xa1, 0x30, 0x0e, 0xf1, 0xe5, 0x29, + 0x00, 0x61, 0x61, 0x0e, 0xbb, 0x9a, 0xbe, 0x08, 0x4b, 0xe5, 0x0d, 0x14, 0xb6, 0xf8, 0x38, 0x4f, + 0x98, 0xf7, 0xe7, 0xcd, 0xe8, 0xc2, 0xff, 0x13, 0xb5, 0xae, 0xcd, 0xf9, 0x2f, 0x02, 0x14, 0x5e, + 0xf0, 0x1d, 0xbb, 0xfe, 0x6f, 0x46, 0x36, 0x20, 0xe7, 0xed, 0x33, 0x7f, 0xcf, 0xfd, 0xa9, 0x9d, + 0x7c, 0x08, 0x76, 0xdd, 0x27, 0xff, 0x40, 0xa5, 0x5d, 0xc5, 0x7f, 0x36, 0xdc, 0xb3, 0x6b, 0xcb, + 0x84, 0xd0, 0x6b, 0xb3, 0xe5, 0x2e, 0x14, 0xb6, 0x51, 0xc7, 0x18, 0x57, 0xa6, 0x2c, 0x4b, 0xfd, + 0x3c, 0x05, 0x10, 0x0e, 0x23, 0xe9, 0x43, 0x72, 0x0f, 0x19, 0x79, 0x30, 0x83, 0x8c, 0x98, 0x95, + 0x94, 0x1e, 0xce, 0x8d, 0xf3, 0xad, 0x78, 0x0f, 0x29, 0x77, 0x2d, 0xc8, 0x2c, 0x3f, 0x67, 0xb1, + 0x2b, 0x27, 0xad, 0x5d, 0x01, 0xe9, 0x17, 0xff, 0x00, 0x69, 0x6f, 0x72, 0xc9, 0x2c, 0x24, 0xf1, + 0x0b, 0x25, 0xad, 0x5f, 0x05, 0x1a, 0x0a, 0xf0, 0x66, 0x64, 0x26, 0x01, 0xf1, 0x73, 0x3f, 0x93, + 0x80, 0x69, 0x93, 0xf8, 0x0a, 0xd2, 0xde, 0xdc, 0xcc, 0x24, 0x20, 0x7e, 0xc4, 0xa4, 0xc2, 0xc4, + 0x46, 0xec, 0xb8, 0xff, 0x90, 0x1a, 0xaf, 0x4f, 0x2f, 0x8a, 0x0b, 0xdf, 0x2e, 0x8a, 0x0b, 0x1f, + 0x87, 0x45, 0xe1, 0x74, 0x58, 0x14, 0xbe, 0x0e, 0x8b, 0xc2, 0xf9, 0xb0, 0x28, 0xbc, 0xdc, 0xfd, + 0x8d, 0x3f, 0x7d, 0x1b, 0x61, 0xd4, 0x4c, 0xf3, 0x8a, 0xf7, 0x7e, 0x04, 0x00, 0x00, 0xff, 0xff, + 0x17, 0x73, 0xba, 0x43, 0x45, 0x0a, 0x00, 0x00, } diff --git a/vendor/github.com/containerd/containerd/api/services/containers/v1/containers.proto b/vendor/github.com/containerd/containerd/api/services/containers/v1/containers.proto index 572ecde1262a3..0a2311c4c47e9 100644 --- a/vendor/github.com/containerd/containerd/api/services/containers/v1/containers.proto +++ b/vendor/github.com/containerd/containerd/api/services/containers/v1/containers.proto @@ -42,6 +42,8 @@ message Container { // Labels provides an area to include arbitrary data on containers. // + // The combined size of a key/value pair cannot exceed 4096 bytes. + // // Note that to add a new value to this field, read the existing set and // include the entire result in the update call. map labels = 2; @@ -84,6 +86,17 @@ message Container { // UpdatedAt is the last time the container was mutated. google.protobuf.Timestamp updated_at = 9 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; + + // Extensions allow clients to provide zero or more blobs that are directly + // associated with the container. One may provide protobuf, json, or other + // encoding formats. The primary use of this is to further decorate the + // container object with fields that may be specific to a client integration. + // + // The key portion of this map should identify a "name" for the extension + // that should be unique against other extensions. When updating extension + // data, one should only update the specified extension using field paths + // to select a specific map key. + map extensions = 10 [(gogoproto.nullable) = false]; } message GetContainerRequest { diff --git a/vendor/github.com/containerd/containerd/api/services/content/v1/content.pb.go b/vendor/github.com/containerd/containerd/api/services/content/v1/content.pb.go index 40cfc66d16755..c9b76b5a779bc 100644 --- a/vendor/github.com/containerd/containerd/api/services/content/v1/content.pb.go +++ b/vendor/github.com/containerd/containerd/api/services/content/v1/content.pb.go @@ -115,7 +115,9 @@ type Info struct { CreatedAt time.Time `protobuf:"bytes,3,opt,name=created_at,json=createdAt,stdtime" json:"created_at"` // UpdatedAt provides the time the info was last updated. UpdatedAt time.Time `protobuf:"bytes,4,opt,name=updated_at,json=updatedAt,stdtime" json:"updated_at"` - // Labels are arbitrary data on content. + // Labels are arbitrary data on snapshots. + // + // The combined size of a key/value pair cannot exceed 4096 bytes. Labels map[string]string `protobuf:"bytes,5,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } @@ -321,7 +323,9 @@ type WriteContentRequest struct { // If this is empty and the message is not a commit, a response will be // returned with the current write state. Data []byte `protobuf:"bytes,6,opt,name=data,proto3" json:"data,omitempty"` - // Labels are arbitrary data to set on commit. + // Labels are arbitrary data on snapshots. + // + // The combined size of a key/value pair cannot exceed 4096 bytes. Labels map[string]string `protobuf:"bytes,7,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } diff --git a/vendor/github.com/containerd/containerd/api/services/content/v1/content.proto b/vendor/github.com/containerd/containerd/api/services/content/v1/content.proto index 9538408bd59d4..a0a41c447bea1 100644 --- a/vendor/github.com/containerd/containerd/api/services/content/v1/content.proto +++ b/vendor/github.com/containerd/containerd/api/services/content/v1/content.proto @@ -87,7 +87,9 @@ message Info { // UpdatedAt provides the time the info was last updated. google.protobuf.Timestamp updated_at = 4 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; - // Labels are arbitrary data on content. + // Labels are arbitrary data on snapshots. + // + // The combined size of a key/value pair cannot exceed 4096 bytes. map labels = 5; } @@ -270,7 +272,9 @@ message WriteContentRequest { // returned with the current write state. bytes data = 6; - // Labels are arbitrary data to set on commit. + // Labels are arbitrary data on snapshots. + // + // The combined size of a key/value pair cannot exceed 4096 bytes. map labels = 7; } diff --git a/vendor/github.com/containerd/containerd/api/services/diff/v1/diff.pb.go b/vendor/github.com/containerd/containerd/api/services/diff/v1/diff.pb.go index 764c5b17d55c4..b19a377317223 100644 --- a/vendor/github.com/containerd/containerd/api/services/diff/v1/diff.pb.go +++ b/vendor/github.com/containerd/containerd/api/services/diff/v1/diff.pb.go @@ -30,6 +30,7 @@ import ( import strings "strings" import reflect "reflect" +import github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys" import io "io" @@ -78,6 +79,9 @@ type DiffRequest struct { // Ref identifies the pre-commit content store object. This // reference can be used to get the status from the content store. Ref string `protobuf:"bytes,4,opt,name=ref,proto3" json:"ref,omitempty"` + // Labels are the labels to apply to the generated content + // on content store commit. + Labels map[string]string `protobuf:"bytes,5,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (m *DiffRequest) Reset() { *m = DiffRequest{} } @@ -334,6 +338,23 @@ func (m *DiffRequest) MarshalTo(dAtA []byte) (int, error) { i = encodeVarintDiff(dAtA, i, uint64(len(m.Ref))) i += copy(dAtA[i:], m.Ref) } + if len(m.Labels) > 0 { + for k, _ := range m.Labels { + dAtA[i] = 0x2a + i++ + v := m.Labels[k] + mapSize := 1 + len(k) + sovDiff(uint64(len(k))) + 1 + len(v) + sovDiff(uint64(len(v))) + i = encodeVarintDiff(dAtA, i, uint64(mapSize)) + dAtA[i] = 0xa + i++ + i = encodeVarintDiff(dAtA, i, uint64(len(k))) + i += copy(dAtA[i:], k) + dAtA[i] = 0x12 + i++ + i = encodeVarintDiff(dAtA, i, uint64(len(v))) + i += copy(dAtA[i:], v) + } + } return i, nil } @@ -441,6 +462,14 @@ func (m *DiffRequest) Size() (n int) { if l > 0 { n += 1 + l + sovDiff(uint64(l)) } + if len(m.Labels) > 0 { + for k, v := range m.Labels { + _ = k + _ = v + mapEntrySize := 1 + len(k) + sovDiff(uint64(len(k))) + 1 + len(v) + sovDiff(uint64(len(v))) + n += mapEntrySize + 1 + sovDiff(uint64(mapEntrySize)) + } + } return n } @@ -492,11 +521,22 @@ func (this *DiffRequest) String() string { if this == nil { return "nil" } + keysForLabels := make([]string, 0, len(this.Labels)) + for k, _ := range this.Labels { + keysForLabels = append(keysForLabels, k) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForLabels) + mapStringForLabels := "map[string]string{" + for _, k := range keysForLabels { + mapStringForLabels += fmt.Sprintf("%v: %v,", k, this.Labels[k]) + } + mapStringForLabels += "}" s := strings.Join([]string{`&DiffRequest{`, `Left:` + strings.Replace(fmt.Sprintf("%v", this.Left), "Mount", "containerd_types.Mount", 1) + `,`, `Right:` + strings.Replace(fmt.Sprintf("%v", this.Right), "Mount", "containerd_types.Mount", 1) + `,`, `MediaType:` + fmt.Sprintf("%v", this.MediaType) + `,`, `Ref:` + fmt.Sprintf("%v", this.Ref) + `,`, + `Labels:` + mapStringForLabels + `,`, `}`, }, "") return s @@ -865,6 +905,122 @@ func (m *DiffRequest) Unmarshal(dAtA []byte) error { } m.Ref = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDiff + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthDiff + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + var keykey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDiff + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + keykey |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDiff + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthDiff + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey := string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + if m.Labels == nil { + m.Labels = make(map[string]string) + } + if iNdEx < postIndex { + var valuekey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDiff + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + valuekey |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + var stringLenmapvalue uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDiff + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapvalue |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapvalue := int(stringLenmapvalue) + if intStringLenmapvalue < 0 { + return ErrInvalidLengthDiff + } + postStringIndexmapvalue := iNdEx + intStringLenmapvalue + if postStringIndexmapvalue > l { + return io.ErrUnexpectedEOF + } + mapvalue := string(dAtA[iNdEx:postStringIndexmapvalue]) + iNdEx = postStringIndexmapvalue + m.Labels[mapkey] = mapvalue + } else { + var mapvalue string + m.Labels[mapkey] = mapvalue + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipDiff(dAtA[iNdEx:]) @@ -1079,31 +1235,34 @@ func init() { } var fileDescriptorDiff = []byte{ - // 401 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x93, 0x41, 0x8b, 0xda, 0x40, - 0x14, 0xc7, 0x9d, 0x26, 0x5a, 0x1c, 0x2d, 0x94, 0xa1, 0xd0, 0x90, 0xb6, 0x41, 0x72, 0x8a, 0x2d, - 0x9d, 0x54, 0x0b, 0x1e, 0xea, 0xc5, 0x16, 0xa1, 0xa7, 0x5e, 0x82, 0xa7, 0x16, 0x5a, 0x62, 0x32, - 0x89, 0x03, 0x9a, 0x19, 0x33, 0xa3, 0xe0, 0xad, 0x9f, 0x63, 0xbf, 0xce, 0x5e, 0x3c, 0xee, 0x71, - 0x8f, 0x6b, 0x3e, 0xc9, 0x92, 0x49, 0xb2, 0x1b, 0x58, 0x70, 0xb3, 0x7b, 0x9a, 0xc7, 0xbc, 0xdf, - 0xff, 0xbd, 0xff, 0xbc, 0xbc, 0xc0, 0x59, 0x4c, 0xe5, 0x6a, 0xb7, 0xc4, 0x01, 0xdb, 0xb8, 0x01, - 0x4b, 0xa4, 0x4f, 0x13, 0x92, 0x86, 0xf5, 0xd0, 0xe7, 0xd4, 0x15, 0x24, 0xdd, 0xd3, 0x80, 0x08, - 0x37, 0xa4, 0x51, 0xe4, 0xee, 0x47, 0xea, 0xc4, 0x3c, 0x65, 0x92, 0xa1, 0x77, 0xf7, 0x2c, 0xae, - 0x38, 0xac, 0xf2, 0xfb, 0x91, 0xf9, 0x26, 0x66, 0x31, 0x53, 0x9c, 0x9b, 0x47, 0x85, 0xc4, 0x9c, - 0x34, 0x6a, 0x2a, 0x0f, 0x9c, 0x08, 0x77, 0xc3, 0x76, 0x89, 0x2c, 0x75, 0xd3, 0x27, 0xe8, 0x42, - 0x22, 0x82, 0x94, 0x72, 0xc9, 0xd2, 0x42, 0x6c, 0x6f, 0x61, 0xff, 0x3b, 0xe7, 0xeb, 0x83, 0x47, - 0xb6, 0x3b, 0x22, 0x24, 0xfa, 0x02, 0xf5, 0xdc, 0xa5, 0x01, 0x06, 0xc0, 0xe9, 0x8d, 0xdf, 0xe3, - 0xda, 0x33, 0x54, 0x05, 0x3c, 0xbf, 0xab, 0xe0, 0x29, 0x12, 0xb9, 0xb0, 0xa3, 0xdc, 0x08, 0xe3, - 0xc5, 0x40, 0x73, 0x7a, 0xe3, 0xb7, 0x0f, 0x35, 0xbf, 0xf2, 0xbc, 0x57, 0x62, 0xf6, 0x4f, 0xf8, - 0xaa, 0x6c, 0x29, 0x38, 0x4b, 0x04, 0x41, 0x13, 0xf8, 0xd2, 0xe7, 0x7c, 0x4d, 0x49, 0xd8, 0xa8, - 0x6d, 0x05, 0xdb, 0x17, 0x00, 0xf6, 0xe6, 0x34, 0x8a, 0x2a, 0xef, 0x9f, 0xa0, 0xbe, 0x26, 0x91, - 0x34, 0xc0, 0x79, 0x1f, 0x0a, 0x42, 0x9f, 0x61, 0x3b, 0xa5, 0xf1, 0x4a, 0x3e, 0xe6, 0xba, 0xa0, - 0xd0, 0x07, 0x08, 0x37, 0x24, 0xa4, 0xfe, 0xbf, 0x3c, 0x67, 0x68, 0x03, 0xe0, 0x74, 0xbd, 0xae, - 0xba, 0x59, 0x1c, 0x38, 0x41, 0xaf, 0xa1, 0x96, 0x92, 0xc8, 0xd0, 0xd5, 0x7d, 0x1e, 0xda, 0x33, - 0xd8, 0x2f, 0xbc, 0x95, 0x8f, 0xac, 0x06, 0xab, 0x35, 0x1d, 0xec, 0xf8, 0x12, 0x40, 0x3d, 0x2f, - 0x81, 0xfe, 0xc2, 0xb6, 0x1a, 0x18, 0x1a, 0xe2, 0x33, 0x5b, 0x85, 0xeb, 0xdf, 0xd1, 0xfc, 0xd8, - 0x04, 0x2d, 0xad, 0xfd, 0x29, 0xfb, 0x38, 0x67, 0x35, 0xb5, 0x49, 0x9b, 0xc3, 0x06, 0x64, 0x51, - 0xfc, 0xc7, 0xe2, 0x78, 0xb2, 0x5a, 0xd7, 0x27, 0xab, 0xf5, 0x3f, 0xb3, 0xc0, 0x31, 0xb3, 0xc0, - 0x55, 0x66, 0x81, 0x9b, 0xcc, 0x02, 0xbf, 0xbf, 0x3d, 0xeb, 0x27, 0x9b, 0xe6, 0xe7, 0xb2, 0xa3, - 0xb6, 0xf7, 0xeb, 0x6d, 0x00, 0x00, 0x00, 0xff, 0xff, 0x6e, 0x16, 0x1d, 0x04, 0xa9, 0x03, 0x00, - 0x00, + // 454 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0x4f, 0x6f, 0xd3, 0x30, + 0x14, 0x9f, 0xfb, 0x0f, 0xf5, 0x75, 0x48, 0xc8, 0x9a, 0x44, 0x14, 0x20, 0xaa, 0x7a, 0xea, 0x40, + 0x38, 0xac, 0xa0, 0x09, 0xb6, 0xcb, 0x40, 0x43, 0x5c, 0xc6, 0x25, 0xda, 0x09, 0x24, 0x50, 0xda, + 0xbc, 0x74, 0x16, 0x69, 0xec, 0xd9, 0x6e, 0xa5, 0xdc, 0xf8, 0x2e, 0x7c, 0x14, 0x2e, 0x3b, 0x72, + 0xe4, 0x48, 0xfb, 0x49, 0x90, 0x9d, 0x14, 0x22, 0x21, 0x95, 0xc0, 0x29, 0x2f, 0xcf, 0xbf, 0x7f, + 0xf6, 0xb3, 0xe1, 0x6c, 0xce, 0xcd, 0xd5, 0x72, 0xca, 0x66, 0x62, 0x11, 0xce, 0x44, 0x6e, 0x62, + 0x9e, 0xa3, 0x4a, 0xea, 0x65, 0x2c, 0x79, 0xa8, 0x51, 0xad, 0xf8, 0x0c, 0x75, 0x98, 0xf0, 0x34, + 0x0d, 0x57, 0x47, 0xee, 0xcb, 0xa4, 0x12, 0x46, 0xd0, 0x7b, 0xbf, 0xb1, 0x6c, 0x8b, 0x63, 0x6e, + 0x7d, 0x75, 0xe4, 0x1f, 0xcc, 0xc5, 0x5c, 0x38, 0x5c, 0x68, 0xab, 0x92, 0xe2, 0x1f, 0x37, 0x32, + 0x35, 0x85, 0x44, 0x1d, 0x2e, 0xc4, 0x32, 0x37, 0x15, 0xef, 0xf4, 0x1f, 0x78, 0x09, 0xea, 0x99, + 0xe2, 0xd2, 0x08, 0x55, 0x92, 0x47, 0xd7, 0xb0, 0xff, 0x52, 0xca, 0xac, 0x88, 0xf0, 0x7a, 0x89, + 0xda, 0xd0, 0x27, 0xd0, 0xb1, 0x29, 0x3d, 0x32, 0x24, 0xe3, 0xc1, 0xe4, 0x3e, 0xab, 0x6d, 0xc3, + 0x29, 0xb0, 0xf3, 0x5f, 0x0a, 0x91, 0x43, 0xd2, 0x10, 0x7a, 0x2e, 0x8d, 0xf6, 0x5a, 0xc3, 0xf6, + 0x78, 0x30, 0xb9, 0xfb, 0x27, 0xe7, 0xad, 0x5d, 0x8f, 0x2a, 0xd8, 0xe8, 0x0d, 0xdc, 0xae, 0x2c, + 0xb5, 0x14, 0xb9, 0x46, 0x7a, 0x0c, 0xb7, 0x62, 0x29, 0x33, 0x8e, 0x49, 0x23, 0xdb, 0x2d, 0x78, + 0xf4, 0xa5, 0x05, 0x83, 0x73, 0x9e, 0xa6, 0xdb, 0xec, 0x8f, 0xa0, 0x93, 0x61, 0x6a, 0x3c, 0xb2, + 0x3b, 0x87, 0x03, 0xd1, 0xc7, 0xd0, 0x55, 0x7c, 0x7e, 0x65, 0xfe, 0x96, 0xba, 0x44, 0xd1, 0x07, + 0x00, 0x0b, 0x4c, 0x78, 0xfc, 0xd1, 0xae, 0x79, 0xed, 0x21, 0x19, 0xf7, 0xa3, 0xbe, 0xeb, 0x5c, + 0x16, 0x12, 0xe9, 0x1d, 0x68, 0x2b, 0x4c, 0xbd, 0x8e, 0xeb, 0xdb, 0x92, 0x5e, 0x40, 0x2f, 0x8b, + 0xa7, 0x98, 0x69, 0xaf, 0xeb, 0x0c, 0x9e, 0xb1, 0x1d, 0x37, 0x82, 0xd5, 0xb6, 0xc1, 0x2e, 0x1c, + 0xed, 0x75, 0x6e, 0x54, 0x11, 0x55, 0x1a, 0xfe, 0x0b, 0x18, 0xd4, 0xda, 0xd6, 0xee, 0x13, 0x16, + 0xee, 0xb4, 0xfa, 0x91, 0x2d, 0xe9, 0x01, 0x74, 0x57, 0x71, 0xb6, 0x44, 0xaf, 0xe5, 0x7a, 0xe5, + 0xcf, 0x49, 0xeb, 0x39, 0x19, 0x9d, 0xc1, 0x7e, 0xa9, 0x5e, 0x9d, 0xf6, 0x76, 0xc2, 0xed, 0xa6, + 0x13, 0x9e, 0x7c, 0x25, 0xd0, 0xb1, 0x12, 0xf4, 0x03, 0x74, 0xdd, 0xe4, 0xe8, 0xe1, 0xce, 0xcd, + 0xd4, 0x2f, 0x94, 0xff, 0xb0, 0x09, 0xb4, 0x8a, 0xf6, 0xbe, 0xf2, 0x19, 0x37, 0x3d, 0x2b, 0xff, + 0xb0, 0x01, 0xb2, 0x14, 0x7f, 0x75, 0x79, 0xb3, 0x0e, 0xf6, 0xbe, 0xaf, 0x83, 0xbd, 0xcf, 0x9b, + 0x80, 0xdc, 0x6c, 0x02, 0xf2, 0x6d, 0x13, 0x90, 0x1f, 0x9b, 0x80, 0xbc, 0x3b, 0xf9, 0xaf, 0xd7, + 0x7e, 0x6a, 0xbf, 0xd3, 0x9e, 0x7b, 0x46, 0x4f, 0x7f, 0x06, 0x00, 0x00, 0xff, 0xff, 0xd6, 0x01, + 0x51, 0xf0, 0x32, 0x04, 0x00, 0x00, } diff --git a/vendor/github.com/containerd/containerd/api/services/diff/v1/diff.proto b/vendor/github.com/containerd/containerd/api/services/diff/v1/diff.proto index f42b5ed42184a..d1d2a824493a3 100644 --- a/vendor/github.com/containerd/containerd/api/services/diff/v1/diff.proto +++ b/vendor/github.com/containerd/containerd/api/services/diff/v1/diff.proto @@ -50,6 +50,10 @@ message DiffRequest { // Ref identifies the pre-commit content store object. This // reference can be used to get the status from the content store. string ref = 4; + + // Labels are the labels to apply to the generated content + // on content store commit. + map labels = 5; } message DiffResponse { diff --git a/vendor/github.com/containerd/containerd/api/services/events/v1/container.pb.go b/vendor/github.com/containerd/containerd/api/services/events/v1/container.pb.go index 2533b1d43e037..420aba0369c62 100644 --- a/vendor/github.com/containerd/containerd/api/services/events/v1/container.pb.go +++ b/vendor/github.com/containerd/containerd/api/services/events/v1/container.pb.go @@ -53,7 +53,7 @@ import _ "github.com/gogo/protobuf/gogoproto" import google_protobuf1 "github.com/gogo/protobuf/types" import _ "github.com/containerd/containerd/protobuf/plugin" -import github_com_containerd_containerd_typeurl "github.com/containerd/containerd/typeurl" +import github_com_containerd_typeurl "github.com/containerd/typeurl" import strings "strings" import reflect "reflect" @@ -158,7 +158,7 @@ func (m *ContainerCreate_Runtime) Field(fieldpath []string) (string, bool) { case "name": return string(m.Name), len(m.Name) > 0 case "options": - decoded, err := github_com_containerd_containerd_typeurl.UnmarshalAny(m.Options) + decoded, err := github_com_containerd_typeurl.UnmarshalAny(m.Options) if err != nil { return "", false } diff --git a/vendor/github.com/containerd/containerd/api/services/events/v1/events.pb.go b/vendor/github.com/containerd/containerd/api/services/events/v1/events.pb.go index 1d068d07b2290..e89406440b283 100644 --- a/vendor/github.com/containerd/containerd/api/services/events/v1/events.pb.go +++ b/vendor/github.com/containerd/containerd/api/services/events/v1/events.pb.go @@ -15,7 +15,7 @@ import _ "github.com/gogo/protobuf/types" import time "time" -import github_com_containerd_containerd_typeurl "github.com/containerd/containerd/typeurl" +import github_com_containerd_typeurl "github.com/containerd/typeurl" import ( context "golang.org/x/net/context" @@ -92,7 +92,7 @@ func (m *Envelope) Field(fieldpath []string) (string, bool) { case "topic": return string(m.Topic), len(m.Topic) > 0 case "event": - decoded, err := github_com_containerd_containerd_typeurl.UnmarshalAny(m.Event) + decoded, err := github_com_containerd_typeurl.UnmarshalAny(m.Event) if err != nil { return "", false } diff --git a/vendor/github.com/containerd/containerd/api/services/images/v1/images.pb.go b/vendor/github.com/containerd/containerd/api/services/images/v1/images.pb.go index 70003cc12479f..41b97dfdd0e1f 100644 --- a/vendor/github.com/containerd/containerd/api/services/images/v1/images.pb.go +++ b/vendor/github.com/containerd/containerd/api/services/images/v1/images.pb.go @@ -67,6 +67,7 @@ type Image struct { // and do not get inherited into the package image in any way. // // Labels may be updated using the field mask. + // The combined size of a key/value pair cannot exceed 4096 bytes. Labels map[string]string `protobuf:"bytes,2,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // Target describes the content entry point of the image. Target containerd_types.Descriptor `protobuf:"bytes,3,opt,name=target" json:"target"` diff --git a/vendor/github.com/containerd/containerd/api/services/images/v1/images.proto b/vendor/github.com/containerd/containerd/api/services/images/v1/images.proto index 49a6cc42efea5..d6b6b8378a4a0 100644 --- a/vendor/github.com/containerd/containerd/api/services/images/v1/images.proto +++ b/vendor/github.com/containerd/containerd/api/services/images/v1/images.proto @@ -51,6 +51,7 @@ message Image { // and do not get inherited into the package image in any way. // // Labels may be updated using the field mask. + // The combined size of a key/value pair cannot exceed 4096 bytes. map labels = 2; // Target describes the content entry point of the image. diff --git a/vendor/github.com/containerd/containerd/api/services/introspection/v1/doc.go b/vendor/github.com/containerd/containerd/api/services/introspection/v1/doc.go new file mode 100644 index 0000000000000..3b9d7947c90e8 --- /dev/null +++ b/vendor/github.com/containerd/containerd/api/services/introspection/v1/doc.go @@ -0,0 +1 @@ +package introspection diff --git a/vendor/github.com/containerd/containerd/api/services/introspection/v1/introspection.pb.go b/vendor/github.com/containerd/containerd/api/services/introspection/v1/introspection.pb.go new file mode 100644 index 0000000000000..9e61bf725d2da --- /dev/null +++ b/vendor/github.com/containerd/containerd/api/services/introspection/v1/introspection.pb.go @@ -0,0 +1,1175 @@ +// Code generated by protoc-gen-gogo. +// source: github.com/containerd/containerd/api/services/introspection/v1/introspection.proto +// DO NOT EDIT! + +/* + Package introspection is a generated protocol buffer package. + + It is generated from these files: + github.com/containerd/containerd/api/services/introspection/v1/introspection.proto + + It has these top-level messages: + Plugin + PluginsRequest + PluginsResponse +*/ +package introspection + +import proto "github.com/gogo/protobuf/proto" +import fmt "fmt" +import math "math" +import containerd_types "github.com/containerd/containerd/api/types" +import google_rpc "github.com/containerd/containerd/protobuf/google/rpc" +import _ "github.com/gogo/protobuf/gogoproto" + +import ( + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) + +import strings "strings" +import reflect "reflect" +import github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys" + +import io "io" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type Plugin struct { + // Type defines the type of plugin. + // + // See package plugin for a list of possible values. Non core plugins may + // define their own values during registration. + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + // ID identifies the plugin uniquely in the system. + ID string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + // Requires lists the plugin types required by this plugin. + Requires []string `protobuf:"bytes,3,rep,name=requires" json:"requires,omitempty"` + // Platforms enumerates the platforms this plugin will support. + // + // If values are provided here, the plugin will only be operable under the + // provided platforms. + // + // If this is empty, the plugin will work across all platforms. + // + // If the plugin prefers certain platforms over others, they should be + // listed from most to least preferred. + Platforms []containerd_types.Platform `protobuf:"bytes,4,rep,name=platforms" json:"platforms"` + // Exports allows plugins to provide values about state or configuration to + // interested parties. + // + // One example is exposing the configured path of a snapshotter plugin. + Exports map[string]string `protobuf:"bytes,5,rep,name=exports" json:"exports,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // Capabilities allows plugins to communicate feature switches to allow + // clients to detect features that may not be on be default or may be + // different from version to version. + // + // Use this sparingly. + Capabilities []string `protobuf:"bytes,6,rep,name=capabilities" json:"capabilities,omitempty"` + // InitErr will be set if the plugin fails initialization. + // + // This means the plugin may have been registered but a non-terminal error + // was encountered during initialization. + // + // Plugins that have this value set cannot be used. + InitErr *google_rpc.Status `protobuf:"bytes,7,opt,name=init_err,json=initErr" json:"init_err,omitempty"` +} + +func (m *Plugin) Reset() { *m = Plugin{} } +func (*Plugin) ProtoMessage() {} +func (*Plugin) Descriptor() ([]byte, []int) { return fileDescriptorIntrospection, []int{0} } + +type PluginsRequest struct { + // Filters contains one or more filters using the syntax defined in the + // containerd filter package. + // + // The returned result will be those that match any of the provided + // filters. Expanded, plugins that match the following will be + // returned: + // + // filters[0] or filters[1] or ... or filters[n-1] or filters[n] + // + // If filters is zero-length or nil, all items will be returned. + Filters []string `protobuf:"bytes,1,rep,name=filters" json:"filters,omitempty"` +} + +func (m *PluginsRequest) Reset() { *m = PluginsRequest{} } +func (*PluginsRequest) ProtoMessage() {} +func (*PluginsRequest) Descriptor() ([]byte, []int) { return fileDescriptorIntrospection, []int{1} } + +type PluginsResponse struct { + Plugins []Plugin `protobuf:"bytes,1,rep,name=plugins" json:"plugins"` +} + +func (m *PluginsResponse) Reset() { *m = PluginsResponse{} } +func (*PluginsResponse) ProtoMessage() {} +func (*PluginsResponse) Descriptor() ([]byte, []int) { return fileDescriptorIntrospection, []int{2} } + +func init() { + proto.RegisterType((*Plugin)(nil), "containerd.services.introspection.v1.Plugin") + proto.RegisterType((*PluginsRequest)(nil), "containerd.services.introspection.v1.PluginsRequest") + proto.RegisterType((*PluginsResponse)(nil), "containerd.services.introspection.v1.PluginsResponse") +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// Client API for Introspection service + +type IntrospectionClient interface { + // Plugins returns a list of plugins in containerd. + // + // Clients can use this to detect features and capabilities when using + // containerd. + Plugins(ctx context.Context, in *PluginsRequest, opts ...grpc.CallOption) (*PluginsResponse, error) +} + +type introspectionClient struct { + cc *grpc.ClientConn +} + +func NewIntrospectionClient(cc *grpc.ClientConn) IntrospectionClient { + return &introspectionClient{cc} +} + +func (c *introspectionClient) Plugins(ctx context.Context, in *PluginsRequest, opts ...grpc.CallOption) (*PluginsResponse, error) { + out := new(PluginsResponse) + err := grpc.Invoke(ctx, "/containerd.services.introspection.v1.Introspection/Plugins", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for Introspection service + +type IntrospectionServer interface { + // Plugins returns a list of plugins in containerd. + // + // Clients can use this to detect features and capabilities when using + // containerd. + Plugins(context.Context, *PluginsRequest) (*PluginsResponse, error) +} + +func RegisterIntrospectionServer(s *grpc.Server, srv IntrospectionServer) { + s.RegisterService(&_Introspection_serviceDesc, srv) +} + +func _Introspection_Plugins_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PluginsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IntrospectionServer).Plugins(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/containerd.services.introspection.v1.Introspection/Plugins", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IntrospectionServer).Plugins(ctx, req.(*PluginsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Introspection_serviceDesc = grpc.ServiceDesc{ + ServiceName: "containerd.services.introspection.v1.Introspection", + HandlerType: (*IntrospectionServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Plugins", + Handler: _Introspection_Plugins_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "github.com/containerd/containerd/api/services/introspection/v1/introspection.proto", +} + +func (m *Plugin) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Plugin) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Type) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.Type))) + i += copy(dAtA[i:], m.Type) + } + if len(m.ID) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.ID))) + i += copy(dAtA[i:], m.ID) + } + if len(m.Requires) > 0 { + for _, s := range m.Requires { + dAtA[i] = 0x1a + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } + if len(m.Platforms) > 0 { + for _, msg := range m.Platforms { + dAtA[i] = 0x22 + i++ + i = encodeVarintIntrospection(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if len(m.Exports) > 0 { + for k, _ := range m.Exports { + dAtA[i] = 0x2a + i++ + v := m.Exports[k] + mapSize := 1 + len(k) + sovIntrospection(uint64(len(k))) + 1 + len(v) + sovIntrospection(uint64(len(v))) + i = encodeVarintIntrospection(dAtA, i, uint64(mapSize)) + dAtA[i] = 0xa + i++ + i = encodeVarintIntrospection(dAtA, i, uint64(len(k))) + i += copy(dAtA[i:], k) + dAtA[i] = 0x12 + i++ + i = encodeVarintIntrospection(dAtA, i, uint64(len(v))) + i += copy(dAtA[i:], v) + } + } + if len(m.Capabilities) > 0 { + for _, s := range m.Capabilities { + dAtA[i] = 0x32 + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } + if m.InitErr != nil { + dAtA[i] = 0x3a + i++ + i = encodeVarintIntrospection(dAtA, i, uint64(m.InitErr.Size())) + n1, err := m.InitErr.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n1 + } + return i, nil +} + +func (m *PluginsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PluginsRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Filters) > 0 { + for _, s := range m.Filters { + dAtA[i] = 0xa + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } + return i, nil +} + +func (m *PluginsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PluginsResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Plugins) > 0 { + for _, msg := range m.Plugins { + dAtA[i] = 0xa + i++ + i = encodeVarintIntrospection(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func encodeFixed64Introspection(dAtA []byte, offset int, v uint64) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) + dAtA[offset+4] = uint8(v >> 32) + dAtA[offset+5] = uint8(v >> 40) + dAtA[offset+6] = uint8(v >> 48) + dAtA[offset+7] = uint8(v >> 56) + return offset + 8 +} +func encodeFixed32Introspection(dAtA []byte, offset int, v uint32) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) + return offset + 4 +} +func encodeVarintIntrospection(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *Plugin) Size() (n int) { + var l int + _ = l + l = len(m.Type) + if l > 0 { + n += 1 + l + sovIntrospection(uint64(l)) + } + l = len(m.ID) + if l > 0 { + n += 1 + l + sovIntrospection(uint64(l)) + } + if len(m.Requires) > 0 { + for _, s := range m.Requires { + l = len(s) + n += 1 + l + sovIntrospection(uint64(l)) + } + } + if len(m.Platforms) > 0 { + for _, e := range m.Platforms { + l = e.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + } + if len(m.Exports) > 0 { + for k, v := range m.Exports { + _ = k + _ = v + mapEntrySize := 1 + len(k) + sovIntrospection(uint64(len(k))) + 1 + len(v) + sovIntrospection(uint64(len(v))) + n += mapEntrySize + 1 + sovIntrospection(uint64(mapEntrySize)) + } + } + if len(m.Capabilities) > 0 { + for _, s := range m.Capabilities { + l = len(s) + n += 1 + l + sovIntrospection(uint64(l)) + } + } + if m.InitErr != nil { + l = m.InitErr.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + return n +} + +func (m *PluginsRequest) Size() (n int) { + var l int + _ = l + if len(m.Filters) > 0 { + for _, s := range m.Filters { + l = len(s) + n += 1 + l + sovIntrospection(uint64(l)) + } + } + return n +} + +func (m *PluginsResponse) Size() (n int) { + var l int + _ = l + if len(m.Plugins) > 0 { + for _, e := range m.Plugins { + l = e.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + } + return n +} + +func sovIntrospection(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozIntrospection(x uint64) (n int) { + return sovIntrospection(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *Plugin) String() string { + if this == nil { + return "nil" + } + keysForExports := make([]string, 0, len(this.Exports)) + for k, _ := range this.Exports { + keysForExports = append(keysForExports, k) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForExports) + mapStringForExports := "map[string]string{" + for _, k := range keysForExports { + mapStringForExports += fmt.Sprintf("%v: %v,", k, this.Exports[k]) + } + mapStringForExports += "}" + s := strings.Join([]string{`&Plugin{`, + `Type:` + fmt.Sprintf("%v", this.Type) + `,`, + `ID:` + fmt.Sprintf("%v", this.ID) + `,`, + `Requires:` + fmt.Sprintf("%v", this.Requires) + `,`, + `Platforms:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Platforms), "Platform", "containerd_types.Platform", 1), `&`, ``, 1) + `,`, + `Exports:` + mapStringForExports + `,`, + `Capabilities:` + fmt.Sprintf("%v", this.Capabilities) + `,`, + `InitErr:` + strings.Replace(fmt.Sprintf("%v", this.InitErr), "Status", "google_rpc.Status", 1) + `,`, + `}`, + }, "") + return s +} +func (this *PluginsRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PluginsRequest{`, + `Filters:` + fmt.Sprintf("%v", this.Filters) + `,`, + `}`, + }, "") + return s +} +func (this *PluginsResponse) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PluginsResponse{`, + `Plugins:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Plugins), "Plugin", "Plugin", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func valueToStringIntrospection(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *Plugin) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Plugin: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Plugin: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Type = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Requires", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Requires = append(m.Requires, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Platforms", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Platforms = append(m.Platforms, containerd_types.Platform{}) + if err := m.Platforms[len(m.Platforms)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Exports", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + var keykey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + keykey |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthIntrospection + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey := string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + if m.Exports == nil { + m.Exports = make(map[string]string) + } + if iNdEx < postIndex { + var valuekey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + valuekey |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + var stringLenmapvalue uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapvalue |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapvalue := int(stringLenmapvalue) + if intStringLenmapvalue < 0 { + return ErrInvalidLengthIntrospection + } + postStringIndexmapvalue := iNdEx + intStringLenmapvalue + if postStringIndexmapvalue > l { + return io.ErrUnexpectedEOF + } + mapvalue := string(dAtA[iNdEx:postStringIndexmapvalue]) + iNdEx = postStringIndexmapvalue + m.Exports[mapkey] = mapvalue + } else { + var mapvalue string + m.Exports[mapkey] = mapvalue + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Capabilities", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Capabilities = append(m.Capabilities, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InitErr", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.InitErr == nil { + m.InitErr = &google_rpc.Status{} + } + if err := m.InitErr.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PluginsRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PluginsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PluginsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Filters", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Filters = append(m.Filters, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PluginsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PluginsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PluginsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Plugins", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Plugins = append(m.Plugins, Plugin{}) + if err := m.Plugins[len(m.Plugins)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipIntrospection(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowIntrospection + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowIntrospection + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowIntrospection + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthIntrospection + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowIntrospection + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipIntrospection(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthIntrospection = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowIntrospection = fmt.Errorf("proto: integer overflow") +) + +func init() { + proto.RegisterFile("github.com/containerd/containerd/api/services/introspection/v1/introspection.proto", fileDescriptorIntrospection) +} + +var fileDescriptorIntrospection = []byte{ + // 485 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x53, 0x3d, 0x6f, 0xdb, 0x30, + 0x10, 0x35, 0x65, 0xc7, 0x8a, 0xcf, 0xe9, 0x07, 0x88, 0xa0, 0x15, 0x34, 0x28, 0x86, 0xd1, 0xc1, + 0x28, 0x5a, 0x0a, 0x71, 0x5b, 0xa0, 0x49, 0x81, 0x0e, 0x46, 0x3d, 0x04, 0xc8, 0x10, 0x28, 0x5b, + 0x97, 0x40, 0x96, 0x69, 0x95, 0xa8, 0x22, 0x32, 0x24, 0x25, 0xd4, 0x5b, 0xb7, 0xfe, 0x35, 0x8f, + 0x1d, 0x3b, 0x05, 0x8d, 0x7e, 0x43, 0x7f, 0x40, 0x21, 0x51, 0x4a, 0xec, 0xcd, 0x46, 0xb6, 0xbb, + 0xa7, 0xf7, 0xee, 0xde, 0x3d, 0x88, 0x10, 0xc4, 0x4c, 0x7f, 0xcb, 0x66, 0x24, 0xe2, 0xd7, 0x7e, + 0xc4, 0x53, 0x1d, 0xb2, 0x94, 0xca, 0xf9, 0x7a, 0x19, 0x0a, 0xe6, 0x2b, 0x2a, 0x73, 0x16, 0x51, + 0xe5, 0xb3, 0x54, 0x4b, 0xae, 0x04, 0x8d, 0x34, 0xe3, 0xa9, 0x9f, 0x1f, 0x6f, 0x02, 0x44, 0x48, + 0xae, 0x39, 0x7e, 0xf5, 0xa0, 0x26, 0x8d, 0x92, 0x6c, 0x12, 0xf3, 0x63, 0xf7, 0x64, 0xab, 0xcd, + 0x7a, 0x29, 0xa8, 0xf2, 0x45, 0x12, 0xea, 0x05, 0x97, 0xd7, 0x66, 0x81, 0xfb, 0x32, 0xe6, 0x3c, + 0x4e, 0xa8, 0x2f, 0x45, 0xe4, 0x2b, 0x1d, 0xea, 0x4c, 0xd5, 0x1f, 0x0e, 0x63, 0x1e, 0xf3, 0xaa, + 0xf4, 0xcb, 0xca, 0xa0, 0xc3, 0x7f, 0x16, 0x74, 0x2f, 0x92, 0x2c, 0x66, 0x29, 0xc6, 0xd0, 0x29, + 0x27, 0x3a, 0x68, 0x80, 0x46, 0xbd, 0xa0, 0xaa, 0xf1, 0x0b, 0xb0, 0xd8, 0xdc, 0xb1, 0x4a, 0x64, + 0xd2, 0x2d, 0x6e, 0x8f, 0xac, 0xb3, 0x2f, 0x81, 0xc5, 0xe6, 0xd8, 0x85, 0x7d, 0x49, 0x6f, 0x32, + 0x26, 0xa9, 0x72, 0xda, 0x83, 0xf6, 0xa8, 0x17, 0xdc, 0xf7, 0xf8, 0x33, 0xf4, 0x1a, 0x4f, 0xca, + 0xe9, 0x0c, 0xda, 0xa3, 0xfe, 0xd8, 0x25, 0x6b, 0x67, 0x57, 0xb6, 0xc9, 0x45, 0x4d, 0x99, 0x74, + 0x56, 0xb7, 0x47, 0xad, 0xe0, 0x41, 0x82, 0x2f, 0xc1, 0xa6, 0x3f, 0x04, 0x97, 0x5a, 0x39, 0x7b, + 0x95, 0xfa, 0x84, 0x6c, 0x13, 0x1a, 0x31, 0x67, 0x90, 0xa9, 0xd1, 0x4e, 0x53, 0x2d, 0x97, 0x41, + 0x33, 0x09, 0x0f, 0xe1, 0x20, 0x0a, 0x45, 0x38, 0x63, 0x09, 0xd3, 0x8c, 0x2a, 0xa7, 0x5b, 0x99, + 0xde, 0xc0, 0xf0, 0x5b, 0xd8, 0x67, 0x29, 0xd3, 0x57, 0x54, 0x4a, 0xc7, 0x1e, 0xa0, 0x51, 0x7f, + 0x8c, 0x89, 0x49, 0x93, 0x48, 0x11, 0x91, 0xcb, 0x2a, 0xcd, 0xc0, 0x2e, 0x39, 0x53, 0x29, 0xdd, + 0x53, 0x38, 0x58, 0xdf, 0x85, 0x9f, 0x43, 0xfb, 0x3b, 0x5d, 0xd6, 0xf1, 0x95, 0x25, 0x3e, 0x84, + 0xbd, 0x3c, 0x4c, 0x32, 0x6a, 0x02, 0x0c, 0x4c, 0x73, 0x6a, 0x7d, 0x44, 0xc3, 0xd7, 0xf0, 0xd4, + 0xd8, 0x55, 0x01, 0xbd, 0xc9, 0xa8, 0xd2, 0xd8, 0x01, 0x7b, 0xc1, 0x12, 0x4d, 0xa5, 0x72, 0x50, + 0xe5, 0xad, 0x69, 0x87, 0x57, 0xf0, 0xec, 0x9e, 0xab, 0x04, 0x4f, 0x15, 0xc5, 0xe7, 0x60, 0x0b, + 0x03, 0x55, 0xe4, 0xfe, 0xf8, 0xcd, 0x2e, 0x11, 0xd5, 0x91, 0x37, 0x23, 0xc6, 0xbf, 0x10, 0x3c, + 0x39, 0x5b, 0xa7, 0xe2, 0x1c, 0xec, 0x7a, 0x25, 0x7e, 0xbf, 0xcb, 0xe4, 0xe6, 0x1a, 0xf7, 0xc3, + 0x8e, 0x2a, 0x73, 0xd7, 0x64, 0xb1, 0xba, 0xf3, 0x5a, 0x7f, 0xee, 0xbc, 0xd6, 0xcf, 0xc2, 0x43, + 0xab, 0xc2, 0x43, 0xbf, 0x0b, 0x0f, 0xfd, 0x2d, 0x3c, 0xf4, 0xf5, 0xfc, 0x71, 0x6f, 0xf1, 0xd3, + 0x06, 0x30, 0xeb, 0x56, 0x3f, 0xff, 0xbb, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0x21, 0xec, 0xef, + 0x92, 0xe2, 0x03, 0x00, 0x00, +} diff --git a/vendor/github.com/containerd/containerd/api/services/introspection/v1/introspection.proto b/vendor/github.com/containerd/containerd/api/services/introspection/v1/introspection.proto new file mode 100644 index 0000000000000..424c73164095a --- /dev/null +++ b/vendor/github.com/containerd/containerd/api/services/introspection/v1/introspection.proto @@ -0,0 +1,81 @@ +syntax = "proto3"; + +package containerd.services.introspection.v1; + +import "github.com/containerd/containerd/api/types/platform.proto"; +import "google/rpc/status.proto"; +import "gogoproto/gogo.proto"; + +option go_package = "github.com/containerd/containerd/api/services/introspection/v1;introspection"; + +service Introspection { + // Plugins returns a list of plugins in containerd. + // + // Clients can use this to detect features and capabilities when using + // containerd. + rpc Plugins(PluginsRequest) returns (PluginsResponse); +} + +message Plugin { + // Type defines the type of plugin. + // + // See package plugin for a list of possible values. Non core plugins may + // define their own values during registration. + string type = 1; + + // ID identifies the plugin uniquely in the system. + string id = 2; + + // Requires lists the plugin types required by this plugin. + repeated string requires = 3; + + // Platforms enumerates the platforms this plugin will support. + // + // If values are provided here, the plugin will only be operable under the + // provided platforms. + // + // If this is empty, the plugin will work across all platforms. + // + // If the plugin prefers certain platforms over others, they should be + // listed from most to least preferred. + repeated types.Platform platforms = 4 [(gogoproto.nullable) = false]; + + // Exports allows plugins to provide values about state or configuration to + // interested parties. + // + // One example is exposing the configured path of a snapshotter plugin. + map exports = 5; + + // Capabilities allows plugins to communicate feature switches to allow + // clients to detect features that may not be on be default or may be + // different from version to version. + // + // Use this sparingly. + repeated string capabilities = 6; + + // InitErr will be set if the plugin fails initialization. + // + // This means the plugin may have been registered but a non-terminal error + // was encountered during initialization. + // + // Plugins that have this value set cannot be used. + google.rpc.Status init_err = 7; +} + +message PluginsRequest { + // Filters contains one or more filters using the syntax defined in the + // containerd filter package. + // + // The returned result will be those that match any of the provided + // filters. Expanded, plugins that match the following will be + // returned: + // + // filters[0] or filters[1] or ... or filters[n-1] or filters[n] + // + // If filters is zero-length or nil, all items will be returned. + repeated string filters = 1; +} + +message PluginsResponse { + repeated Plugin plugins = 1 [(gogoproto.nullable) = false]; +} diff --git a/vendor/github.com/containerd/containerd/api/services/namespaces/v1/namespace.pb.go b/vendor/github.com/containerd/containerd/api/services/namespaces/v1/namespace.pb.go index 9854ec16ea7cb..e98330b6c27ee 100644 --- a/vendor/github.com/containerd/containerd/api/services/namespaces/v1/namespace.pb.go +++ b/vendor/github.com/containerd/containerd/api/services/namespaces/v1/namespace.pb.go @@ -55,6 +55,8 @@ type Namespace struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // Labels provides an area to include arbitrary data on namespaces. // + // The combined size of a key/value pair cannot exceed 4096 bytes. + // // Note that to add a new value to this field, read the existing set and // include the entire result in the update call. Labels map[string]string `protobuf:"bytes,2,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` diff --git a/vendor/github.com/containerd/containerd/api/services/namespaces/v1/namespace.proto b/vendor/github.com/containerd/containerd/api/services/namespaces/v1/namespace.proto index bbbd85054b1ca..d58a8c2ad275e 100644 --- a/vendor/github.com/containerd/containerd/api/services/namespaces/v1/namespace.proto +++ b/vendor/github.com/containerd/containerd/api/services/namespaces/v1/namespace.proto @@ -32,6 +32,8 @@ message Namespace { // Labels provides an area to include arbitrary data on namespaces. // + // The combined size of a key/value pair cannot exceed 4096 bytes. + // // Note that to add a new value to this field, read the existing set and // include the entire result in the update call. map labels = 2; diff --git a/vendor/github.com/containerd/containerd/api/services/snapshot/v1/snapshots.pb.go b/vendor/github.com/containerd/containerd/api/services/snapshot/v1/snapshots.pb.go index 2758bf49099e6..ae3c7927e6af1 100644 --- a/vendor/github.com/containerd/containerd/api/services/snapshot/v1/snapshots.pb.go +++ b/vendor/github.com/containerd/containerd/api/services/snapshot/v1/snapshots.pb.go @@ -97,6 +97,8 @@ type PrepareSnapshotRequest struct { Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` Parent string `protobuf:"bytes,3,opt,name=parent,proto3" json:"parent,omitempty"` // Labels are arbitrary data on snapshots. + // + // The combined size of a key/value pair cannot exceed 4096 bytes. Labels map[string]string `protobuf:"bytes,4,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } @@ -117,6 +119,8 @@ type ViewSnapshotRequest struct { Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` Parent string `protobuf:"bytes,3,opt,name=parent,proto3" json:"parent,omitempty"` // Labels are arbitrary data on snapshots. + // + // The combined size of a key/value pair cannot exceed 4096 bytes. Labels map[string]string `protobuf:"bytes,4,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } @@ -163,6 +167,8 @@ type CommitSnapshotRequest struct { Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` Key string `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` // Labels are arbitrary data on snapshots. + // + // The combined size of a key/value pair cannot exceed 4096 bytes. Labels map[string]string `protobuf:"bytes,4,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } @@ -188,6 +194,8 @@ type Info struct { // UpdatedAt provides the time the info was last updated. UpdatedAt time.Time `protobuf:"bytes,5,opt,name=updated_at,json=updatedAt,stdtime" json:"updated_at"` // Labels are arbitrary data on snapshots. + // + // The combined size of a key/value pair cannot exceed 4096 bytes. Labels map[string]string `protobuf:"bytes,6,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } diff --git a/vendor/github.com/containerd/containerd/api/services/snapshot/v1/snapshots.proto b/vendor/github.com/containerd/containerd/api/services/snapshot/v1/snapshots.proto index af3930ffb79e1..f8c08952021bc 100644 --- a/vendor/github.com/containerd/containerd/api/services/snapshot/v1/snapshots.proto +++ b/vendor/github.com/containerd/containerd/api/services/snapshot/v1/snapshots.proto @@ -29,6 +29,8 @@ message PrepareSnapshotRequest { string parent = 3; // Labels are arbitrary data on snapshots. + // + // The combined size of a key/value pair cannot exceed 4096 bytes. map labels = 4; } @@ -42,6 +44,8 @@ message ViewSnapshotRequest { string parent = 3; // Labels are arbitrary data on snapshots. + // + // The combined size of a key/value pair cannot exceed 4096 bytes. map labels = 4; } @@ -69,6 +73,8 @@ message CommitSnapshotRequest { string key = 3; // Labels are arbitrary data on snapshots. + // + // The combined size of a key/value pair cannot exceed 4096 bytes. map labels = 4; } @@ -99,6 +105,8 @@ message Info { google.protobuf.Timestamp updated_at = 5 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; // Labels are arbitrary data on snapshots. + // + // The combined size of a key/value pair cannot exceed 4096 bytes. map labels = 6; } diff --git a/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks.pb.go b/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks.pb.go index fb6efa8dde7a0..0f587685b945f 100644 --- a/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks.pb.go +++ b/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks.pb.go @@ -34,6 +34,8 @@ UpdateTaskRequest MetricsRequest MetricsResponse + WaitRequest + WaitResponse */ package tasks @@ -266,7 +268,8 @@ func (*ListPidsRequest) ProtoMessage() {} func (*ListPidsRequest) Descriptor() ([]byte, []int) { return fileDescriptorTasks, []int{18} } type ListPidsResponse struct { - Pids []uint32 `protobuf:"varint,1,rep,packed,name=pids" json:"pids,omitempty"` + // Processes includes the process ID and additional process information + Processes []*containerd_v1_types.ProcessInfo `protobuf:"bytes,1,rep,name=processes" json:"processes,omitempty"` } func (m *ListPidsResponse) Reset() { *m = ListPidsResponse{} } @@ -316,6 +319,24 @@ func (m *MetricsResponse) Reset() { *m = MetricsResponse{} } func (*MetricsResponse) ProtoMessage() {} func (*MetricsResponse) Descriptor() ([]byte, []int) { return fileDescriptorTasks, []int{24} } +type WaitRequest struct { + ContainerID string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` + ExecID string `protobuf:"bytes,2,opt,name=exec_id,json=execId,proto3" json:"exec_id,omitempty"` +} + +func (m *WaitRequest) Reset() { *m = WaitRequest{} } +func (*WaitRequest) ProtoMessage() {} +func (*WaitRequest) Descriptor() ([]byte, []int) { return fileDescriptorTasks, []int{25} } + +type WaitResponse struct { + ExitStatus uint32 `protobuf:"varint,1,opt,name=exit_status,json=exitStatus,proto3" json:"exit_status,omitempty"` + ExitedAt time.Time `protobuf:"bytes,2,opt,name=exited_at,json=exitedAt,stdtime" json:"exited_at"` +} + +func (m *WaitResponse) Reset() { *m = WaitResponse{} } +func (*WaitResponse) ProtoMessage() {} +func (*WaitResponse) Descriptor() ([]byte, []int) { return fileDescriptorTasks, []int{26} } + func init() { proto.RegisterType((*CreateTaskRequest)(nil), "containerd.services.tasks.v1.CreateTaskRequest") proto.RegisterType((*CreateTaskResponse)(nil), "containerd.services.tasks.v1.CreateTaskResponse") @@ -342,6 +363,8 @@ func init() { proto.RegisterType((*UpdateTaskRequest)(nil), "containerd.services.tasks.v1.UpdateTaskRequest") proto.RegisterType((*MetricsRequest)(nil), "containerd.services.tasks.v1.MetricsRequest") proto.RegisterType((*MetricsResponse)(nil), "containerd.services.tasks.v1.MetricsResponse") + proto.RegisterType((*WaitRequest)(nil), "containerd.services.tasks.v1.WaitRequest") + proto.RegisterType((*WaitResponse)(nil), "containerd.services.tasks.v1.WaitResponse") } // Reference imports to suppress errors if they are not otherwise used. @@ -375,6 +398,7 @@ type TasksClient interface { Checkpoint(ctx context.Context, in *CheckpointTaskRequest, opts ...grpc.CallOption) (*CheckpointTaskResponse, error) Update(ctx context.Context, in *UpdateTaskRequest, opts ...grpc.CallOption) (*google_protobuf.Empty, error) Metrics(ctx context.Context, in *MetricsRequest, opts ...grpc.CallOption) (*MetricsResponse, error) + Wait(ctx context.Context, in *WaitRequest, opts ...grpc.CallOption) (*WaitResponse, error) } type tasksClient struct { @@ -529,6 +553,15 @@ func (c *tasksClient) Metrics(ctx context.Context, in *MetricsRequest, opts ...g return out, nil } +func (c *tasksClient) Wait(ctx context.Context, in *WaitRequest, opts ...grpc.CallOption) (*WaitResponse, error) { + out := new(WaitResponse) + err := grpc.Invoke(ctx, "/containerd.services.tasks.v1.Tasks/Wait", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // Server API for Tasks service type TasksServer interface { @@ -552,6 +585,7 @@ type TasksServer interface { Checkpoint(context.Context, *CheckpointTaskRequest) (*CheckpointTaskResponse, error) Update(context.Context, *UpdateTaskRequest) (*google_protobuf.Empty, error) Metrics(context.Context, *MetricsRequest) (*MetricsResponse, error) + Wait(context.Context, *WaitRequest) (*WaitResponse, error) } func RegisterTasksServer(s *grpc.Server, srv TasksServer) { @@ -846,6 +880,24 @@ func _Tasks_Metrics_Handler(srv interface{}, ctx context.Context, dec func(inter return interceptor(ctx, in, info, handler) } +func _Tasks_Wait_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(WaitRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TasksServer).Wait(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/containerd.services.tasks.v1.Tasks/Wait", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TasksServer).Wait(ctx, req.(*WaitRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Tasks_serviceDesc = grpc.ServiceDesc{ ServiceName: "containerd.services.tasks.v1.Tasks", HandlerType: (*TasksServer)(nil), @@ -914,6 +966,10 @@ var _Tasks_serviceDesc = grpc.ServiceDesc{ MethodName: "Metrics", Handler: _Tasks_Metrics_Handler, }, + { + MethodName: "Wait", + Handler: _Tasks_Wait_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "github.com/containerd/containerd/api/services/tasks/v1/tasks.proto", @@ -1591,22 +1647,17 @@ func (m *ListPidsResponse) MarshalTo(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.Pids) > 0 { - dAtA7 := make([]byte, len(m.Pids)*10) - var j6 int - for _, num := range m.Pids { - for num >= 1<<7 { - dAtA7[j6] = uint8(uint64(num)&0x7f | 0x80) - num >>= 7 - j6++ - } - dAtA7[j6] = uint8(num) - j6++ + if len(m.Processes) > 0 { + for _, msg := range m.Processes { + dAtA[i] = 0xa + i++ + i = encodeVarintTasks(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n } - dAtA[i] = 0xa - i++ - i = encodeVarintTasks(dAtA, i, uint64(j6)) - i += copy(dAtA[i:], dAtA7[:j6]) } return i, nil } @@ -1642,11 +1693,11 @@ func (m *CheckpointTaskRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintTasks(dAtA, i, uint64(m.Options.Size())) - n8, err := m.Options.MarshalTo(dAtA[i:]) + n6, err := m.Options.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n8 + i += n6 } return i, nil } @@ -1706,11 +1757,11 @@ func (m *UpdateTaskRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintTasks(dAtA, i, uint64(m.Resources.Size())) - n9, err := m.Resources.MarshalTo(dAtA[i:]) + n7, err := m.Resources.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n9 + i += n7 } return i, nil } @@ -1778,6 +1829,67 @@ func (m *MetricsResponse) MarshalTo(dAtA []byte) (int, error) { return i, nil } +func (m *WaitRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *WaitRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.ContainerID) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintTasks(dAtA, i, uint64(len(m.ContainerID))) + i += copy(dAtA[i:], m.ContainerID) + } + if len(m.ExecID) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintTasks(dAtA, i, uint64(len(m.ExecID))) + i += copy(dAtA[i:], m.ExecID) + } + return i, nil +} + +func (m *WaitResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *WaitResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.ExitStatus != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintTasks(dAtA, i, uint64(m.ExitStatus)) + } + dAtA[i] = 0x12 + i++ + i = encodeVarintTasks(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.ExitedAt))) + n8, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.ExitedAt, dAtA[i:]) + if err != nil { + return 0, err + } + i += n8 + return i, nil +} + func encodeFixed64Tasks(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) dAtA[offset+1] = uint8(v >> 8) @@ -2097,12 +2209,11 @@ func (m *ListPidsRequest) Size() (n int) { func (m *ListPidsResponse) Size() (n int) { var l int _ = l - if len(m.Pids) > 0 { - l = 0 - for _, e := range m.Pids { - l += sovTasks(uint64(e)) + if len(m.Processes) > 0 { + for _, e := range m.Processes { + l = e.Size() + n += 1 + l + sovTasks(uint64(l)) } - n += 1 + sovTasks(uint64(l)) + l } return n } @@ -2175,6 +2286,31 @@ func (m *MetricsResponse) Size() (n int) { return n } +func (m *WaitRequest) Size() (n int) { + var l int + _ = l + l = len(m.ContainerID) + if l > 0 { + n += 1 + l + sovTasks(uint64(l)) + } + l = len(m.ExecID) + if l > 0 { + n += 1 + l + sovTasks(uint64(l)) + } + return n +} + +func (m *WaitResponse) Size() (n int) { + var l int + _ = l + if m.ExitStatus != 0 { + n += 1 + sovTasks(uint64(m.ExitStatus)) + } + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.ExitedAt) + n += 1 + l + sovTasks(uint64(l)) + return n +} + func sovTasks(x uint64) (n int) { for { n++ @@ -2410,7 +2546,7 @@ func (this *ListPidsResponse) String() string { return "nil" } s := strings.Join([]string{`&ListPidsResponse{`, - `Pids:` + fmt.Sprintf("%v", this.Pids) + `,`, + `Processes:` + strings.Replace(fmt.Sprintf("%v", this.Processes), "ProcessInfo", "containerd_v1_types.ProcessInfo", 1) + `,`, `}`, }, "") return s @@ -2468,6 +2604,28 @@ func (this *MetricsResponse) String() string { }, "") return s } +func (this *WaitRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&WaitRequest{`, + `ContainerID:` + fmt.Sprintf("%v", this.ContainerID) + `,`, + `ExecID:` + fmt.Sprintf("%v", this.ExecID) + `,`, + `}`, + }, "") + return s +} +func (this *WaitResponse) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&WaitResponse{`, + `ExitStatus:` + fmt.Sprintf("%v", this.ExitStatus) + `,`, + `ExitedAt:` + strings.Replace(strings.Replace(this.ExitedAt.String(), "Timestamp", "google_protobuf3.Timestamp", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} func valueToStringTasks(v interface{}) string { rv := reflect.ValueOf(v) if rv.IsNil() { @@ -4705,67 +4863,36 @@ func (m *ListPidsResponse) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: - if wireType == 0 { - var v uint32 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTasks - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (uint32(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Pids = append(m.Pids, v) - } else if wireType == 2 { - var packedLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTasks - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - packedLen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if packedLen < 0 { - return ErrInvalidLengthTasks + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Processes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTasks } - postIndex := iNdEx + packedLen - if postIndex > l { + if iNdEx >= l { return io.ErrUnexpectedEOF } - for iNdEx < postIndex { - var v uint32 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTasks - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (uint32(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Pids = append(m.Pids, v) + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break } - } else { - return fmt.Errorf("proto: wrong wireType = %d for field Pids", wireType) } + if msglen < 0 { + return ErrInvalidLengthTasks + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Processes = append(m.Processes, &containerd_v1_types.ProcessInfo{}) + if err := m.Processes[len(m.Processes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTasks(dAtA[iNdEx:]) @@ -5281,6 +5408,213 @@ func (m *MetricsResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *WaitRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTasks + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: WaitRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: WaitRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContainerID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTasks + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTasks + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContainerID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExecID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTasks + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTasks + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ExecID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTasks(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTasks + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *WaitResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTasks + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: WaitResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: WaitResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ExitStatus", wireType) + } + m.ExitStatus = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTasks + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ExitStatus |= (uint32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExitedAt", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTasks + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTasks + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.ExitedAt, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTasks(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTasks + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipTasks(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 @@ -5391,85 +5725,88 @@ func init() { } var fileDescriptorTasks = []byte{ - // 1274 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0x4f, 0x6f, 0x1b, 0x45, - 0x14, 0xef, 0xc6, 0xf6, 0xda, 0x7e, 0x6e, 0xda, 0x64, 0x48, 0xc3, 0xb2, 0x54, 0x71, 0x58, 0x24, - 0x64, 0x02, 0xdd, 0xa5, 0x2e, 0xaa, 0x10, 0xad, 0x90, 0x9a, 0x3f, 0x44, 0x16, 0x54, 0x4d, 0xb7, - 0x05, 0xa1, 0x5e, 0xc2, 0x76, 0x77, 0xe2, 0x8c, 0x62, 0xef, 0x6e, 0x77, 0xc6, 0x69, 0x03, 0x07, - 0xf8, 0x08, 0xbd, 0x72, 0xe1, 0xf3, 0xe4, 0xc8, 0x11, 0x21, 0x14, 0xa8, 0xbf, 0x05, 0x07, 0x24, - 0x34, 0x7f, 0x76, 0xb3, 0xb1, 0xe3, 0xd8, 0xa9, 0x1b, 0x2e, 0xed, 0xcc, 0xec, 0xef, 0xbd, 0x79, - 0xf3, 0x9b, 0x37, 0xef, 0xfd, 0x1c, 0x58, 0x6d, 0x13, 0xb6, 0xdb, 0x7b, 0x6a, 0xfb, 0x51, 0xd7, - 0xf1, 0xa3, 0x90, 0x79, 0x24, 0xc4, 0x49, 0x90, 0x1f, 0x7a, 0x31, 0x71, 0x28, 0x4e, 0xf6, 0x89, - 0x8f, 0xa9, 0xc3, 0x3c, 0xba, 0x47, 0x9d, 0xfd, 0x9b, 0x72, 0x60, 0xc7, 0x49, 0xc4, 0x22, 0x74, - 0xfd, 0x18, 0x6d, 0xa7, 0x48, 0x5b, 0x02, 0xf6, 0x6f, 0x9a, 0xef, 0xb6, 0xa3, 0xa8, 0xdd, 0xc1, - 0x8e, 0xc0, 0x3e, 0xed, 0xed, 0x38, 0xb8, 0x1b, 0xb3, 0x03, 0x69, 0x6a, 0xbe, 0x33, 0xf8, 0xd1, - 0x0b, 0xd3, 0x4f, 0x0b, 0xed, 0xa8, 0x1d, 0x89, 0xa1, 0xc3, 0x47, 0x6a, 0xf5, 0xf6, 0x44, 0xf1, - 0xb2, 0x83, 0x18, 0x53, 0xa7, 0x1b, 0xf5, 0x42, 0xa6, 0xec, 0x3e, 0x3b, 0x8f, 0x1d, 0x66, 0x09, - 0xf1, 0xd5, 0xe9, 0xcc, 0x3b, 0xe7, 0xb0, 0x0c, 0x30, 0xf5, 0x13, 0x12, 0xb3, 0x28, 0x51, 0xc6, - 0x9f, 0x9f, 0xc3, 0x98, 0x33, 0x26, 0xfe, 0x51, 0xb6, 0xf5, 0x41, 0x6e, 0x18, 0xe9, 0x62, 0xca, - 0xbc, 0x6e, 0x2c, 0x01, 0xd6, 0xe1, 0x0c, 0xcc, 0xaf, 0x25, 0xd8, 0x63, 0xf8, 0xb1, 0x47, 0xf7, - 0x5c, 0xfc, 0xac, 0x87, 0x29, 0x43, 0x4d, 0xb8, 0x9c, 0xb9, 0xdf, 0x26, 0x81, 0xa1, 0x2d, 0x6b, - 0x8d, 0xea, 0xea, 0xd5, 0xfe, 0x51, 0xbd, 0xb6, 0x96, 0xae, 0xb7, 0xd6, 0xdd, 0x5a, 0x06, 0x6a, - 0x05, 0xc8, 0x01, 0x3d, 0x89, 0x22, 0xb6, 0x43, 0x8d, 0xc2, 0x72, 0xa1, 0x51, 0x6b, 0xbe, 0x6d, - 0xe7, 0xae, 0x54, 0x44, 0x67, 0xdf, 0xe7, 0x64, 0xba, 0x0a, 0x86, 0x16, 0xa0, 0x44, 0x59, 0x40, - 0x42, 0xa3, 0xc8, 0xbd, 0xbb, 0x72, 0x82, 0x16, 0x41, 0xa7, 0x2c, 0x88, 0x7a, 0xcc, 0x28, 0x89, - 0x65, 0x35, 0x53, 0xeb, 0x38, 0x49, 0x0c, 0x3d, 0x5b, 0xc7, 0x49, 0x82, 0x4c, 0xa8, 0x30, 0x9c, - 0x74, 0x49, 0xe8, 0x75, 0x8c, 0xf2, 0xb2, 0xd6, 0xa8, 0xb8, 0xd9, 0x1c, 0xdd, 0x05, 0xf0, 0x77, - 0xb1, 0xbf, 0x17, 0x47, 0x24, 0x64, 0x46, 0x65, 0x59, 0x6b, 0xd4, 0x9a, 0xd7, 0x87, 0xc3, 0x5a, - 0xcf, 0x18, 0x77, 0x73, 0x78, 0x64, 0x43, 0x39, 0x8a, 0x19, 0x89, 0x42, 0x6a, 0x54, 0x85, 0xe9, - 0x82, 0x2d, 0xd9, 0xb4, 0x53, 0x36, 0xed, 0x7b, 0xe1, 0x81, 0x9b, 0x82, 0xac, 0x27, 0x80, 0xf2, - 0x4c, 0xd2, 0x38, 0x0a, 0x29, 0x7e, 0x2d, 0x2a, 0xe7, 0xa0, 0x10, 0x93, 0xc0, 0x98, 0x59, 0xd6, - 0x1a, 0xb3, 0x2e, 0x1f, 0x5a, 0x6d, 0xb8, 0xfc, 0x88, 0x79, 0x09, 0x9b, 0xe6, 0x82, 0xde, 0x87, - 0x32, 0x7e, 0x81, 0xfd, 0x6d, 0xe5, 0xb9, 0xba, 0x0a, 0xfd, 0xa3, 0xba, 0xbe, 0xf1, 0x02, 0xfb, - 0xad, 0x75, 0x57, 0xe7, 0x9f, 0x5a, 0x81, 0xf5, 0x1e, 0xcc, 0xaa, 0x8d, 0x54, 0xfc, 0x2a, 0x16, - 0xed, 0x38, 0x96, 0x4d, 0x98, 0x5f, 0xc7, 0x1d, 0x3c, 0x75, 0xc6, 0x58, 0xbf, 0x6a, 0x70, 0x45, - 0x7a, 0xca, 0x76, 0x5b, 0x84, 0x99, 0xcc, 0x58, 0xef, 0x1f, 0xd5, 0x67, 0x5a, 0xeb, 0xee, 0x0c, - 0x39, 0x85, 0x11, 0x54, 0x87, 0x1a, 0x7e, 0x41, 0xd8, 0x36, 0x65, 0x1e, 0xeb, 0xf1, 0x9c, 0xe3, - 0x5f, 0x80, 0x2f, 0x3d, 0x12, 0x2b, 0xe8, 0x1e, 0x54, 0xf9, 0x0c, 0x07, 0xdb, 0x1e, 0x13, 0x29, - 0x56, 0x6b, 0x9a, 0x43, 0x17, 0xf8, 0x38, 0x7d, 0x0e, 0xab, 0x95, 0xc3, 0xa3, 0xfa, 0xa5, 0x97, - 0x7f, 0xd5, 0x35, 0xb7, 0x22, 0xcd, 0xee, 0x31, 0x2b, 0x82, 0x05, 0x19, 0xdf, 0x56, 0x12, 0xf9, - 0x98, 0xd2, 0x0b, 0x67, 0x1f, 0x03, 0x6c, 0xe2, 0x8b, 0xbf, 0xe4, 0x0d, 0xa8, 0x89, 0x6d, 0x14, - 0xe9, 0xb7, 0xa1, 0x1c, 0xcb, 0x03, 0x8a, 0x2d, 0x06, 0xde, 0xc8, 0xfe, 0x4d, 0xf5, 0x4c, 0x52, - 0x12, 0x52, 0xb0, 0xb5, 0x02, 0x73, 0x5f, 0x13, 0xca, 0x78, 0x1a, 0x64, 0xd4, 0x2c, 0x82, 0xbe, - 0x43, 0x3a, 0x0c, 0x27, 0x32, 0x5a, 0x57, 0xcd, 0x78, 0xd2, 0xe4, 0xb0, 0xd9, 0xdb, 0x28, 0x89, - 0x12, 0x6f, 0x68, 0xa2, 0x62, 0x9c, 0xbd, 0xad, 0x84, 0x5a, 0x2f, 0x35, 0xa8, 0x7d, 0x45, 0x3a, - 0x9d, 0x8b, 0x26, 0x49, 0x14, 0x1c, 0xd2, 0xe6, 0x65, 0x45, 0xe6, 0x96, 0x9a, 0xf1, 0x54, 0xf4, - 0x3a, 0x1d, 0x91, 0x51, 0x15, 0x97, 0x0f, 0xad, 0x7f, 0x34, 0x40, 0xdc, 0xf8, 0x0d, 0x64, 0x49, - 0x56, 0x13, 0x67, 0x4e, 0xaf, 0x89, 0x85, 0x11, 0x35, 0xb1, 0x38, 0xb2, 0x26, 0x96, 0x06, 0x6a, - 0x62, 0x03, 0x8a, 0x34, 0xc6, 0xbe, 0xa8, 0xa2, 0xa3, 0x4a, 0x9a, 0x40, 0xe4, 0x59, 0x2a, 0x8f, - 0x4c, 0xa5, 0x6b, 0xf0, 0xd6, 0x89, 0xa3, 0xcb, 0x9b, 0xb5, 0x7e, 0xd1, 0x60, 0xce, 0xc5, 0x94, - 0xfc, 0x80, 0xb7, 0xd8, 0xc1, 0x85, 0x5f, 0xd5, 0x02, 0x94, 0x9e, 0x93, 0x80, 0xed, 0xaa, 0x9b, - 0x92, 0x13, 0xce, 0xce, 0x2e, 0x26, 0xed, 0x5d, 0xf9, 0xfa, 0x67, 0x5d, 0x35, 0xb3, 0x7e, 0x82, - 0x2b, 0x6b, 0x9d, 0x88, 0xe2, 0xd6, 0x83, 0xff, 0x23, 0x30, 0x79, 0x9d, 0x05, 0x71, 0x0b, 0x72, - 0x62, 0x7d, 0x09, 0x73, 0x5b, 0x5e, 0x8f, 0x4e, 0x5d, 0x3f, 0x37, 0x61, 0xde, 0xc5, 0xb4, 0xd7, - 0x9d, 0xda, 0xd1, 0x06, 0x5c, 0xe5, 0x8f, 0x73, 0x8b, 0x04, 0xd3, 0x24, 0xaf, 0xf5, 0x81, 0xac, - 0x07, 0xd2, 0x8d, 0x7a, 0xe2, 0x08, 0x8a, 0x31, 0x09, 0xe4, 0x0b, 0x9f, 0x75, 0xc5, 0xd8, 0xfa, - 0x53, 0x83, 0x6b, 0x6b, 0x59, 0x9f, 0x9d, 0x56, 0x77, 0x6c, 0xc3, 0x7c, 0xec, 0x25, 0x38, 0x64, - 0xdb, 0xb9, 0x5e, 0x2f, 0xaf, 0xa4, 0xc9, 0x6b, 0xfa, 0x1f, 0x47, 0xf5, 0x95, 0x9c, 0x82, 0x8a, - 0x62, 0x1c, 0x66, 0xe6, 0xd4, 0x69, 0x47, 0x37, 0x02, 0xd2, 0xc6, 0x94, 0xd9, 0xeb, 0xe2, 0x3f, - 0x77, 0x4e, 0x3a, 0x5b, 0x3b, 0x55, 0x07, 0x14, 0x26, 0xd1, 0x01, 0xdf, 0xc1, 0xe2, 0xe0, 0xe9, - 0x14, 0x19, 0x5f, 0x40, 0xed, 0x58, 0xdd, 0x9d, 0x5a, 0xf5, 0x86, 0x04, 0x49, 0xde, 0xc0, 0xfa, - 0x11, 0xe6, 0xbf, 0x89, 0x83, 0x37, 0xa0, 0xd5, 0x9a, 0x50, 0x4d, 0x30, 0x8d, 0x7a, 0x89, 0x8f, - 0xa9, 0xe0, 0x6a, 0xd4, 0xa1, 0x8e, 0x61, 0xd6, 0x0a, 0x5c, 0xb9, 0x2f, 0x45, 0x6d, 0xba, 0xb3, - 0x01, 0x65, 0x59, 0xdd, 0xe5, 0x51, 0xaa, 0x6e, 0x3a, 0xe5, 0x09, 0x95, 0x61, 0xb3, 0x5a, 0x5f, - 0x56, 0x9a, 0x58, 0x9d, 0xdb, 0x38, 0x45, 0x1f, 0x0a, 0x80, 0x9b, 0x02, 0x9b, 0xff, 0xd6, 0xa0, - 0x24, 0x3a, 0x06, 0xda, 0x03, 0x5d, 0x6a, 0x2b, 0xe4, 0xd8, 0x67, 0xfd, 0x52, 0xb0, 0x87, 0xb4, - 0xac, 0xf9, 0xc9, 0xe4, 0x06, 0x2a, 0xd4, 0xef, 0xa1, 0x24, 0x34, 0x10, 0x5a, 0x39, 0xdb, 0x34, - 0xaf, 0xc8, 0xcc, 0x8f, 0x26, 0xc2, 0xaa, 0x1d, 0xda, 0xa0, 0x4b, 0x61, 0x31, 0xee, 0x38, 0x43, - 0x42, 0xcb, 0xfc, 0x78, 0x12, 0x83, 0x6c, 0xa3, 0x67, 0x30, 0x7b, 0x42, 0xc1, 0xa0, 0xe6, 0x24, - 0xe6, 0x27, 0x1b, 0xd9, 0x39, 0xb7, 0x7c, 0x02, 0x85, 0x4d, 0xcc, 0x50, 0xe3, 0x6c, 0xa3, 0x63, - 0x99, 0x63, 0x7e, 0x38, 0x01, 0x32, 0xe3, 0xad, 0xc8, 0x2b, 0x0c, 0xb2, 0xcf, 0x36, 0x19, 0x54, - 0x25, 0xa6, 0x33, 0x31, 0x5e, 0x6d, 0xd4, 0x82, 0x22, 0x17, 0x19, 0x68, 0x4c, 0x6c, 0x39, 0x21, - 0x62, 0x2e, 0x0e, 0x3d, 0xa0, 0x0d, 0xfe, 0x23, 0x15, 0x6d, 0x41, 0x91, 0x77, 0x05, 0x34, 0x26, - 0x0f, 0x87, 0x05, 0xc4, 0x48, 0x8f, 0x8f, 0xa0, 0x9a, 0xf5, 0xd6, 0x71, 0x54, 0x0c, 0x36, 0xe1, - 0x91, 0x4e, 0x1f, 0x40, 0x59, 0x75, 0x45, 0x34, 0xe6, 0xbe, 0x4f, 0x36, 0xcf, 0x33, 0x1c, 0x96, - 0x44, 0x97, 0x1b, 0x17, 0xe1, 0x60, 0x2b, 0x1c, 0xe9, 0xf0, 0x21, 0xe8, 0xb2, 0xdd, 0x8d, 0x7b, - 0x34, 0x43, 0x4d, 0x71, 0xa4, 0x4b, 0x02, 0x95, 0xb4, 0x63, 0xa1, 0x1b, 0xe3, 0x73, 0x24, 0xd7, - 0x20, 0x4d, 0x7b, 0x52, 0xb8, 0xca, 0xa8, 0xe7, 0x00, 0xb9, 0x9e, 0x72, 0x6b, 0x0c, 0xc5, 0xa7, - 0x75, 0x47, 0xf3, 0xd3, 0xf3, 0x19, 0xa9, 0x8d, 0x1f, 0x82, 0x2e, 0x9b, 0xc6, 0x38, 0xda, 0x86, - 0x5a, 0xcb, 0x48, 0xda, 0x76, 0xa0, 0xac, 0xca, 0xfb, 0xb8, 0x5c, 0x39, 0xd9, 0x31, 0xcc, 0x1b, - 0x13, 0xa2, 0x65, 0xe8, 0xab, 0xdf, 0x1e, 0xbe, 0x5a, 0xba, 0xf4, 0xfb, 0xab, 0xa5, 0x4b, 0x3f, - 0xf7, 0x97, 0xb4, 0xc3, 0xfe, 0x92, 0xf6, 0x5b, 0x7f, 0x49, 0xfb, 0xbb, 0xbf, 0xa4, 0x3d, 0xb9, - 0xfb, 0x7a, 0x7f, 0x72, 0xba, 0x23, 0x06, 0x4f, 0x75, 0x71, 0x9e, 0x5b, 0xff, 0x05, 0x00, 0x00, - 0xff, 0xff, 0x5e, 0xf6, 0xae, 0x85, 0xb9, 0x12, 0x00, 0x00, + // 1317 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0x5b, 0x6f, 0x1b, 0x45, + 0x1b, 0xee, 0xfa, 0xec, 0xd7, 0x49, 0x9b, 0xec, 0x97, 0xe6, 0x33, 0x4b, 0x15, 0x87, 0xe5, 0xc6, + 0x04, 0xba, 0x4b, 0x5d, 0x54, 0x21, 0x5a, 0x21, 0x35, 0x07, 0x22, 0x0b, 0xaa, 0xa6, 0xdb, 0x72, + 0x50, 0x25, 0x14, 0xb6, 0xbb, 0x13, 0x67, 0x14, 0x7b, 0x67, 0xbb, 0x33, 0x4e, 0x1b, 0xb8, 0x80, + 0x9f, 0xd0, 0x5b, 0x6e, 0xf8, 0x3d, 0xb9, 0xe4, 0x12, 0xa1, 0x2a, 0x50, 0xff, 0x0b, 0xee, 0xd0, + 0x1c, 0x76, 0xb3, 0xb1, 0x63, 0xaf, 0x93, 0x34, 0xdc, 0xb4, 0x33, 0xb3, 0xef, 0x69, 0x9e, 0x79, + 0x0f, 0x8f, 0x03, 0xab, 0x1d, 0xcc, 0x76, 0xfb, 0xcf, 0x2c, 0x8f, 0xf4, 0x6c, 0x8f, 0x04, 0xcc, + 0xc5, 0x01, 0x8a, 0xfc, 0xf4, 0xd2, 0x0d, 0xb1, 0x4d, 0x51, 0xb4, 0x8f, 0x3d, 0x44, 0x6d, 0xe6, + 0xd2, 0x3d, 0x6a, 0xef, 0xdf, 0x92, 0x0b, 0x2b, 0x8c, 0x08, 0x23, 0xfa, 0x8d, 0x63, 0x69, 0x2b, + 0x96, 0xb4, 0xa4, 0xc0, 0xfe, 0x2d, 0xe3, 0xdd, 0x0e, 0x21, 0x9d, 0x2e, 0xb2, 0x85, 0xec, 0xb3, + 0xfe, 0x8e, 0x8d, 0x7a, 0x21, 0x3b, 0x90, 0xaa, 0xc6, 0x3b, 0xc3, 0x1f, 0xdd, 0x20, 0xfe, 0xb4, + 0xd0, 0x21, 0x1d, 0x22, 0x96, 0x36, 0x5f, 0xa9, 0xd3, 0x3b, 0x53, 0xc5, 0xcb, 0x0e, 0x42, 0x44, + 0xed, 0x1e, 0xe9, 0x07, 0x4c, 0xe9, 0x7d, 0x7a, 0x16, 0x3d, 0xc4, 0x22, 0xec, 0xa9, 0xdb, 0x19, + 0x77, 0xcf, 0xa0, 0xe9, 0x23, 0xea, 0x45, 0x38, 0x64, 0x24, 0x52, 0xca, 0x9f, 0x9d, 0x41, 0x99, + 0x23, 0x26, 0xfe, 0x51, 0xba, 0x8d, 0x61, 0x6c, 0x18, 0xee, 0x21, 0xca, 0xdc, 0x5e, 0x28, 0x05, + 0xcc, 0xc3, 0x1c, 0xcc, 0xaf, 0x45, 0xc8, 0x65, 0xe8, 0x89, 0x4b, 0xf7, 0x1c, 0xf4, 0xbc, 0x8f, + 0x28, 0xd3, 0x5b, 0x30, 0x93, 0x98, 0xdf, 0xc6, 0x7e, 0x5d, 0x5b, 0xd6, 0x9a, 0xd5, 0xd5, 0x6b, + 0x83, 0xa3, 0x46, 0x6d, 0x2d, 0x3e, 0x6f, 0xaf, 0x3b, 0xb5, 0x44, 0xa8, 0xed, 0xeb, 0x36, 0x94, + 0x22, 0x42, 0xd8, 0x0e, 0xad, 0xe7, 0x97, 0xf3, 0xcd, 0x5a, 0xeb, 0xff, 0x56, 0xea, 0x49, 0x45, + 0x74, 0xd6, 0x03, 0x0e, 0xa6, 0xa3, 0xc4, 0xf4, 0x05, 0x28, 0x52, 0xe6, 0xe3, 0xa0, 0x5e, 0xe0, + 0xd6, 0x1d, 0xb9, 0xd1, 0x17, 0xa1, 0x44, 0x99, 0x4f, 0xfa, 0xac, 0x5e, 0x14, 0xc7, 0x6a, 0xa7, + 0xce, 0x51, 0x14, 0xd5, 0x4b, 0xc9, 0x39, 0x8a, 0x22, 0xdd, 0x80, 0x0a, 0x43, 0x51, 0x0f, 0x07, + 0x6e, 0xb7, 0x5e, 0x5e, 0xd6, 0x9a, 0x15, 0x27, 0xd9, 0xeb, 0xf7, 0x00, 0xbc, 0x5d, 0xe4, 0xed, + 0x85, 0x04, 0x07, 0xac, 0x5e, 0x59, 0xd6, 0x9a, 0xb5, 0xd6, 0x8d, 0xd1, 0xb0, 0xd6, 0x13, 0xc4, + 0x9d, 0x94, 0xbc, 0x6e, 0x41, 0x99, 0x84, 0x0c, 0x93, 0x80, 0xd6, 0xab, 0x42, 0x75, 0xc1, 0x92, + 0x68, 0x5a, 0x31, 0x9a, 0xd6, 0xfd, 0xe0, 0xc0, 0x89, 0x85, 0xcc, 0xa7, 0xa0, 0xa7, 0x91, 0xa4, + 0x21, 0x09, 0x28, 0x3a, 0x17, 0x94, 0x73, 0x90, 0x0f, 0xb1, 0x5f, 0xcf, 0x2d, 0x6b, 0xcd, 0x59, + 0x87, 0x2f, 0xcd, 0x0e, 0xcc, 0x3c, 0x66, 0x6e, 0xc4, 0x2e, 0xf2, 0x40, 0xef, 0x43, 0x19, 0xbd, + 0x44, 0xde, 0xb6, 0xb2, 0x5c, 0x5d, 0x85, 0xc1, 0x51, 0xa3, 0xb4, 0xf1, 0x12, 0x79, 0xed, 0x75, + 0xa7, 0xc4, 0x3f, 0xb5, 0x7d, 0xf3, 0x3d, 0x98, 0x55, 0x8e, 0x54, 0xfc, 0x2a, 0x16, 0xed, 0x38, + 0x96, 0x4d, 0x98, 0x5f, 0x47, 0x5d, 0x74, 0xe1, 0x8c, 0x31, 0x7f, 0xd3, 0xe0, 0xaa, 0xb4, 0x94, + 0x78, 0x5b, 0x84, 0x5c, 0xa2, 0x5c, 0x1a, 0x1c, 0x35, 0x72, 0xed, 0x75, 0x27, 0x87, 0x4f, 0x41, + 0x44, 0x6f, 0x40, 0x0d, 0xbd, 0xc4, 0x6c, 0x9b, 0x32, 0x97, 0xf5, 0x79, 0xce, 0xf1, 0x2f, 0xc0, + 0x8f, 0x1e, 0x8b, 0x13, 0xfd, 0x3e, 0x54, 0xf9, 0x0e, 0xf9, 0xdb, 0x2e, 0x13, 0x29, 0x56, 0x6b, + 0x19, 0x23, 0x0f, 0xf8, 0x24, 0x2e, 0x87, 0xd5, 0xca, 0xe1, 0x51, 0xe3, 0xca, 0xab, 0xbf, 0x1a, + 0x9a, 0x53, 0x91, 0x6a, 0xf7, 0x99, 0x49, 0x60, 0x41, 0xc6, 0xb7, 0x15, 0x11, 0x0f, 0x51, 0x7a, + 0xe9, 0xe8, 0x23, 0x80, 0x4d, 0x74, 0xf9, 0x8f, 0xbc, 0x01, 0x35, 0xe1, 0x46, 0x81, 0x7e, 0x07, + 0xca, 0xa1, 0xbc, 0xa0, 0x70, 0x31, 0x54, 0x23, 0xfb, 0xb7, 0x54, 0x99, 0xc4, 0x20, 0xc4, 0xc2, + 0xe6, 0x0a, 0xcc, 0x7d, 0x85, 0x29, 0xe3, 0x69, 0x90, 0x40, 0xb3, 0x08, 0xa5, 0x1d, 0xdc, 0x65, + 0x28, 0x92, 0xd1, 0x3a, 0x6a, 0xc7, 0x93, 0x26, 0x25, 0x9b, 0xd4, 0x46, 0x51, 0xb4, 0xf8, 0xba, + 0x26, 0x3a, 0xc6, 0x64, 0xb7, 0x52, 0xd4, 0x7c, 0xa5, 0x41, 0xed, 0x4b, 0xdc, 0xed, 0x5e, 0x36, + 0x48, 0xa2, 0xe1, 0xe0, 0x0e, 0x6f, 0x2b, 0x32, 0xb7, 0xd4, 0x8e, 0xa7, 0xa2, 0xdb, 0xed, 0x8a, + 0x8c, 0xaa, 0x38, 0x7c, 0x69, 0xfe, 0xa3, 0x81, 0xce, 0x95, 0xdf, 0x42, 0x96, 0x24, 0x3d, 0x31, + 0x77, 0x7a, 0x4f, 0xcc, 0x8f, 0xe9, 0x89, 0x85, 0xb1, 0x3d, 0xb1, 0x38, 0xd4, 0x13, 0x9b, 0x50, + 0xa0, 0x21, 0xf2, 0x44, 0x17, 0x1d, 0xd7, 0xd2, 0x84, 0x44, 0x1a, 0xa5, 0xf2, 0xd8, 0x54, 0xba, + 0x0e, 0xff, 0x3b, 0x71, 0x75, 0xf9, 0xb2, 0xe6, 0xaf, 0x1a, 0xcc, 0x39, 0x88, 0xe2, 0x1f, 0xd1, + 0x16, 0x3b, 0xb8, 0xf4, 0xa7, 0x5a, 0x80, 0xe2, 0x0b, 0xec, 0xb3, 0x5d, 0xf5, 0x52, 0x72, 0xc3, + 0xd1, 0xd9, 0x45, 0xb8, 0xb3, 0x2b, 0xab, 0x7f, 0xd6, 0x51, 0x3b, 0xf3, 0x67, 0xb8, 0xba, 0xd6, + 0x25, 0x14, 0xb5, 0x1f, 0xfe, 0x17, 0x81, 0xc9, 0xe7, 0xcc, 0x8b, 0x57, 0x90, 0x1b, 0xf3, 0x0b, + 0x98, 0xdb, 0x72, 0xfb, 0xf4, 0xc2, 0xfd, 0x73, 0x13, 0xe6, 0x1d, 0x44, 0xfb, 0xbd, 0x0b, 0x1b, + 0xda, 0x80, 0x6b, 0xbc, 0x38, 0xb7, 0xb0, 0x7f, 0x91, 0xe4, 0x35, 0x1d, 0xd9, 0x0f, 0xa4, 0x19, + 0x55, 0xe2, 0x9f, 0x43, 0x55, 0xb5, 0x0b, 0x14, 0x97, 0xf9, 0xf2, 0xa4, 0x32, 0x6f, 0x07, 0x3b, + 0xc4, 0x39, 0x56, 0x31, 0x5f, 0x6b, 0x70, 0x7d, 0x2d, 0x99, 0xc9, 0x17, 0xe5, 0x28, 0xdb, 0x30, + 0x1f, 0xba, 0x11, 0x0a, 0xd8, 0x76, 0x8a, 0x17, 0xc8, 0xe7, 0x6b, 0xf1, 0xfe, 0xff, 0xe7, 0x51, + 0x63, 0x25, 0xc5, 0xb6, 0x48, 0x88, 0x82, 0x44, 0x9d, 0xda, 0x1d, 0x72, 0xd3, 0xc7, 0x1d, 0x44, + 0x99, 0xb5, 0x2e, 0xfe, 0x73, 0xe6, 0xa4, 0xb1, 0xb5, 0x53, 0x39, 0x43, 0x7e, 0x1a, 0xce, 0xf0, + 0x1d, 0x2c, 0x0e, 0xdf, 0x2e, 0x01, 0xae, 0x76, 0xcc, 0x04, 0x4f, 0xed, 0x90, 0x23, 0xe4, 0x25, + 0xad, 0x60, 0xfe, 0x04, 0xf3, 0x5f, 0x87, 0xfe, 0x5b, 0xe0, 0x75, 0x2d, 0xa8, 0x46, 0x88, 0x92, + 0x7e, 0xe4, 0x21, 0x2a, 0xb0, 0x1a, 0x77, 0xa9, 0x63, 0x31, 0x73, 0x05, 0xae, 0x3e, 0x90, 0x04, + 0x38, 0xf6, 0x5c, 0x87, 0xb2, 0x9c, 0x04, 0xf2, 0x2a, 0x55, 0x27, 0xde, 0xf2, 0xe4, 0x4b, 0x64, + 0x93, 0xb9, 0x50, 0x56, 0xfc, 0x59, 0xdd, 0xbb, 0x7e, 0x0a, 0x97, 0x14, 0x02, 0x4e, 0x2c, 0x68, + 0xee, 0x40, 0xed, 0x5b, 0x17, 0x5f, 0xfe, 0xec, 0x8c, 0x60, 0x46, 0xfa, 0x51, 0xb1, 0x0e, 0xf1, + 0x10, 0x6d, 0x32, 0x0f, 0xc9, 0x9d, 0x87, 0x87, 0xb4, 0x5e, 0xcf, 0x40, 0x51, 0x4c, 0x4e, 0x7d, + 0x0f, 0x4a, 0x92, 0x63, 0xea, 0xb6, 0x35, 0xe9, 0x17, 0x93, 0x35, 0xc2, 0xe9, 0x8d, 0x8f, 0xa7, + 0x57, 0x50, 0x57, 0xfb, 0x01, 0x8a, 0x82, 0x0b, 0xea, 0x2b, 0x93, 0x55, 0xd3, 0xcc, 0xd4, 0xf8, + 0x70, 0x2a, 0x59, 0xe5, 0xa1, 0x03, 0x25, 0x49, 0xb0, 0xb2, 0xae, 0x33, 0x42, 0x38, 0x8d, 0x8f, + 0xa6, 0x51, 0x48, 0x1c, 0x3d, 0x87, 0xd9, 0x13, 0x4c, 0x4e, 0x6f, 0x4d, 0xa3, 0x7e, 0x72, 0xa0, + 0x9f, 0xd1, 0xe5, 0x53, 0xc8, 0x6f, 0x22, 0xa6, 0x37, 0x27, 0x2b, 0x1d, 0xd3, 0x3d, 0xe3, 0x83, + 0x29, 0x24, 0x13, 0xdc, 0x0a, 0xbc, 0xd3, 0xea, 0xd6, 0x64, 0x95, 0x61, 0x76, 0x66, 0xd8, 0x53, + 0xcb, 0x2b, 0x47, 0x6d, 0x28, 0x70, 0xb2, 0xa5, 0x67, 0xc4, 0x96, 0x22, 0x64, 0xc6, 0xe2, 0x48, + 0x72, 0x6f, 0xf0, 0x1f, 0xeb, 0xfa, 0x16, 0x14, 0x78, 0x29, 0xe9, 0x19, 0x79, 0x38, 0x4a, 0xa4, + 0xc6, 0x5a, 0x7c, 0x0c, 0xd5, 0x84, 0x63, 0x64, 0x41, 0x31, 0x4c, 0x46, 0xc6, 0x1a, 0x7d, 0x08, + 0x65, 0xc5, 0x0e, 0xf4, 0x8c, 0xf7, 0x3e, 0x49, 0x22, 0x26, 0x18, 0x2c, 0x8a, 0x69, 0x9f, 0x15, + 0xe1, 0x30, 0x25, 0x18, 0x6b, 0xf0, 0x11, 0x94, 0xe4, 0xd8, 0xcf, 0x2a, 0x9a, 0x11, 0x72, 0x30, + 0xd6, 0x24, 0x86, 0x4a, 0x3c, 0xb9, 0xf5, 0x9b, 0xd9, 0x39, 0x92, 0x22, 0x0a, 0x86, 0x35, 0xad, + 0xb8, 0xca, 0xa8, 0x17, 0x00, 0xa9, 0x79, 0x79, 0x3b, 0x03, 0xe2, 0xd3, 0x26, 0xbf, 0xf1, 0xc9, + 0xd9, 0x94, 0x94, 0xe3, 0x47, 0x50, 0x92, 0x03, 0x31, 0x0b, 0xb6, 0x91, 0xb1, 0x39, 0x16, 0xb6, + 0x1d, 0x28, 0xab, 0xd1, 0x95, 0x95, 0x2b, 0x27, 0xa7, 0xa1, 0x71, 0x73, 0x4a, 0x69, 0x15, 0xfa, + 0xf7, 0x50, 0xe0, 0x33, 0x27, 0xab, 0x0a, 0x53, 0xf3, 0xcf, 0x58, 0x99, 0x46, 0x54, 0x9a, 0x5f, + 0xfd, 0xe6, 0xf0, 0xcd, 0xd2, 0x95, 0x3f, 0xde, 0x2c, 0x5d, 0xf9, 0x65, 0xb0, 0xa4, 0x1d, 0x0e, + 0x96, 0xb4, 0xdf, 0x07, 0x4b, 0xda, 0xdf, 0x83, 0x25, 0xed, 0xe9, 0xbd, 0xf3, 0xfd, 0x65, 0xef, + 0xae, 0x58, 0x3c, 0x2b, 0x09, 0xb8, 0x6e, 0xff, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x67, 0xc5, 0x63, + 0x32, 0x20, 0x14, 0x00, 0x00, } diff --git a/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks.proto b/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks.proto index 8fb5e8032d590..eb373185ebabc 100644 --- a/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks.proto +++ b/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks.proto @@ -49,6 +49,8 @@ service Tasks { rpc Update(UpdateTaskRequest) returns (google.protobuf.Empty); rpc Metrics(MetricsRequest) returns (MetricsResponse); + + rpc Wait(WaitRequest) returns (WaitResponse); } message CreateTaskRequest { @@ -168,8 +170,9 @@ message ListPidsRequest { string container_id = 1; } -message ListPidsResponse{ - repeated uint32 pids = 1; +message ListPidsResponse { + // Processes includes the process ID and additional process information + repeated containerd.v1.types.ProcessInfo processes = 1; } message CheckpointTaskRequest { @@ -194,3 +197,13 @@ message MetricsRequest { message MetricsResponse { repeated types.Metric metrics = 1; } + +message WaitRequest { + string container_id = 1; + string exec_id = 2; +} + +message WaitResponse { + uint32 exit_status = 1; + google.protobuf.Timestamp exited_at = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; +} diff --git a/vendor/github.com/containerd/containerd/api/types/descriptor.pb.go b/vendor/github.com/containerd/containerd/api/types/descriptor.pb.go index e1db00bec17c3..785d0507071be 100644 --- a/vendor/github.com/containerd/containerd/api/types/descriptor.pb.go +++ b/vendor/github.com/containerd/containerd/api/types/descriptor.pb.go @@ -9,11 +9,13 @@ github.com/containerd/containerd/api/types/descriptor.proto github.com/containerd/containerd/api/types/metrics.proto github.com/containerd/containerd/api/types/mount.proto + github.com/containerd/containerd/api/types/platform.proto It has these top-level messages: Descriptor Metric Mount + Platform */ package types diff --git a/vendor/github.com/containerd/containerd/api/types/platform.pb.go b/vendor/github.com/containerd/containerd/api/types/platform.pb.go new file mode 100644 index 0000000000000..0ca2afc2596cc --- /dev/null +++ b/vendor/github.com/containerd/containerd/api/types/platform.pb.go @@ -0,0 +1,412 @@ +// Code generated by protoc-gen-gogo. +// source: github.com/containerd/containerd/api/types/platform.proto +// DO NOT EDIT! + +package types + +import proto "github.com/gogo/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "github.com/gogo/protobuf/gogoproto" + +import strings "strings" +import reflect "reflect" + +import io "io" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// Platform follows the structure of the OCI platform specification, from +// descriptors. +type Platform struct { + OS string `protobuf:"bytes,1,opt,name=os,proto3" json:"os,omitempty"` + Architecture string `protobuf:"bytes,2,opt,name=architecture,proto3" json:"architecture,omitempty"` + Variant string `protobuf:"bytes,3,opt,name=variant,proto3" json:"variant,omitempty"` +} + +func (m *Platform) Reset() { *m = Platform{} } +func (*Platform) ProtoMessage() {} +func (*Platform) Descriptor() ([]byte, []int) { return fileDescriptorPlatform, []int{0} } + +func init() { + proto.RegisterType((*Platform)(nil), "containerd.types.Platform") +} +func (m *Platform) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Platform) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.OS) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintPlatform(dAtA, i, uint64(len(m.OS))) + i += copy(dAtA[i:], m.OS) + } + if len(m.Architecture) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintPlatform(dAtA, i, uint64(len(m.Architecture))) + i += copy(dAtA[i:], m.Architecture) + } + if len(m.Variant) > 0 { + dAtA[i] = 0x1a + i++ + i = encodeVarintPlatform(dAtA, i, uint64(len(m.Variant))) + i += copy(dAtA[i:], m.Variant) + } + return i, nil +} + +func encodeFixed64Platform(dAtA []byte, offset int, v uint64) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) + dAtA[offset+4] = uint8(v >> 32) + dAtA[offset+5] = uint8(v >> 40) + dAtA[offset+6] = uint8(v >> 48) + dAtA[offset+7] = uint8(v >> 56) + return offset + 8 +} +func encodeFixed32Platform(dAtA []byte, offset int, v uint32) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) + return offset + 4 +} +func encodeVarintPlatform(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *Platform) Size() (n int) { + var l int + _ = l + l = len(m.OS) + if l > 0 { + n += 1 + l + sovPlatform(uint64(l)) + } + l = len(m.Architecture) + if l > 0 { + n += 1 + l + sovPlatform(uint64(l)) + } + l = len(m.Variant) + if l > 0 { + n += 1 + l + sovPlatform(uint64(l)) + } + return n +} + +func sovPlatform(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozPlatform(x uint64) (n int) { + return sovPlatform(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *Platform) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&Platform{`, + `OS:` + fmt.Sprintf("%v", this.OS) + `,`, + `Architecture:` + fmt.Sprintf("%v", this.Architecture) + `,`, + `Variant:` + fmt.Sprintf("%v", this.Variant) + `,`, + `}`, + }, "") + return s +} +func valueToStringPlatform(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *Platform) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlatform + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Platform: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Platform: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OS", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlatform + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPlatform + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OS = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Architecture", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlatform + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPlatform + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Architecture = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Variant", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlatform + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPlatform + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Variant = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPlatform(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPlatform + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipPlatform(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPlatform + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPlatform + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPlatform + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthPlatform + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPlatform + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipPlatform(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthPlatform = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowPlatform = fmt.Errorf("proto: integer overflow") +) + +func init() { + proto.RegisterFile("github.com/containerd/containerd/api/types/platform.proto", fileDescriptorPlatform) +} + +var fileDescriptorPlatform = []byte{ + // 203 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xb2, 0x4c, 0xcf, 0x2c, 0xc9, + 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0xcf, 0x2b, 0x49, 0xcc, 0xcc, 0x4b, 0x2d, + 0x4a, 0x41, 0x66, 0x26, 0x16, 0x64, 0xea, 0x97, 0x54, 0x16, 0xa4, 0x16, 0xeb, 0x17, 0xe4, 0x24, + 0x96, 0xa4, 0xe5, 0x17, 0xe5, 0xea, 0x15, 0x14, 0xe5, 0x97, 0xe4, 0x0b, 0x09, 0x20, 0x14, 0xe9, + 0x81, 0x15, 0x48, 0x89, 0xa4, 0xe7, 0xa7, 0xe7, 0x83, 0x25, 0xf5, 0x41, 0x2c, 0x88, 0x3a, 0xa5, + 0x04, 0x2e, 0x8e, 0x00, 0xa8, 0x4e, 0x21, 0x31, 0x2e, 0xa6, 0xfc, 0x62, 0x09, 0x46, 0x05, 0x46, + 0x0d, 0x4e, 0x27, 0xb6, 0x47, 0xf7, 0xe4, 0x99, 0xfc, 0x83, 0x83, 0x98, 0xf2, 0x8b, 0x85, 0x94, + 0xb8, 0x78, 0x12, 0x8b, 0x92, 0x33, 0x32, 0x4b, 0x52, 0x93, 0x4b, 0x4a, 0x8b, 0x52, 0x25, 0x98, + 0x40, 0x2a, 0x82, 0x50, 0xc4, 0x84, 0x24, 0xb8, 0xd8, 0xcb, 0x12, 0x8b, 0x32, 0x13, 0xf3, 0x4a, + 0x24, 0x98, 0xc1, 0xd2, 0x30, 0xae, 0x93, 0xd7, 0x89, 0x87, 0x72, 0x0c, 0x37, 0x1e, 0xca, 0x31, + 0x34, 0x3c, 0x92, 0x63, 0x3c, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, + 0x18, 0xa3, 0x0c, 0x88, 0xf7, 0x9e, 0x35, 0x98, 0x4c, 0x62, 0x03, 0x3b, 0xda, 0x18, 0x10, 0x00, + 0x00, 0xff, 0xff, 0x97, 0xa1, 0x99, 0x56, 0x19, 0x01, 0x00, 0x00, +} diff --git a/vendor/github.com/containerd/containerd/api/types/platform.proto b/vendor/github.com/containerd/containerd/api/types/platform.proto new file mode 100644 index 0000000000000..b1dce06233fb9 --- /dev/null +++ b/vendor/github.com/containerd/containerd/api/types/platform.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +package containerd.types; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/containerd/containerd/api/types;types"; + +// Platform follows the structure of the OCI platform specification, from +// descriptors. +message Platform { + string os = 1 [(gogoproto.customname) = "OS"]; + string architecture = 2; + string variant = 3; +} diff --git a/vendor/github.com/containerd/containerd/api/types/task/task.pb.go b/vendor/github.com/containerd/containerd/api/types/task/task.pb.go index d84f3e510ac1f..ccc230ae73456 100644 --- a/vendor/github.com/containerd/containerd/api/types/task/task.pb.go +++ b/vendor/github.com/containerd/containerd/api/types/task/task.pb.go @@ -10,6 +10,7 @@ It has these top-level messages: Process + ProcessInfo */ package task @@ -18,6 +19,7 @@ import fmt "fmt" import math "math" import _ "github.com/gogo/protobuf/gogoproto" import _ "github.com/gogo/protobuf/types" +import google_protobuf2 "github.com/gogo/protobuf/types" import time "time" @@ -90,8 +92,22 @@ func (m *Process) Reset() { *m = Process{} } func (*Process) ProtoMessage() {} func (*Process) Descriptor() ([]byte, []int) { return fileDescriptorTask, []int{0} } +type ProcessInfo struct { + // PID is the process ID. + Pid uint32 `protobuf:"varint,1,opt,name=pid,proto3" json:"pid,omitempty"` + // Info contains additional process information. + // + // Info varies by platform. + Info *google_protobuf2.Any `protobuf:"bytes,2,opt,name=info" json:"info,omitempty"` +} + +func (m *ProcessInfo) Reset() { *m = ProcessInfo{} } +func (*ProcessInfo) ProtoMessage() {} +func (*ProcessInfo) Descriptor() ([]byte, []int) { return fileDescriptorTask, []int{1} } + func init() { proto.RegisterType((*Process)(nil), "containerd.v1.types.Process") + proto.RegisterType((*ProcessInfo)(nil), "containerd.v1.types.ProcessInfo") proto.RegisterEnum("containerd.v1.types.Status", Status_name, Status_value) } func (m *Process) Marshal() (dAtA []byte, err error) { @@ -175,6 +191,39 @@ func (m *Process) MarshalTo(dAtA []byte) (int, error) { return i, nil } +func (m *ProcessInfo) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ProcessInfo) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Pid != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintTask(dAtA, i, uint64(m.Pid)) + } + if m.Info != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintTask(dAtA, i, uint64(m.Info.Size())) + n2, err := m.Info.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n2 + } + return i, nil +} + func encodeFixed64Task(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) dAtA[offset+1] = uint8(v >> 8) @@ -242,6 +291,19 @@ func (m *Process) Size() (n int) { return n } +func (m *ProcessInfo) Size() (n int) { + var l int + _ = l + if m.Pid != 0 { + n += 1 + sovTask(uint64(m.Pid)) + } + if m.Info != nil { + l = m.Info.Size() + n += 1 + l + sovTask(uint64(l)) + } + return n +} + func sovTask(x uint64) (n int) { for { n++ @@ -274,6 +336,17 @@ func (this *Process) String() string { }, "") return s } +func (this *ProcessInfo) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ProcessInfo{`, + `Pid:` + fmt.Sprintf("%v", this.Pid) + `,`, + `Info:` + strings.Replace(fmt.Sprintf("%v", this.Info), "Any", "google_protobuf2.Any", 1) + `,`, + `}`, + }, "") + return s +} func valueToStringTask(v interface{}) string { rv := reflect.ValueOf(v) if rv.IsNil() { @@ -584,6 +657,108 @@ func (m *Process) Unmarshal(dAtA []byte) error { } return nil } +func (m *ProcessInfo) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTask + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ProcessInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ProcessInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Pid", wireType) + } + m.Pid = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTask + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Pid |= (uint32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Info", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTask + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTask + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Info == nil { + m.Info = &google_protobuf2.Any{} + } + if err := m.Info.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTask(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTask + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipTask(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 @@ -694,37 +869,39 @@ func init() { } var fileDescriptorTask = []byte{ - // 503 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0x3d, 0x6f, 0xd3, 0x40, - 0x1c, 0xc6, 0x73, 0x6e, 0xe3, 0x24, 0x97, 0xb6, 0x98, 0xa3, 0xaa, 0x2c, 0x83, 0x6c, 0x8b, 0x29, - 0x62, 0xb0, 0x45, 0xba, 0xb1, 0xe5, 0x4d, 0x28, 0x42, 0x72, 0xa3, 0x4b, 0x22, 0xc6, 0xc8, 0xc9, - 0x1d, 0xe6, 0xd4, 0xe6, 0xce, 0xb2, 0xcf, 0xbc, 0x6c, 0x8c, 0xa8, 0x13, 0x5f, 0xa0, 0x13, 0x7c, - 0x0a, 0x3e, 0x41, 0x46, 0x26, 0xc4, 0x14, 0xa8, 0x3f, 0x09, 0x3a, 0xdb, 0x09, 0x19, 0x58, 0xac, - 0x7b, 0x9e, 0xdf, 0x73, 0x8f, 0xff, 0xf7, 0x87, 0x2f, 0x22, 0x26, 0xdf, 0x66, 0x4b, 0x6f, 0x25, - 0xd6, 0xfe, 0x4a, 0x70, 0x19, 0x32, 0x4e, 0x13, 0x72, 0x78, 0x0c, 0x63, 0xe6, 0xcb, 0x8f, 0x31, - 0x4d, 0x7d, 0x19, 0xa6, 0xd7, 0xc5, 0xc7, 0x8b, 0x13, 0x21, 0x05, 0x7a, 0xf4, 0x2f, 0xe5, 0xbd, - 0x7b, 0xee, 0x15, 0x21, 0xeb, 0x3c, 0x12, 0x91, 0x28, 0xb8, 0xaf, 0x4e, 0x65, 0xd4, 0x72, 0x22, - 0x21, 0xa2, 0x1b, 0xea, 0x17, 0x6a, 0x99, 0xbd, 0xf1, 0x25, 0x5b, 0xd3, 0x54, 0x86, 0xeb, 0xb8, - 0x0c, 0x3c, 0xcd, 0x35, 0xd8, 0x98, 0x24, 0x62, 0x45, 0xd3, 0x14, 0x75, 0xe1, 0xc9, 0xbe, 0x79, - 0xc1, 0x88, 0x09, 0x5c, 0xd0, 0x69, 0xf5, 0x1f, 0xe4, 0x5b, 0xa7, 0x3d, 0xd8, 0xf9, 0xe3, 0x21, - 0x6e, 0xef, 0x43, 0x63, 0x82, 0x2e, 0xa0, 0xc6, 0x88, 0xa9, 0x15, 0x49, 0x3d, 0xdf, 0x3a, 0xda, - 0x78, 0x88, 0x35, 0x46, 0x90, 0x01, 0x8f, 0x62, 0x46, 0xcc, 0x23, 0x17, 0x74, 0x4e, 0xb1, 0x3a, - 0xa2, 0x4b, 0xa8, 0xa7, 0x32, 0x94, 0x59, 0x6a, 0x1e, 0xbb, 0xa0, 0x73, 0xd6, 0x7d, 0xec, 0xfd, - 0xe7, 0x19, 0xde, 0xb4, 0x88, 0xe0, 0x2a, 0x8a, 0xce, 0x61, 0x3d, 0x95, 0x84, 0x71, 0xb3, 0xae, - 0xfe, 0x80, 0x4b, 0x81, 0x2e, 0x54, 0x15, 0x11, 0x99, 0x34, 0xf5, 0xc2, 0xae, 0x54, 0xe5, 0xd3, - 0x24, 0x31, 0x1b, 0x7b, 0x9f, 0x26, 0x09, 0xb2, 0x60, 0x53, 0xd2, 0x64, 0xcd, 0x78, 0x78, 0x63, - 0x36, 0x5d, 0xd0, 0x69, 0xe2, 0xbd, 0x46, 0x0e, 0x6c, 0xd3, 0x0f, 0x4c, 0x2e, 0xaa, 0xd9, 0x5a, - 0xc5, 0xc0, 0x50, 0x59, 0xe5, 0x28, 0xa8, 0x07, 0x5b, 0x4a, 0x51, 0xb2, 0x08, 0xa5, 0x09, 0x5d, - 0xd0, 0x69, 0x77, 0x2d, 0xaf, 0x5c, 0xab, 0xb7, 0x5b, 0xab, 0x37, 0xdb, 0xad, 0xb5, 0xdf, 0xdc, - 0x6c, 0x9d, 0xda, 0x97, 0xdf, 0x0e, 0xc0, 0xcd, 0xf2, 0x5a, 0x4f, 0x3e, 0xfb, 0x09, 0xa0, 0x5e, - 0xb5, 0xd9, 0xb0, 0x31, 0x0f, 0x5e, 0x05, 0x57, 0xaf, 0x03, 0xa3, 0x66, 0x3d, 0xbc, 0xbd, 0x73, - 0x4f, 0x4b, 0x30, 0xe7, 0xd7, 0x5c, 0xbc, 0xe7, 0x8a, 0x0f, 0xf0, 0xa8, 0x37, 0x1b, 0x0d, 0x0d, - 0x70, 0xc8, 0x07, 0x09, 0x0d, 0x25, 0x25, 0x8a, 0xe3, 0x79, 0x10, 0x8c, 0x83, 0x97, 0x86, 0x76, - 0xc8, 0x71, 0xc6, 0x39, 0xe3, 0x91, 0xe2, 0xd3, 0xd9, 0xd5, 0x64, 0x32, 0x1a, 0x1a, 0x47, 0x87, - 0x7c, 0x2a, 0x45, 0x1c, 0x53, 0x82, 0x9e, 0x40, 0x7d, 0xd2, 0x9b, 0x4f, 0x47, 0x43, 0xe3, 0xd8, - 0x32, 0x6e, 0xef, 0xdc, 0x93, 0x12, 0x4f, 0xc2, 0x2c, 0x2d, 0xdb, 0x15, 0x55, 0xed, 0xf5, 0xc3, - 0xdb, 0x0a, 0x33, 0x1e, 0x59, 0x67, 0x9f, 0xbf, 0xda, 0xb5, 0xef, 0xdf, 0xec, 0xea, 0x35, 0x7d, - 0x73, 0x73, 0x6f, 0xd7, 0x7e, 0xdd, 0xdb, 0xb5, 0x4f, 0xb9, 0x0d, 0x36, 0xb9, 0x0d, 0x7e, 0xe4, - 0x36, 0xf8, 0x93, 0xdb, 0x60, 0xa9, 0x17, 0xab, 0xb9, 0xfc, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x14, - 0xf3, 0xee, 0x85, 0xe8, 0x02, 0x00, 0x00, + // 543 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0xcf, 0x6e, 0xd3, 0x4c, + 0x14, 0xc5, 0x33, 0x6e, 0xe3, 0x24, 0xe3, 0xb6, 0x9f, 0x3f, 0x13, 0x55, 0xc6, 0x20, 0xdb, 0xea, + 0xca, 0x62, 0x61, 0x8b, 0x74, 0xc7, 0x2e, 0xff, 0x84, 0x2c, 0x24, 0x37, 0x72, 0x12, 0xb1, 0x8c, + 0x9c, 0x78, 0x62, 0x46, 0x6d, 0x66, 0x2c, 0x7b, 0x0c, 0x64, 0xc7, 0x12, 0x75, 0xc5, 0x0b, 0x74, + 0x05, 0x4f, 0xc1, 0x13, 0x64, 0xc9, 0x0a, 0xb1, 0x0a, 0xd4, 0x4f, 0x82, 0xc6, 0x76, 0xd2, 0x08, + 0xd8, 0x8c, 0xee, 0x3d, 0xbf, 0x33, 0x77, 0xee, 0x1c, 0xf8, 0x22, 0xc2, 0xec, 0x4d, 0x36, 0xb7, + 0x17, 0x74, 0xe5, 0x2c, 0x28, 0x61, 0x01, 0x26, 0x28, 0x09, 0x0f, 0xcb, 0x20, 0xc6, 0x0e, 0x5b, + 0xc7, 0x28, 0x75, 0x58, 0x90, 0x5e, 0x17, 0x87, 0x1d, 0x27, 0x94, 0x51, 0xe5, 0xd1, 0x83, 0xcb, + 0x7e, 0xfb, 0xdc, 0x2e, 0x4c, 0x5a, 0x3b, 0xa2, 0x11, 0x2d, 0xb8, 0xc3, 0xab, 0xd2, 0xaa, 0x19, + 0x11, 0xa5, 0xd1, 0x0d, 0x72, 0x8a, 0x6e, 0x9e, 0x2d, 0x1d, 0x86, 0x57, 0x28, 0x65, 0xc1, 0x2a, + 0xae, 0x0c, 0x8f, 0xff, 0x34, 0x04, 0x64, 0x5d, 0xa2, 0x8b, 0x5c, 0x80, 0x8d, 0x51, 0x42, 0x17, + 0x28, 0x4d, 0x95, 0x0e, 0x3c, 0xd9, 0x3f, 0x3a, 0xc3, 0xa1, 0x0a, 0x4c, 0x60, 0xb5, 0x7a, 0xff, + 0xe5, 0x5b, 0x43, 0xea, 0xef, 0x74, 0x77, 0xe0, 0x4b, 0x7b, 0x93, 0x1b, 0x2a, 0xe7, 0x50, 0xc0, + 0xa1, 0x2a, 0x14, 0x4e, 0x31, 0xdf, 0x1a, 0x82, 0x3b, 0xf0, 0x05, 0x1c, 0x2a, 0x32, 0x3c, 0x8a, + 0x71, 0xa8, 0x1e, 0x99, 0xc0, 0x3a, 0xf5, 0x79, 0xa9, 0x5c, 0x42, 0x31, 0x65, 0x01, 0xcb, 0x52, + 0xf5, 0xd8, 0x04, 0xd6, 0x59, 0xe7, 0x89, 0xfd, 0x8f, 0x1f, 0xda, 0xe3, 0xc2, 0xe2, 0x57, 0x56, + 0xa5, 0x0d, 0xeb, 0x29, 0x0b, 0x31, 0x51, 0xeb, 0xfc, 0x05, 0xbf, 0x6c, 0x94, 0x73, 0x3e, 0x2a, + 0xa4, 0x19, 0x53, 0xc5, 0x42, 0xae, 0xba, 0x4a, 0x47, 0x49, 0xa2, 0x36, 0xf6, 0x3a, 0x4a, 0x12, + 0x45, 0x83, 0x4d, 0x86, 0x92, 0x15, 0x26, 0xc1, 0x8d, 0xda, 0x34, 0x81, 0xd5, 0xf4, 0xf7, 0xbd, + 0x62, 0x40, 0x09, 0xbd, 0xc7, 0x6c, 0x56, 0xed, 0xd6, 0x2a, 0x16, 0x86, 0x5c, 0x2a, 0x57, 0x51, + 0xba, 0xb0, 0xc5, 0x3b, 0x14, 0xce, 0x02, 0xa6, 0x42, 0x13, 0x58, 0x52, 0x47, 0xb3, 0xcb, 0x40, + 0xed, 0x5d, 0xa0, 0xf6, 0x64, 0x97, 0x78, 0xaf, 0xb9, 0xd9, 0x1a, 0xb5, 0x4f, 0x3f, 0x0d, 0xe0, + 0x37, 0xcb, 0x6b, 0x5d, 0x76, 0xe1, 0x42, 0xa9, 0xca, 0xd8, 0x25, 0x4b, 0xba, 0xcb, 0x06, 0x3c, + 0x64, 0x63, 0xc1, 0x63, 0x4c, 0x96, 0xb4, 0xc8, 0x51, 0xea, 0xb4, 0xff, 0x1a, 0xdf, 0x25, 0x6b, + 0xbf, 0x70, 0x3c, 0xfb, 0x0e, 0xa0, 0x58, 0x2d, 0xa6, 0xc3, 0xc6, 0xd4, 0x7b, 0xe5, 0x5d, 0xbd, + 0xf6, 0xe4, 0x9a, 0xf6, 0xff, 0xed, 0x9d, 0x79, 0x5a, 0x82, 0x29, 0xb9, 0x26, 0xf4, 0x1d, 0xe1, + 0xbc, 0xef, 0x0f, 0xbb, 0x93, 0xe1, 0x40, 0x06, 0x87, 0xbc, 0x9f, 0xa0, 0x80, 0xa1, 0x90, 0x73, + 0x7f, 0xea, 0x79, 0xae, 0xf7, 0x52, 0x16, 0x0e, 0xb9, 0x9f, 0x11, 0x82, 0x49, 0xc4, 0xf9, 0x78, + 0x72, 0x35, 0x1a, 0x0d, 0x07, 0xf2, 0xd1, 0x21, 0x1f, 0x33, 0x1a, 0xc7, 0x28, 0x54, 0x9e, 0x42, + 0x71, 0xd4, 0x9d, 0x8e, 0x87, 0x03, 0xf9, 0x58, 0x93, 0x6f, 0xef, 0xcc, 0x93, 0x12, 0x8f, 0x82, + 0x2c, 0x2d, 0xa7, 0x73, 0xca, 0xa7, 0xd7, 0x0f, 0x6f, 0x73, 0x8c, 0x49, 0xa4, 0x9d, 0x7d, 0xfc, + 0xac, 0xd7, 0xbe, 0x7e, 0xd1, 0xab, 0xdf, 0xf4, 0xd4, 0xcd, 0xbd, 0x5e, 0xfb, 0x71, 0xaf, 0xd7, + 0x3e, 0xe4, 0x3a, 0xd8, 0xe4, 0x3a, 0xf8, 0x96, 0xeb, 0xe0, 0x57, 0xae, 0x83, 0xb9, 0x58, 0xc4, + 0x70, 0xf9, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x19, 0xf7, 0x5b, 0x8f, 0x4e, 0x03, 0x00, 0x00, } diff --git a/vendor/github.com/containerd/containerd/api/types/task/task.proto b/vendor/github.com/containerd/containerd/api/types/task/task.proto index 4833d12a535ed..5845edf292e8c 100644 --- a/vendor/github.com/containerd/containerd/api/types/task/task.proto +++ b/vendor/github.com/containerd/containerd/api/types/task/task.proto @@ -4,6 +4,7 @@ package containerd.v1.types; import "gogoproto/gogo.proto"; import "google/protobuf/timestamp.proto"; +import "google/protobuf/any.proto"; enum Status { option (gogoproto.goproto_enum_prefix) = false; @@ -29,3 +30,12 @@ message Process { uint32 exit_status = 9; google.protobuf.Timestamp exited_at = 10 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; } + +message ProcessInfo { + // PID is the process ID. + uint32 pid = 1; + // Info contains additional process information. + // + // Info varies by platform. + google.protobuf.Any info = 2; +} diff --git a/vendor/github.com/containerd/containerd/archive/tar.go b/vendor/github.com/containerd/containerd/archive/tar.go index 47111b027f5ac..0550f218cd4c3 100644 --- a/vendor/github.com/containerd/containerd/archive/tar.go +++ b/vendor/github.com/containerd/containerd/archive/tar.go @@ -88,8 +88,6 @@ const ( // See https://github.com/opencontainers/image-spec/blob/master/layer.md#applying-changesets func Apply(ctx context.Context, root string, r io.Reader) (int64, error) { root = filepath.Clean(root) - fn := prepareApply() - defer fn() var ( tr = tar.NewReader(r) @@ -107,6 +105,12 @@ func Apply(ctx context.Context, root string, r io.Reader) (int64, error) { // Iterate through the files in the archive. for { + select { + case <-ctx.Done(): + return 0, ctx.Err() + default: + } + hdr, err := tr.Next() if err == io.EOF { // end of tar archive @@ -445,19 +449,18 @@ func createTarFile(ctx context.Context, path, extractDir string, hdr *tar.Header // Create directory unless it exists as a directory already. // In that case we just want to merge the two if fi, err := os.Lstat(path); !(err == nil && fi.IsDir()) { - if err := os.Mkdir(path, hdrInfo.Mode()); err != nil { + if err := mkdir(path, hdrInfo.Mode()); err != nil { return err } } case tar.TypeReg, tar.TypeRegA: - file, err := openFile(path, os.O_CREATE|os.O_WRONLY, hdrInfo.Mode()) + file, err := openFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, hdrInfo.Mode()) if err != nil { return err } - buf := bufferPool.Get().([]byte) - _, err = io.CopyBuffer(file, reader, buf) - bufferPool.Put(buf) + + _, err = copyBuffered(ctx, file, reader) if err1 := file.Close(); err == nil { err = err1 } @@ -522,9 +525,43 @@ func createTarFile(ctx context.Context, path, extractDir string, hdr *tar.Header return err } - if err := chtimes(path, boundTime(latestTime(hdr.AccessTime, hdr.ModTime)), boundTime(hdr.ModTime)); err != nil { - return err + return chtimes(path, boundTime(latestTime(hdr.AccessTime, hdr.ModTime)), boundTime(hdr.ModTime)) +} + +func copyBuffered(ctx context.Context, dst io.Writer, src io.Reader) (written int64, err error) { + buf := bufferPool.Get().([]byte) + defer bufferPool.Put(buf) + + for { + select { + case <-ctx.Done(): + err = ctx.Err() + return + default: + } + + nr, er := src.Read(buf) + if nr > 0 { + nw, ew := dst.Write(buf[0:nr]) + if nw > 0 { + written += int64(nw) + } + if ew != nil { + err = ew + break + } + if nr != nw { + err = io.ErrShortWrite + break + } + } + if er != nil { + if er != io.EOF { + err = er + } + break + } } + return written, err - return nil } diff --git a/vendor/github.com/containerd/containerd/archive/tar_unix.go b/vendor/github.com/containerd/containerd/archive/tar_unix.go index 75bc15b6b75ce..44b1069432f86 100644 --- a/vendor/github.com/containerd/containerd/archive/tar_unix.go +++ b/vendor/github.com/containerd/containerd/archive/tar_unix.go @@ -31,44 +31,40 @@ func setHeaderForSpecialDevice(hdr *tar.Header, name string, fi os.FileInfo) err // Currently go does not fill in the major/minors if s.Mode&syscall.S_IFBLK != 0 || s.Mode&syscall.S_IFCHR != 0 { - hdr.Devmajor = int64(major(uint64(s.Rdev))) - hdr.Devminor = int64(minor(uint64(s.Rdev))) + hdr.Devmajor = int64(unix.Major(uint64(s.Rdev))) + hdr.Devminor = int64(unix.Minor(uint64(s.Rdev))) } return nil } -func major(device uint64) uint64 { - return (device >> 8) & 0xfff -} - -func minor(device uint64) uint64 { - return (device & 0xff) | ((device >> 12) & 0xfff00) -} - -func mkdev(major int64, minor int64) uint32 { - return uint32(((minor & 0xfff00) << 12) | ((major & 0xfff) << 8) | (minor & 0xff)) -} - func open(p string) (*os.File, error) { return os.Open(p) } func openFile(name string, flag int, perm os.FileMode) (*os.File, error) { - return os.OpenFile(name, flag, perm) + f, err := os.OpenFile(name, flag, perm) + if err != nil { + return nil, err + } + // Call chmod to avoid permission mask + if err := os.Chmod(name, perm); err != nil { + return nil, err + } + return f, err } func mkdirAll(path string, perm os.FileMode) error { return os.MkdirAll(path, perm) } -func prepareApply() func() { - // Unset unmask before doing an apply operation, - // restore unmask when complete - oldmask := unix.Umask(0) - return func() { - unix.Umask(oldmask) +func mkdir(path string, perm os.FileMode) error { + if err := os.Mkdir(path, perm); err != nil { + return err } + // Only final created directory gets explicit permission + // call to avoid permission mask + return os.Chmod(path, perm) } func skipFile(*tar.Header) bool { @@ -103,7 +99,7 @@ func handleTarTypeBlockCharFifo(hdr *tar.Header, path string) error { mode |= unix.S_IFIFO } - return unix.Mknod(path, mode, int(mkdev(hdr.Devmajor, hdr.Devminor))) + return unix.Mknod(path, mode, int(unix.Mkdev(uint32(hdr.Devmajor), uint32(hdr.Devminor)))) } func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo) error { diff --git a/vendor/github.com/containerd/containerd/archive/tar_windows.go b/vendor/github.com/containerd/containerd/archive/tar_windows.go index 4ccf605e0be7e..cb3b6c59a97f0 100644 --- a/vendor/github.com/containerd/containerd/archive/tar_windows.go +++ b/vendor/github.com/containerd/containerd/archive/tar_windows.go @@ -56,9 +56,8 @@ func mkdirAll(path string, perm os.FileMode) error { return sys.MkdirAll(path, perm) } -func prepareApply() func() { - // No umask or filesystem changes needed before apply - return func() {} +func mkdir(path string, perm os.FileMode) error { + return os.Mkdir(path, perm) } func skipFile(hdr *tar.Header) bool { diff --git a/vendor/github.com/containerd/containerd/client.go b/vendor/github.com/containerd/containerd/client.go index ddf66bc8f31b3..ad41ee57eed92 100644 --- a/vendor/github.com/containerd/containerd/client.go +++ b/vendor/github.com/containerd/containerd/client.go @@ -15,26 +15,30 @@ import ( diffapi "github.com/containerd/containerd/api/services/diff/v1" eventsapi "github.com/containerd/containerd/api/services/events/v1" imagesapi "github.com/containerd/containerd/api/services/images/v1" + introspectionapi "github.com/containerd/containerd/api/services/introspection/v1" namespacesapi "github.com/containerd/containerd/api/services/namespaces/v1" snapshotapi "github.com/containerd/containerd/api/services/snapshot/v1" "github.com/containerd/containerd/api/services/tasks/v1" versionservice "github.com/containerd/containerd/api/services/version/v1" "github.com/containerd/containerd/containers" "github.com/containerd/containerd/content" + "github.com/containerd/containerd/diff" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" + "github.com/containerd/containerd/namespaces" + "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/plugin" "github.com/containerd/containerd/reference" "github.com/containerd/containerd/remotes" "github.com/containerd/containerd/remotes/docker" "github.com/containerd/containerd/remotes/docker/schema1" contentservice "github.com/containerd/containerd/services/content" - "github.com/containerd/containerd/services/diff" diffservice "github.com/containerd/containerd/services/diff" imagesservice "github.com/containerd/containerd/services/images" + namespacesservice "github.com/containerd/containerd/services/namespaces" snapshotservice "github.com/containerd/containerd/services/snapshot" "github.com/containerd/containerd/snapshot" - "github.com/containerd/containerd/typeurl" + "github.com/containerd/typeurl" pempty "github.com/golang/protobuf/ptypes/empty" ocispec "github.com/opencontainers/image-spec/specs-go/v1" specs "github.com/opencontainers/runtime-spec/specs-go" @@ -44,12 +48,13 @@ import ( ) func init() { + const prefix = "types.containerd.io" // register TypeUrls for commonly marshaled external types major := strconv.Itoa(specs.VersionMajor) - typeurl.Register(&specs.Spec{}, "opencontainers/runtime-spec", major, "Spec") - typeurl.Register(&specs.Process{}, "opencontainers/runtime-spec", major, "Process") - typeurl.Register(&specs.LinuxResources{}, "opencontainers/runtime-spec", major, "LinuxResources") - typeurl.Register(&specs.WindowsResources{}, "opencontainers/runtime-spec", major, "WindowsResources") + typeurl.Register(&specs.Spec{}, prefix, "opencontainers/runtime-spec", major, "Spec") + typeurl.Register(&specs.Process{}, prefix, "opencontainers/runtime-spec", major, "Process") + typeurl.Register(&specs.LinuxResources{}, prefix, "opencontainers/runtime-spec", major, "LinuxResources") + typeurl.Register(&specs.WindowsResources{}, prefix, "opencontainers/runtime-spec", major, "WindowsResources") } // New returns a new containerd client that is connected to the containerd @@ -98,10 +103,8 @@ func NewWithConn(conn *grpc.ClientConn, opts ...ClientOpt) (*Client, error) { // Client is the client to interact with containerd and its various services // using a uniform interface type Client struct { - conn *grpc.ClientConn - - defaultns string - runtime string + conn *grpc.ClientConn + runtime string } // IsServing returns true if the client can successfully connect to the @@ -176,6 +179,9 @@ type RemoteContext struct { // Snapshotter used for unpacking Snapshotter string + // Labels to be applied to the created image + Labels map[string]string + // BaseHandlers are a set of handlers which get are called on dispatch. // These handlers always get called before any operation specific // handlers. @@ -197,7 +203,7 @@ func defaultRemoteContext() *RemoteContext { } // Pull downloads the provided content into containerd's content store -func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpts) (Image, error) { +func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (Image, error) { pullCtx := defaultRemoteContext() for _, o := range opts { if err := o(c, pullCtx); err != nil { @@ -224,8 +230,8 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpts) (Imag handler = images.Handlers(append(pullCtx.BaseHandlers, schema1Converter)...) } else { handler = images.Handlers(append(pullCtx.BaseHandlers, - remotes.FetchHandler(store, fetcher), - images.ChildrenHandler(store))..., + remotes.FetchHandler(store, fetcher, desc), + images.ChildrenHandler(store, platforms.Default()))..., ) } @@ -242,22 +248,28 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpts) (Imag imgrec := images.Image{ Name: name, Target: desc, + Labels: pullCtx.Labels, } is := c.ImageService() - if updated, err := is.Update(ctx, imgrec, "target"); err != nil { - if !errdefs.IsNotFound(err) { + if created, err := is.Create(ctx, imgrec); err != nil { + if !errdefs.IsAlreadyExists(err) { return nil, err } - created, err := is.Create(ctx, imgrec) + updated, err := is.Update(ctx, imgrec) if err != nil { return nil, err } - imgrec = created - } else { imgrec = updated + } else { + imgrec = created + } + + // Remove root tag from manifest now that image refers to it + if _, err := store.Update(ctx, content.Info{Digest: desc.Digest}, "labels.containerd.io/gc.root"); err != nil { + return nil, errors.Wrap(err, "failed to remove manifest root tag") } img := &image{ @@ -273,7 +285,7 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpts) (Imag } // Push uploads the provided content to a remote resource -func (c *Client) Push(ctx context.Context, ref string, desc ocispec.Descriptor, opts ...RemoteOpts) error { +func (c *Client) Push(ctx context.Context, ref string, desc ocispec.Descriptor, opts ...RemoteOpt) error { pushCtx := defaultRemoteContext() for _, o := range opts { if err := o(c, pushCtx); err != nil { @@ -296,7 +308,7 @@ func (c *Client) Push(ctx context.Context, ref string, desc ocispec.Descriptor, m.Lock() manifestStack = append(manifestStack, desc) m.Unlock() - return nil, images.StopHandler + return nil, images.ErrStopHandler default: return nil, nil } @@ -306,7 +318,7 @@ func (c *Client) Push(ctx context.Context, ref string, desc ocispec.Descriptor, pushHandler := remotes.PushHandler(cs, pusher) handlers := append(pushCtx.BaseHandlers, - images.ChildrenHandler(cs), + images.ChildrenHandler(cs, platforms.Default()), filterHandler, pushHandler, ) @@ -338,8 +350,8 @@ func (c *Client) GetImage(ctx context.Context, ref string) (Image, error) { } // ListImages returns all existing images -func (c *Client) ListImages(ctx context.Context) ([]Image, error) { - imgs, err := c.ImageService().List(ctx) +func (c *Client) ListImages(ctx context.Context, filters ...string) ([]Image, error) { + imgs, err := c.ImageService().List(ctx, filters...) if err != nil { return nil, err } @@ -404,42 +416,57 @@ func (c *Client) Close() error { return c.conn.Close() } -func (c *Client) NamespaceService() namespacesapi.NamespacesClient { - return namespacesapi.NewNamespacesClient(c.conn) +// NamespaceService returns the underlying Namespaces Store +func (c *Client) NamespaceService() namespaces.Store { + return namespacesservice.NewStoreFromClient(namespacesapi.NewNamespacesClient(c.conn)) } +// ContainerService returns the underlying container Store func (c *Client) ContainerService() containers.Store { return NewRemoteContainerStore(containersapi.NewContainersClient(c.conn)) } +// ContentStore returns the underlying content Store func (c *Client) ContentStore() content.Store { return contentservice.NewStoreFromClient(contentapi.NewContentClient(c.conn)) } +// SnapshotService returns the underlying snapshotter for the provided snapshotter name func (c *Client) SnapshotService(snapshotterName string) snapshot.Snapshotter { return snapshotservice.NewSnapshotterFromClient(snapshotapi.NewSnapshotsClient(c.conn), snapshotterName) } +// TaskService returns the underlying TasksClient func (c *Client) TaskService() tasks.TasksClient { return tasks.NewTasksClient(c.conn) } +// ImageService returns the underlying image Store func (c *Client) ImageService() images.Store { return imagesservice.NewStoreFromClient(imagesapi.NewImagesClient(c.conn)) } -func (c *Client) DiffService() diff.DiffService { +// DiffService returns the underlying Differ +func (c *Client) DiffService() diff.Differ { return diffservice.NewDiffServiceFromClient(diffapi.NewDiffClient(c.conn)) } +// IntrospectionService returns the underlying Introspection Client +func (c *Client) IntrospectionService() introspectionapi.IntrospectionClient { + return introspectionapi.NewIntrospectionClient(c.conn) +} + +// HealthService returns the underlying GRPC HealthClient func (c *Client) HealthService() grpc_health_v1.HealthClient { return grpc_health_v1.NewHealthClient(c.conn) } +// EventService returns the underlying EventsClient func (c *Client) EventService() eventsapi.EventsClient { return eventsapi.NewEventsClient(c.conn) } +// VersionService returns the underlying VersionClient func (c *Client) VersionService() versionservice.VersionClient { return versionservice.NewVersionClient(c.conn) } @@ -473,11 +500,38 @@ const ( type importOpts struct { format imageFormat refObject string + labels map[string]string } // ImportOpt allows the caller to specify import specific options type ImportOpt func(c *importOpts) error +// WithImportLabel sets a label to be associated with an imported image +func WithImportLabel(key, value string) ImportOpt { + return func(opts *importOpts) error { + if opts.labels == nil { + opts.labels = make(map[string]string) + } + + opts.labels[key] = value + return nil + } +} + +// WithImportLabels associates a set of labels to an imported image +func WithImportLabels(labels map[string]string) ImportOpt { + return func(opts *importOpts) error { + if opts.labels == nil { + opts.labels = make(map[string]string) + } + + for k, v := range labels { + opts.labels[k] = v + } + return nil + } +} + // WithOCIImportFormat sets the import format for an OCI image format func WithOCIImportFormat() ImportOpt { return func(c *importOpts) error { diff --git a/vendor/github.com/containerd/containerd/client_opts.go b/vendor/github.com/containerd/containerd/client_opts.go index 83d5288c4ccc3..c1e93bae92e75 100644 --- a/vendor/github.com/containerd/containerd/client_opts.go +++ b/vendor/github.com/containerd/containerd/client_opts.go @@ -33,25 +33,51 @@ func WithDialOpts(opts []grpc.DialOption) ClientOpt { } } -// RemoteOpts allows the caller to set distribution options for a remote -type RemoteOpts func(*Client, *RemoteContext) error +// RemoteOpt allows the caller to set distribution options for a remote +type RemoteOpt func(*Client, *RemoteContext) error // WithPullUnpack is used to unpack an image after pull. This // uses the snapshotter, content store, and diff service // configured for the client. -func WithPullUnpack(client *Client, c *RemoteContext) error { +func WithPullUnpack(_ *Client, c *RemoteContext) error { c.Unpack = true return nil } // WithPullSnapshotter specifies snapshotter name used for unpacking -func WithPullSnapshotter(snapshotterName string) RemoteOpts { - return func(client *Client, c *RemoteContext) error { +func WithPullSnapshotter(snapshotterName string) RemoteOpt { + return func(_ *Client, c *RemoteContext) error { c.Snapshotter = snapshotterName return nil } } +// WithPullLabel sets a label to be associated with a pulled reference +func WithPullLabel(key, value string) RemoteOpt { + return func(_ *Client, rc *RemoteContext) error { + if rc.Labels == nil { + rc.Labels = make(map[string]string) + } + + rc.Labels[key] = value + return nil + } +} + +// WithPullLabels associates a set of labels to a pulled reference +func WithPullLabels(labels map[string]string) RemoteOpt { + return func(_ *Client, rc *RemoteContext) error { + if rc.Labels == nil { + rc.Labels = make(map[string]string) + } + + for k, v := range labels { + rc.Labels[k] = v + } + return nil + } +} + // WithSchema1Conversion is used to convert Docker registry schema 1 // manifests to oci manifests on pull. Without this option schema 1 // manifests will return a not supported error. @@ -61,7 +87,7 @@ func WithSchema1Conversion(client *Client, c *RemoteContext) error { } // WithResolver specifies the resolver to use. -func WithResolver(resolver remotes.Resolver) RemoteOpts { +func WithResolver(resolver remotes.Resolver) RemoteOpt { return func(client *Client, c *RemoteContext) error { c.Resolver = resolver return nil @@ -69,7 +95,7 @@ func WithResolver(resolver remotes.Resolver) RemoteOpts { } // WithImageHandler adds a base handler to be called on dispatch. -func WithImageHandler(h images.Handler) RemoteOpts { +func WithImageHandler(h images.Handler) RemoteOpt { return func(client *Client, c *RemoteContext) error { c.BaseHandlers = append(c.BaseHandlers, h) return nil diff --git a/vendor/github.com/containerd/containerd/container.go b/vendor/github.com/containerd/containerd/container.go index a9657d1e9731f..a9750eca01a9b 100644 --- a/vendor/github.com/containerd/containerd/container.go +++ b/vendor/github.com/containerd/containerd/container.go @@ -5,36 +5,36 @@ import ( "encoding/json" "path/filepath" "strings" - "sync" "github.com/containerd/containerd/api/services/tasks/v1" "github.com/containerd/containerd/api/types" "github.com/containerd/containerd/containers" "github.com/containerd/containerd/errdefs" - "github.com/containerd/containerd/typeurl" + "github.com/containerd/typeurl" + prototypes "github.com/gogo/protobuf/types" specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" ) -// DeleteOpts allows the caller to set options for the deletion of a container -type DeleteOpts func(context.Context, *Client, containers.Container) error - // Container is a metadata object for container resources and task creation type Container interface { // ID identifies the container ID() string // Info returns the underlying container record type - Info() containers.Container + Info(context.Context) (containers.Container, error) // Delete removes the container Delete(context.Context, ...DeleteOpts) error // NewTask creates a new task based on the container metadata NewTask(context.Context, IOCreation, ...NewTaskOpts) (Task, error) // Spec returns the OCI runtime specification - Spec() (*specs.Spec, error) + Spec(context.Context) (*specs.Spec, error) // Task returns the current task for the container // // If IOAttach options are passed the client will reattach to the IO for the running // task. If no task exists for the container a NotFound error is returned + // + // Clients must make sure that only one reader is attached to the task and consuming + // the output from the task's fifos Task(context.Context, IOAttach) (Task, error) // Image returns the image that the container is based on Image(context.Context) (Image, error) @@ -42,52 +42,54 @@ type Container interface { Labels(context.Context) (map[string]string, error) // SetLabels sets the provided labels for the container and returns the final label set SetLabels(context.Context, map[string]string) (map[string]string, error) + // Extensions returns the extensions set on the container + Extensions(context.Context) (map[string]prototypes.Any, error) + // Update a container + Update(context.Context, ...UpdateContainerOpts) error } func containerFromRecord(client *Client, c containers.Container) *container { return &container{ client: client, - c: c, + id: c.ID, } } var _ = (Container)(&container{}) type container struct { - mu sync.Mutex - client *Client - c containers.Container + id string } // ID returns the container's unique id func (c *container) ID() string { - return c.c.ID + return c.id } -func (c *container) Info() containers.Container { - return c.c +func (c *container) Info(ctx context.Context) (containers.Container, error) { + return c.get(ctx) } -func (c *container) Labels(ctx context.Context) (map[string]string, error) { - r, err := c.client.ContainerService().Get(ctx, c.ID()) +func (c *container) Extensions(ctx context.Context) (map[string]prototypes.Any, error) { + r, err := c.get(ctx) if err != nil { return nil, err } + return r.Extensions, nil +} - c.c = r - - m := make(map[string]string, len(r.Labels)) - for k, v := range c.c.Labels { - m[k] = v +func (c *container) Labels(ctx context.Context) (map[string]string, error) { + r, err := c.get(ctx) + if err != nil { + return nil, err } - - return m, nil + return r.Labels, nil } func (c *container) SetLabels(ctx context.Context, labels map[string]string) (map[string]string, error) { container := containers.Container{ - ID: c.ID(), + ID: c.id, Labels: labels, } @@ -102,20 +104,17 @@ func (c *container) SetLabels(ctx context.Context, labels map[string]string) (ma if err != nil { return nil, err } - - c.c = r // update our local container - - m := make(map[string]string, len(r.Labels)) - for k, v := range c.c.Labels { - m[k] = v - } - return m, nil + return r.Labels, nil } // Spec returns the current OCI specification for the container -func (c *container) Spec() (*specs.Spec, error) { +func (c *container) Spec(ctx context.Context) (*specs.Spec, error) { + r, err := c.get(ctx) + if err != nil { + return nil, err + } var s specs.Spec - if err := json.Unmarshal(c.c.Spec.Value, &s); err != nil { + if err := json.Unmarshal(r.Spec.Value, &s); err != nil { return nil, err } return &s, nil @@ -123,20 +122,20 @@ func (c *container) Spec() (*specs.Spec, error) { // Delete deletes an existing container // an error is returned if the container has running tasks -func (c *container) Delete(ctx context.Context, opts ...DeleteOpts) (err error) { - if _, err := c.Task(ctx, nil); err == nil { - return errors.Wrapf(errdefs.ErrFailedPrecondition, "cannot delete running task %v", c.ID()) +func (c *container) Delete(ctx context.Context, opts ...DeleteOpts) error { + if _, err := c.loadTask(ctx, nil); err == nil { + return errors.Wrapf(errdefs.ErrFailedPrecondition, "cannot delete running task %v", c.id) + } + r, err := c.get(ctx) + if err != nil { + return err } for _, o := range opts { - if err := o(ctx, c.client, c.c); err != nil { + if err := o(ctx, c.client, r); err != nil { return err } } - - if cerr := c.client.ContainerService().Delete(ctx, c.ID()); err == nil { - err = cerr - } - return err + return c.client.ContainerService().Delete(ctx, c.id) } func (c *container) Task(ctx context.Context, attach IOAttach) (Task, error) { @@ -145,12 +144,16 @@ func (c *container) Task(ctx context.Context, attach IOAttach) (Task, error) { // Image returns the image that the container is based on func (c *container) Image(ctx context.Context) (Image, error) { - if c.c.Image == "" { - return nil, errors.Wrapf(errdefs.ErrNotFound, "container not created from an image") + r, err := c.get(ctx) + if err != nil { + return nil, err + } + if r.Image == "" { + return nil, errors.Wrap(errdefs.ErrNotFound, "container not created from an image") } - i, err := c.client.ImageService().Get(ctx, c.c.Image) + i, err := c.client.ImageService().Get(ctx, r.Image) if err != nil { - return nil, errors.Wrapf(err, "failed to get image for container") + return nil, errors.Wrapf(err, "failed to get image %s for container", r.Image) } return &image{ client: c.client, @@ -159,27 +162,29 @@ func (c *container) Image(ctx context.Context) (Image, error) { } func (c *container) NewTask(ctx context.Context, ioCreate IOCreation, opts ...NewTaskOpts) (Task, error) { - c.mu.Lock() - defer c.mu.Unlock() - i, err := ioCreate(c.c.ID) + i, err := ioCreate(c.id) if err != nil { return nil, err } cfg := i.Config() request := &tasks.CreateTaskRequest{ - ContainerID: c.c.ID, + ContainerID: c.id, Terminal: cfg.Terminal, Stdin: cfg.Stdin, Stdout: cfg.Stdout, Stderr: cfg.Stderr, } - if c.c.SnapshotKey != "" { - if c.c.Snapshotter == "" { + r, err := c.get(ctx) + if err != nil { + return nil, err + } + if r.SnapshotKey != "" { + if r.Snapshotter == "" { return nil, errors.Wrapf(errdefs.ErrInvalidArgument, "unable to resolve rootfs mounts without snapshotter on container") } // get the rootfs from the snapshotter and add it to the request - mounts, err := c.client.SnapshotService(c.c.Snapshotter).Mounts(ctx, c.c.SnapshotKey) + mounts, err := c.client.SnapshotService(r.Snapshotter).Mounts(ctx, r.SnapshotKey) if err != nil { return nil, err } @@ -216,25 +221,39 @@ func (c *container) NewTask(ctx context.Context, ioCreate IOCreation, opts ...Ne t := &task{ client: c.client, io: i, - id: c.ID(), + id: c.id, } if info.Checkpoint != nil { request.Checkpoint = info.Checkpoint - // we need to defer the create call to start - t.deferred = request - } else { - response, err := c.client.TaskService().Create(ctx, request) - if err != nil { - return nil, errdefs.FromGRPC(err) - } - t.pid = response.Pid } + response, err := c.client.TaskService().Create(ctx, request) + if err != nil { + return nil, errdefs.FromGRPC(err) + } + t.pid = response.Pid return t, nil } +func (c *container) Update(ctx context.Context, opts ...UpdateContainerOpts) error { + // fetch the current container config before updating it + r, err := c.get(ctx) + if err != nil { + return err + } + for _, o := range opts { + if err := o(ctx, c.client, &r); err != nil { + return err + } + } + if _, err := c.client.ContainerService().Update(ctx, r); err != nil { + return errdefs.FromGRPC(err) + } + return nil +} + func (c *container) loadTask(ctx context.Context, ioAttach IOAttach) (Task, error) { response, err := c.client.TaskService().Get(ctx, &tasks.GetRequest{ - ContainerID: c.c.ID, + ContainerID: c.id, }) if err != nil { err = errdefs.FromGRPC(err) @@ -258,6 +277,10 @@ func (c *container) loadTask(ctx context.Context, ioAttach IOAttach) (Task, erro return t, nil } +func (c *container) get(ctx context.Context) (containers.Container, error) { + return c.client.ContainerService().Get(ctx, c.id) +} + func attachExistingIO(response *tasks.GetResponse, ioAttach IOAttach) (IO, error) { // get the existing fifo paths from the task information stored by the daemon paths := &FIFOSet{ diff --git a/vendor/github.com/containerd/containerd/container_opts.go b/vendor/github.com/containerd/containerd/container_opts.go index 10b566e185eee..57ffc0a368680 100644 --- a/vendor/github.com/containerd/containerd/container_opts.go +++ b/vendor/github.com/containerd/containerd/container_opts.go @@ -2,19 +2,27 @@ package containerd import ( "context" + "time" "github.com/containerd/containerd/containers" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/platforms" - "github.com/containerd/containerd/typeurl" + "github.com/containerd/containerd/snapshot" + "github.com/containerd/typeurl" "github.com/gogo/protobuf/types" "github.com/opencontainers/image-spec/identity" "github.com/pkg/errors" ) +// DeleteOpts allows the caller to set options for the deletion of a container +type DeleteOpts func(ctx context.Context, client *Client, c containers.Container) error + // NewContainerOpts allows the caller to set additional options when creating a container type NewContainerOpts func(ctx context.Context, client *Client, c *containers.Container) error +// UpdateContainerOpts allows the caller to set additional options when updating a container +type UpdateContainerOpts func(ctx context.Context, client *Client, c *containers.Container) error + // WithRuntime allows a user to specify the runtime name and additional options that should // be used to create tasks for the container func WithRuntime(name string, options interface{}) NewContainerOpts { @@ -80,12 +88,16 @@ func WithSnapshot(id string) NewContainerOpts { // root filesystem in read-write mode func WithNewSnapshot(id string, i Image) NewContainerOpts { return func(ctx context.Context, client *Client, c *containers.Container) error { - diffIDs, err := i.(*image).i.RootFS(ctx, client.ContentStore(), platforms.Format(platforms.Default())) + diffIDs, err := i.(*image).i.RootFS(ctx, client.ContentStore(), platforms.Default()) if err != nil { return err } setSnapshotterIfEmpty(c) - if _, err := client.SnapshotService(c.Snapshotter).Prepare(ctx, id, identity.ChainID(diffIDs).String()); err != nil { + labels := map[string]string{ + "containerd.io/gc.root": time.Now().String(), + } + parent := identity.ChainID(diffIDs).String() + if _, err := client.SnapshotService(c.Snapshotter).Prepare(ctx, id, parent, snapshot.WithLabels(labels)); err != nil { return err } c.SnapshotKey = id @@ -109,12 +121,16 @@ func WithSnapshotCleanup(ctx context.Context, client *Client, c containers.Conta // root filesystem in read-only mode func WithNewSnapshotView(id string, i Image) NewContainerOpts { return func(ctx context.Context, client *Client, c *containers.Container) error { - diffIDs, err := i.(*image).i.RootFS(ctx, client.ContentStore(), platforms.Format(platforms.Default())) + diffIDs, err := i.(*image).i.RootFS(ctx, client.ContentStore(), platforms.Default()) if err != nil { return err } setSnapshotterIfEmpty(c) - if _, err := client.SnapshotService(c.Snapshotter).View(ctx, id, identity.ChainID(diffIDs).String()); err != nil { + labels := map[string]string{ + "containerd.io/gc.root": time.Now().String(), + } + parent := identity.ChainID(diffIDs).String() + if _, err := client.SnapshotService(c.Snapshotter).View(ctx, id, parent, snapshot.WithLabels(labels)); err != nil { return err } c.SnapshotKey = id @@ -128,3 +144,31 @@ func setSnapshotterIfEmpty(c *containers.Container) { c.Snapshotter = DefaultSnapshotter } } + +// WithContainerExtension appends extension data to the container object. +// Use this to decorate the container object with additional data for the client +// integration. +// +// Make sure to register the type of `extension` in the typeurl package via +// `typeurl.Register` or container creation may fail. +func WithContainerExtension(name string, extension interface{}) NewContainerOpts { + return func(ctx context.Context, client *Client, c *containers.Container) error { + if name == "" { + return errors.Wrapf(errdefs.ErrInvalidArgument, "extension key must not be zero-length") + } + + any, err := typeurl.MarshalAny(extension) + if err != nil { + if errors.Cause(err) == typeurl.ErrNotFound { + return errors.Wrapf(err, "extension %q is not registered with the typeurl package, see `typeurl.Register`", name) + } + return errors.Wrap(err, "error marshalling extension") + } + + if c.Extensions == nil { + c.Extensions = make(map[string]types.Any) + } + c.Extensions[name] = *any + return nil + } +} diff --git a/vendor/github.com/containerd/containerd/container_opts_unix.go b/vendor/github.com/containerd/containerd/container_opts_unix.go index 8108f4b837037..e2cd7c939d695 100644 --- a/vendor/github.com/containerd/containerd/container_opts_unix.go +++ b/vendor/github.com/containerd/containerd/container_opts_unix.go @@ -18,16 +18,20 @@ import ( digest "github.com/opencontainers/go-digest" "github.com/opencontainers/image-spec/identity" "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/pkg/errors" ) // WithCheckpoint allows a container to be created from the checkpointed information // provided by the descriptor. The image, snapshot, and runtime specifications are // restored on the container -func WithCheckpoint(desc v1.Descriptor, snapshotKey string) NewContainerOpts { +func WithCheckpoint(im Image, snapshotKey string) NewContainerOpts { // set image and rw, and spec return func(ctx context.Context, client *Client, c *containers.Container) error { - id := desc.Digest - store := client.ContentStore() + var ( + desc = im.Target() + id = desc.Digest + store = client.ContentStore() + ) index, err := decodeIndex(ctx, store, id) if err != nil { return err @@ -38,14 +42,14 @@ func WithCheckpoint(desc v1.Descriptor, snapshotKey string) NewContainerOpts { case v1.MediaTypeImageLayer: fk := m rw = &fk - case images.MediaTypeDockerSchema2Manifest: - config, err := images.Config(ctx, store, m, platforms.Format(platforms.Default())) + case images.MediaTypeDockerSchema2Manifest, images.MediaTypeDockerSchema2ManifestList: + config, err := images.Config(ctx, store, m, platforms.Default()) if err != nil { - return err + return errors.Wrap(err, "unable to resolve image config") } diffIDs, err := images.RootFS(ctx, store, config) if err != nil { - return err + return errors.Wrap(err, "unable to get rootfs") } setSnapshotterIfEmpty(c) if _, err := client.SnapshotService(c.Snapshotter).Prepare(ctx, snapshotKey, identity.ChainID(diffIDs).String()); err != nil { @@ -57,7 +61,7 @@ func WithCheckpoint(desc v1.Descriptor, snapshotKey string) NewContainerOpts { case images.MediaTypeContainerd1CheckpointConfig: data, err := content.ReadBlob(ctx, store, m.Digest) if err != nil { - return err + return errors.Wrap(err, "unable to read checkpoint config") } var any protobuf.Any if err := proto.Unmarshal(data, &any); err != nil { @@ -70,10 +74,10 @@ func WithCheckpoint(desc v1.Descriptor, snapshotKey string) NewContainerOpts { // apply the rw snapshot to the new rw layer mounts, err := client.SnapshotService(c.Snapshotter).Mounts(ctx, snapshotKey) if err != nil { - return err + return errors.Wrapf(err, "unable to get mounts for %s", snapshotKey) } if _, err := client.DiffService().Apply(ctx, *rw, mounts); err != nil { - return err + return errors.Wrap(err, "unable to apply rw diff") } } c.SnapshotKey = snapshotKey @@ -84,8 +88,9 @@ func WithCheckpoint(desc v1.Descriptor, snapshotKey string) NewContainerOpts { // WithTaskCheckpoint allows a task to be created with live runtime and memory data from a // previous checkpoint. Additional software such as CRIU may be required to // restore a task from a checkpoint -func WithTaskCheckpoint(desc v1.Descriptor) NewTaskOpts { +func WithTaskCheckpoint(im Image) NewTaskOpts { return func(ctx context.Context, c *Client, info *TaskInfo) error { + desc := im.Target() id := desc.Digest index, err := decodeIndex(ctx, c.ContentStore(), id) if err != nil { diff --git a/vendor/github.com/containerd/containerd/containers/containers.go b/vendor/github.com/containerd/containerd/containers/containers.go index 6ad161f8f58d0..df4ad83c9ebf3 100644 --- a/vendor/github.com/containerd/containerd/containers/containers.go +++ b/vendor/github.com/containerd/containerd/containers/containers.go @@ -57,13 +57,18 @@ type Container struct { // UpdatedAt is the time at which the container was updated. UpdatedAt time.Time + + // Extensions stores client-specified metadata + Extensions map[string]types.Any } +// RuntimeInfo holds runtime specific information type RuntimeInfo struct { Name string Options *types.Any } +// Store interacts with the underlying container storage type Store interface { Get(ctx context.Context, id string) (Container, error) diff --git a/vendor/github.com/containerd/containerd/containerstore.go b/vendor/github.com/containerd/containerd/containerstore.go index 8d75fbe9e9da7..4db2350b081fb 100644 --- a/vendor/github.com/containerd/containerd/containerstore.go +++ b/vendor/github.com/containerd/containerd/containerstore.go @@ -15,6 +15,7 @@ type remoteContainers struct { var _ containers.Store = &remoteContainers{} +// NewRemoteContainerStore returns the container Store connected with the provided client func NewRemoteContainerStore(client containersapi.ContainersClient) containers.Store { return &remoteContainers{ client: client, @@ -97,6 +98,7 @@ func containerToProto(container *containers.Container) containersapi.Container { Spec: container.Spec, Snapshotter: container.Snapshotter, SnapshotKey: container.SnapshotKey, + Extensions: container.Extensions, } } @@ -116,6 +118,9 @@ func containerFromProto(containerpb *containersapi.Container) containers.Contain Spec: containerpb.Spec, Snapshotter: containerpb.Snapshotter, SnapshotKey: containerpb.SnapshotKey, + CreatedAt: containerpb.CreatedAt, + UpdatedAt: containerpb.UpdatedAt, + Extensions: containerpb.Extensions, } } diff --git a/vendor/github.com/containerd/containerd/content/content.go b/vendor/github.com/containerd/containerd/content/content.go index 6dce8b2e74932..05fd4aebe1d62 100644 --- a/vendor/github.com/containerd/containerd/content/content.go +++ b/vendor/github.com/containerd/containerd/content/content.go @@ -8,20 +8,25 @@ import ( "github.com/opencontainers/go-digest" ) +// ReaderAt extends the standard io.ReaderAt interface with reporting of Size and io.Closer type ReaderAt interface { io.ReaderAt io.Closer Size() int64 } +// Provider provides a reader interface for specific content type Provider interface { ReaderAt(ctx context.Context, dgst digest.Digest) (ReaderAt, error) } +// Ingester writes content type Ingester interface { Writer(ctx context.Context, ref string, size int64, expected digest.Digest) (Writer, error) } +// Info holds content specific information +// // TODO(stevvooe): Consider a very different name for this struct. Info is way // to general. It also reads very weird in certain context, like pluralization. type Info struct { @@ -32,6 +37,7 @@ type Info struct { Labels map[string]string } +// Status of a content operation type Status struct { Ref string Offset int64 @@ -81,8 +87,10 @@ type IngestManager interface { Abort(ctx context.Context, ref string) error } +// Writer handles the write of content into a content store type Writer interface { // Close is expected to be called after Commit() when commission is needed. + // Closing a writer without commit allows resuming or aborting. io.WriteCloser // Digest may return empty digest or panics until committed. @@ -111,6 +119,7 @@ type Store interface { // Opt is used to alter the mutable properties of content type Opt func(*Info) error +// WithLabels allows labels to be set on content func WithLabels(labels map[string]string) Opt { return func(info *Info) error { info.Labels = labels diff --git a/vendor/github.com/containerd/containerd/content/helpers.go b/vendor/github.com/containerd/containerd/content/helpers.go index b6d21ccbd57a8..32efc6ca0ec71 100644 --- a/vendor/github.com/containerd/containerd/content/helpers.go +++ b/vendor/github.com/containerd/containerd/content/helpers.go @@ -19,6 +19,7 @@ var ( } ) +// NewReader returns a io.Reader from a ReaderAt func NewReader(ra ReaderAt) io.Reader { rd := io.NewSectionReader(ra, 0, ra.Size()) return rd @@ -47,7 +48,7 @@ func ReadBlob(ctx context.Context, provider Provider, dgst digest.Digest) ([]byt // This is useful when the digest and size are known beforehand. // // Copy is buffered, so no need to wrap reader in buffered io. -func WriteBlob(ctx context.Context, cs Ingester, ref string, r io.Reader, size int64, expected digest.Digest) error { +func WriteBlob(ctx context.Context, cs Ingester, ref string, r io.Reader, size int64, expected digest.Digest, opts ...Opt) error { cw, err := cs.Writer(ctx, ref, size, expected) if err != nil { if !errdefs.IsAlreadyExists(err) { @@ -58,7 +59,7 @@ func WriteBlob(ctx context.Context, cs Ingester, ref string, r io.Reader, size i } defer cw.Close() - return Copy(ctx, cw, r, size, expected) + return Copy(ctx, cw, r, size, expected, opts...) } // Copy copies data with the expected digest from the reader into the @@ -68,7 +69,7 @@ func WriteBlob(ctx context.Context, cs Ingester, ref string, r io.Reader, size i // the size or digest is unknown, these values may be empty. // // Copy is buffered, so no need to wrap reader in buffered io. -func Copy(ctx context.Context, cw Writer, r io.Reader, size int64, expected digest.Digest) error { +func Copy(ctx context.Context, cw Writer, r io.Reader, size int64, expected digest.Digest, opts ...Opt) error { ws, err := cw.Status() if err != nil { return err @@ -95,7 +96,7 @@ func Copy(ctx context.Context, cw Writer, r io.Reader, size int64, expected dige return err } - if err := cw.Commit(ctx, size, expected); err != nil { + if err := cw.Commit(ctx, size, expected, opts...); err != nil { if !errdefs.IsAlreadyExists(err) { return errors.Wrapf(err, "failed commit on ref %q", ws.Ref) } diff --git a/vendor/github.com/containerd/containerd/content/local/store.go b/vendor/github.com/containerd/containerd/content/local/store.go index f977e5ba90c13..14a98881dd44c 100644 --- a/vendor/github.com/containerd/containerd/content/local/store.go +++ b/vendor/github.com/containerd/containerd/content/local/store.go @@ -8,6 +8,7 @@ import ( "os" "path/filepath" "strconv" + "strings" "sync" "time" @@ -27,6 +28,19 @@ var ( } ) +// LabelStore is used to store mutable labels for digests +type LabelStore interface { + // Get returns all the labels for the given digest + Get(digest.Digest) (map[string]string, error) + + // Set sets all the labels for a given digest + Set(digest.Digest, map[string]string) error + + // Update replaces the given labels for a digest, + // a key with an empty value removes a label. + Update(digest.Digest, map[string]string) (map[string]string, error) +} + // Store is digest-keyed store for content. All data written into the store is // stored under a verifiable digest. // @@ -34,15 +48,27 @@ var ( // including resumable ingest. type store struct { root string + ls LabelStore } +// NewStore returns a local content store func NewStore(root string) (content.Store, error) { + return NewLabeledStore(root, nil) +} + +// NewLabeledStore returns a new content store using the provided label store +// +// Note: content stores which are used underneath a metadata store may not +// require labels and should use `NewStore`. `NewLabeledStore` is primarily +// useful for tests or standalone implementations. +func NewLabeledStore(root string, ls LabelStore) (content.Store, error) { if err := os.MkdirAll(filepath.Join(root, "ingest"), 0777); err != nil && !os.IsExist(err) { return nil, err } return &store{ root: root, + ls: ls, }, nil } @@ -56,16 +82,23 @@ func (s *store) Info(ctx context.Context, dgst digest.Digest) (content.Info, err return content.Info{}, err } - - return s.info(dgst, fi), nil + var labels map[string]string + if s.ls != nil { + labels, err = s.ls.Get(dgst) + if err != nil { + return content.Info{}, err + } + } + return s.info(dgst, fi, labels), nil } -func (s *store) info(dgst digest.Digest, fi os.FileInfo) content.Info { +func (s *store) info(dgst digest.Digest, fi os.FileInfo, labels map[string]string) content.Info { return content.Info{ Digest: dgst, Size: fi.Size(), CreatedAt: fi.ModTime(), - UpdatedAt: fi.ModTime(), + UpdatedAt: getATime(fi), + Labels: labels, } } @@ -97,8 +130,8 @@ func (s *store) ReaderAt(ctx context.Context, dgst digest.Digest) (content.Reade // // While this is safe to do concurrently, safe exist-removal logic must hold // some global lock on the store. -func (cs *store) Delete(ctx context.Context, dgst digest.Digest) error { - if err := os.RemoveAll(cs.blobPath(dgst)); err != nil { +func (s *store) Delete(ctx context.Context, dgst digest.Digest) error { + if err := os.RemoveAll(s.blobPath(dgst)); err != nil { if !os.IsNotExist(err) { return err } @@ -109,14 +142,72 @@ func (cs *store) Delete(ctx context.Context, dgst digest.Digest) error { return nil } -func (cs *store) Update(ctx context.Context, info content.Info, fieldpaths ...string) (content.Info, error) { - // TODO: Support persisting and updating mutable content data - return content.Info{}, errors.Wrapf(errdefs.ErrFailedPrecondition, "update not supported on immutable content store") +func (s *store) Update(ctx context.Context, info content.Info, fieldpaths ...string) (content.Info, error) { + if s.ls == nil { + return content.Info{}, errors.Wrapf(errdefs.ErrFailedPrecondition, "update not supported on immutable content store") + } + + p := s.blobPath(info.Digest) + fi, err := os.Stat(p) + if err != nil { + if os.IsNotExist(err) { + err = errors.Wrapf(errdefs.ErrNotFound, "content %v", info.Digest) + } + + return content.Info{}, err + } + + var ( + all bool + labels map[string]string + ) + if len(fieldpaths) > 0 { + for _, path := range fieldpaths { + if strings.HasPrefix(path, "labels.") { + if labels == nil { + labels = map[string]string{} + } + + key := strings.TrimPrefix(path, "labels.") + labels[key] = info.Labels[key] + continue + } + + switch path { + case "labels": + all = true + labels = info.Labels + default: + return content.Info{}, errors.Wrapf(errdefs.ErrInvalidArgument, "cannot update %q field on content info %q", path, info.Digest) + } + } + } else { + all = true + labels = info.Labels + } + + if all { + err = s.ls.Set(info.Digest, labels) + } else { + labels, err = s.ls.Update(info.Digest, labels) + } + if err != nil { + return content.Info{}, err + } + + info = s.info(info.Digest, fi, labels) + info.UpdatedAt = time.Now() + + if err := os.Chtimes(p, info.UpdatedAt, info.CreatedAt); err != nil { + log.G(ctx).WithError(err).Warnf("could not change access time for %s", info.Digest) + } + + return info, nil } -func (cs *store) Walk(ctx context.Context, fn content.WalkFunc, filters ...string) error { +func (s *store) Walk(ctx context.Context, fn content.WalkFunc, filters ...string) error { // TODO: Support filters - root := filepath.Join(cs.root, "blobs") + root := filepath.Join(s.root, "blobs") var alg digest.Algorithm return filepath.Walk(root, func(path string, fi os.FileInfo, err error) error { if err != nil { @@ -153,7 +244,14 @@ func (cs *store) Walk(ctx context.Context, fn content.WalkFunc, filters ...strin // store or extra paths not expected previously. } - return fn(cs.info(dgst, fi)) + var labels map[string]string + if s.ls != nil { + labels, err = s.ls.Get(dgst) + if err != nil { + return err + } + } + return fn(s.info(dgst, fi, labels)) }) } @@ -382,8 +480,8 @@ func (s *store) Abort(ctx context.Context, ref string) error { return nil } -func (cs *store) blobPath(dgst digest.Digest) string { - return filepath.Join(cs.root, "blobs", dgst.Algorithm().String(), dgst.Hex()) +func (s *store) blobPath(dgst digest.Digest) string { + return filepath.Join(s.root, "blobs", dgst.Algorithm().String(), dgst.Hex()) } func (s *store) ingestRoot(ref string) string { diff --git a/vendor/github.com/containerd/containerd/content/local/store_unix.go b/vendor/github.com/containerd/containerd/content/local/store_unix.go index 46eab02c5109c..0d500b84d00f1 100644 --- a/vendor/github.com/containerd/containerd/content/local/store_unix.go +++ b/vendor/github.com/containerd/containerd/content/local/store_unix.go @@ -18,3 +18,12 @@ func getStartTime(fi os.FileInfo) time.Time { return fi.ModTime() } + +func getATime(fi os.FileInfo) time.Time { + if st, ok := fi.Sys().(*syscall.Stat_t); ok { + return time.Unix(int64(sys.StatAtime(st).Sec), + int64(sys.StatAtime(st).Nsec)) + } + + return fi.ModTime() +} diff --git a/vendor/github.com/containerd/containerd/content/local/store_windows.go b/vendor/github.com/containerd/containerd/content/local/store_windows.go index 7fb6ad43a5815..5f12ea5c423c7 100644 --- a/vendor/github.com/containerd/containerd/content/local/store_windows.go +++ b/vendor/github.com/containerd/containerd/content/local/store_windows.go @@ -8,3 +8,7 @@ import ( func getStartTime(fi os.FileInfo) time.Time { return fi.ModTime() } + +func getATime(fi os.FileInfo) time.Time { + return fi.ModTime() +} diff --git a/vendor/github.com/containerd/containerd/content/local/writer.go b/vendor/github.com/containerd/containerd/content/local/writer.go index 362c0e209ace5..8f1e92ded640a 100644 --- a/vendor/github.com/containerd/containerd/content/local/writer.go +++ b/vendor/github.com/containerd/containerd/content/local/writer.go @@ -56,6 +56,13 @@ func (w *writer) Write(p []byte) (n int, err error) { } func (w *writer) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) error { + var base content.Info + for _, opt := range opts { + if err := opt(&base); err != nil { + return err + } + } + if w.fp == nil { return errors.Wrap(errdefs.ErrFailedPrecondition, "cannot commit on closed writer") } @@ -123,6 +130,12 @@ func (w *writer) Commit(ctx context.Context, size int64, expected digest.Digest, w.fp = nil unlock(w.ref) + if w.s.ls != nil && base.Labels != nil { + if err := w.s.ls.Set(dgst, base.Labels); err != nil { + return err + } + } + return nil } @@ -130,10 +143,10 @@ func (w *writer) Commit(ctx context.Context, size int64, expected digest.Digest, // tact. // // If one needs to resume the transaction, a new writer can be obtained from -// `ContentStore.Resume` using the same key. The write can then be continued +// `Ingester.Writer` using the same key. The write can then be continued // from it was left off. // -// To abandon a transaction completely, first call close then `Store.Remove` to +// To abandon a transaction completely, first call close then `IngestManager.Abort` to // clean up the associated resources. func (w *writer) Close() (err error) { if w.fp != nil { diff --git a/vendor/github.com/containerd/containerd/dialer.go b/vendor/github.com/containerd/containerd/dialer.go index 0e54ebae18a79..c87cf12d00ebc 100644 --- a/vendor/github.com/containerd/containerd/dialer.go +++ b/vendor/github.com/containerd/containerd/dialer.go @@ -2,7 +2,6 @@ package containerd import ( "net" - "strings" "time" "github.com/pkg/errors" @@ -13,12 +12,12 @@ type dialResult struct { err error } +// Dialer returns a GRPC net.Conn connected to the provided address func Dialer(address string, timeout time.Duration) (net.Conn, error) { var ( stopC = make(chan struct{}) synC = make(chan *dialResult) ) - address = strings.TrimPrefix(address, "unix://") go func() { defer close(synC) for { @@ -47,6 +46,6 @@ func Dialer(address string, timeout time.Duration) (net.Conn, error) { dr.c.Close() } }() - return nil, errors.Errorf("dial %s: no such file or directory", address) + return nil, errors.Errorf("dial %s: timeout", address) } } diff --git a/vendor/github.com/containerd/containerd/dialer_unix.go b/vendor/github.com/containerd/containerd/dialer_unix.go index 3c4689986862c..2e97d17a453a6 100644 --- a/vendor/github.com/containerd/containerd/dialer_unix.go +++ b/vendor/github.com/containerd/containerd/dialer_unix.go @@ -6,6 +6,7 @@ import ( "fmt" "net" "os" + "strings" "syscall" "time" ) @@ -24,9 +25,12 @@ func isNoent(err error) bool { } func dialer(address string, timeout time.Duration) (net.Conn, error) { + address = strings.TrimPrefix(address, "unix://") return net.DialTimeout("unix", address, timeout) } +// DialAddress returns the address with unix:// prepended to the +// provided address func DialAddress(address string) string { return fmt.Sprintf("unix://%s", address) } diff --git a/vendor/github.com/containerd/containerd/dialer_windows.go b/vendor/github.com/containerd/containerd/dialer_windows.go index c91a326174bc8..43625ef1ffec0 100644 --- a/vendor/github.com/containerd/containerd/dialer_windows.go +++ b/vendor/github.com/containerd/containerd/dialer_windows.go @@ -24,6 +24,7 @@ func dialer(address string, timeout time.Duration) (net.Conn, error) { return winio.DialPipe(address, &timeout) } +// DialAddress returns the dial address func DialAddress(address string) string { return address } diff --git a/vendor/github.com/containerd/containerd/diff/diff.go b/vendor/github.com/containerd/containerd/diff/diff.go new file mode 100644 index 0000000000000..85cef358357db --- /dev/null +++ b/vendor/github.com/containerd/containerd/diff/diff.go @@ -0,0 +1,69 @@ +package diff + +import ( + "github.com/containerd/containerd/mount" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" + "golang.org/x/net/context" +) + +// Config is used to hold parameters needed for a diff operation +type Config struct { + // MediaType is the type of diff to generate + // Default depends on the differ, + // i.e. application/vnd.oci.image.layer.v1.tar+gzip + MediaType string + + // Reference is the content upload reference + // Default will use a random reference string + Reference string + + // Labels are the labels to apply to the generated content + Labels map[string]string +} + +// Opt is used to configure a diff operation +type Opt func(*Config) error + +// Differ allows the apply and creation of filesystem diffs between mounts +type Differ interface { + // Apply applies the content referred to by the given descriptor to + // the provided mount. The method of applying is based on the + // implementation and content descriptor. For example, in the common + // case the descriptor is a file system difference in tar format, + // that tar would be applied on top of the mounts. + Apply(ctx context.Context, desc ocispec.Descriptor, mount []mount.Mount) (ocispec.Descriptor, error) + + // DiffMounts computes the difference between two mounts and returns a + // descriptor for the computed diff. The options can provide + // a ref which can be used to track the content creation of the diff. + // The media type which is used to determine the format of the created + // content can also be provided as an option. + DiffMounts(ctx context.Context, lower, upper []mount.Mount, opts ...Opt) (ocispec.Descriptor, error) +} + +// WithMediaType sets the media type to use for creating the diff, without +// specifying the differ will choose a default. +func WithMediaType(m string) Opt { + return func(c *Config) error { + c.MediaType = m + return nil + } +} + +// WithReference is used to set the content upload reference used by +// the diff operation. This allows the caller to track the upload through +// the content store. +func WithReference(ref string) Opt { + return func(c *Config) error { + c.Reference = ref + return nil + } +} + +// WithLabels is used to set content labels on the created diff content. +func WithLabels(labels map[string]string) Opt { + return func(c *Config) error { + c.Labels = labels + return nil + } +} diff --git a/vendor/github.com/containerd/containerd/differ/differ.go b/vendor/github.com/containerd/containerd/diff/walking/differ.go similarity index 66% rename from vendor/github.com/containerd/containerd/differ/differ.go rename to vendor/github.com/containerd/containerd/diff/walking/differ.go index 3aa26442977fa..c94e5592cc2c4 100644 --- a/vendor/github.com/containerd/containerd/differ/differ.go +++ b/vendor/github.com/containerd/containerd/diff/walking/differ.go @@ -1,23 +1,30 @@ -package differ +package walking import ( + "crypto/rand" + "encoding/base64" + "fmt" "io" "io/ioutil" "os" "strings" + "time" - "github.com/boltdb/bolt" "github.com/containerd/containerd/archive" "github.com/containerd/containerd/archive/compression" "github.com/containerd/containerd/content" + "github.com/containerd/containerd/diff" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" + "github.com/containerd/containerd/log" "github.com/containerd/containerd/metadata" "github.com/containerd/containerd/mount" + "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/plugin" digest "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" + "github.com/sirupsen/logrus" "golang.org/x/net/context" ) @@ -25,20 +32,17 @@ func init() { plugin.Register(&plugin.Registration{ Type: plugin.DiffPlugin, ID: "walking", - Requires: []plugin.PluginType{ - plugin.ContentPlugin, + Requires: []plugin.Type{ plugin.MetadataPlugin, }, - Init: func(ic *plugin.InitContext) (interface{}, error) { - c, err := ic.Get(plugin.ContentPlugin) - if err != nil { - return nil, err - } + InitFn: func(ic *plugin.InitContext) (interface{}, error) { md, err := ic.Get(plugin.MetadataPlugin) if err != nil { return nil, err } - return NewWalkingDiff(metadata.NewContentStore(md.(*bolt.DB), c.(content.Store))) + + ic.Meta.Platforms = append(ic.Meta.Platforms, platforms.DefaultSpec()) + return NewWalkingDiff(md.(*metadata.DB).ContentStore()) }, }) } @@ -49,9 +53,9 @@ type walkingDiff struct { var emptyDesc = ocispec.Descriptor{} -// NewWalkingDiff is a generic implementation of plugin.Differ. +// NewWalkingDiff is a generic implementation of diff.Differ. // NewWalkingDiff is expected to work with any filesystem. -func NewWalkingDiff(store content.Store) (plugin.Differ, error) { +func NewWalkingDiff(store content.Store) (diff.Differ, error) { return &walkingDiff{ store: store, }, nil @@ -60,7 +64,18 @@ func NewWalkingDiff(store content.Store) (plugin.Differ, error) { // Apply applies the content associated with the provided digests onto the // provided mounts. Archive content will be extracted and decompressed if // necessary. -func (s *walkingDiff) Apply(ctx context.Context, desc ocispec.Descriptor, mounts []mount.Mount) (ocispec.Descriptor, error) { +func (s *walkingDiff) Apply(ctx context.Context, desc ocispec.Descriptor, mounts []mount.Mount) (d ocispec.Descriptor, err error) { + t1 := time.Now() + defer func() { + if err == nil { + log.G(ctx).WithFields(logrus.Fields{ + "d": time.Now().Sub(t1), + "dgst": desc.Digest, + "size": desc.Size, + "media": desc.MediaType, + }).Debugf("diff applied") + } + }() var isCompressed bool switch desc.MediaType { case ocispec.MediaTypeImageLayer, images.MediaTypeDockerSchema2Layer: @@ -81,7 +96,7 @@ func (s *walkingDiff) Apply(ctx context.Context, desc ocispec.Descriptor, mounts } defer os.RemoveAll(dir) - if err := mount.MountAll(mounts, dir); err != nil { + if err := mount.All(mounts, dir); err != nil { return emptyDesc, errors.Wrap(err, "failed to mount") } defer mount.Unmount(dir, 0) @@ -125,17 +140,25 @@ func (s *walkingDiff) Apply(ctx context.Context, desc ocispec.Descriptor, mounts // DiffMounts creates a diff between the given mounts and uploads the result // to the content store. -func (s *walkingDiff) DiffMounts(ctx context.Context, lower, upper []mount.Mount, media, ref string) (ocispec.Descriptor, error) { +func (s *walkingDiff) DiffMounts(ctx context.Context, lower, upper []mount.Mount, opts ...diff.Opt) (d ocispec.Descriptor, err error) { + var config diff.Config + for _, opt := range opts { + if err := opt(&config); err != nil { + return emptyDesc, err + } + } + + if config.MediaType == "" { + config.MediaType = ocispec.MediaTypeImageLayerGzip + } + var isCompressed bool - switch media { + switch config.MediaType { case ocispec.MediaTypeImageLayer: case ocispec.MediaTypeImageLayerGzip: isCompressed = true - case "": - media = ocispec.MediaTypeImageLayerGzip - isCompressed = true default: - return emptyDesc, errors.Wrapf(errdefs.ErrNotImplemented, "unsupported diff media type: %v", media) + return emptyDesc, errors.Wrapf(errdefs.ErrNotImplemented, "unsupported diff media type: %v", config.MediaType) } aDir, err := ioutil.TempDir("", "left-") if err != nil { @@ -149,22 +172,42 @@ func (s *walkingDiff) DiffMounts(ctx context.Context, lower, upper []mount.Mount } defer os.RemoveAll(bDir) - if err := mount.MountAll(lower, aDir); err != nil { + if err := mount.All(lower, aDir); err != nil { return emptyDesc, errors.Wrap(err, "failed to mount") } defer mount.Unmount(aDir, 0) - if err := mount.MountAll(upper, bDir); err != nil { + if err := mount.All(upper, bDir); err != nil { return emptyDesc, errors.Wrap(err, "failed to mount") } defer mount.Unmount(bDir, 0) - cw, err := s.store.Writer(ctx, ref, 0, "") + var newReference bool + if config.Reference == "" { + newReference = true + config.Reference = uniqueRef() + } + + cw, err := s.store.Writer(ctx, config.Reference, 0, "") if err != nil { return emptyDesc, errors.Wrap(err, "failed to open writer") } + defer func() { + if err != nil { + cw.Close() + if newReference { + if err := s.store.Abort(ctx, config.Reference); err != nil { + log.G(ctx).WithField("ref", config.Reference).Warnf("failed to delete diff upload") + } + } + } + }() + if !newReference { + if err := cw.Truncate(0); err != nil { + return emptyDesc, err + } + } - var opts []content.Opt if isCompressed { dgstr := digest.SHA256.Digester() compressed, err := compression.CompressStream(cw, compression.Gzip) @@ -176,17 +219,24 @@ func (s *walkingDiff) DiffMounts(ctx context.Context, lower, upper []mount.Mount if err != nil { return emptyDesc, errors.Wrap(err, "failed to write compressed diff") } - opts = append(opts, content.WithLabels(map[string]string{ - "containerd.io/uncompressed": dgstr.Digest().String(), - })) + + if config.Labels == nil { + config.Labels = map[string]string{} + } + config.Labels["containerd.io/uncompressed"] = dgstr.Digest().String() } else { if err = archive.WriteDiff(ctx, cw, aDir, bDir); err != nil { return emptyDesc, errors.Wrap(err, "failed to write diff") } } + var commitopts []content.Opt + if config.Labels != nil { + commitopts = append(commitopts, content.WithLabels(config.Labels)) + } + dgst := cw.Digest() - if err := cw.Commit(ctx, 0, dgst, opts...); err != nil { + if err := cw.Commit(ctx, 0, dgst, commitopts...); err != nil { return emptyDesc, errors.Wrap(err, "failed to commit") } @@ -196,7 +246,7 @@ func (s *walkingDiff) DiffMounts(ctx context.Context, lower, upper []mount.Mount } return ocispec.Descriptor{ - MediaType: media, + MediaType: config.MediaType, Size: info.Size, Digest: info.Digest, }, nil @@ -212,3 +262,11 @@ func (rc *readCounter) Read(p []byte) (n int, err error) { rc.c += int64(n) return } + +func uniqueRef() string { + t := time.Now() + var b [3]byte + // Ignore read failures, just decreases uniqueness + rand.Read(b[:]) + return fmt.Sprintf("%d-%s", t.UnixNano(), base64.URLEncoding.EncodeToString(b[:])) +} diff --git a/vendor/github.com/containerd/containerd/errdefs/errors.go b/vendor/github.com/containerd/containerd/errdefs/errors.go index 44ec72e7b9e8b..b4d6ea860b041 100644 --- a/vendor/github.com/containerd/containerd/errdefs/errors.go +++ b/vendor/github.com/containerd/containerd/errdefs/errors.go @@ -29,6 +29,7 @@ var ( ErrNotImplemented = errors.New("not implemented") // represents not supported and unimplemented ) +// IsInvalidArgument returns true if the error is due to an invalid argument func IsInvalidArgument(err error) bool { return errors.Cause(err) == ErrInvalidArgument } @@ -45,15 +46,17 @@ func IsAlreadyExists(err error) bool { } // IsFailedPrecondition returns true if an operation could not proceed to the -// lack of a particular condition. +// lack of a particular condition func IsFailedPrecondition(err error) bool { return errors.Cause(err) == ErrFailedPrecondition } +// IsUnavailable returns true if the error is due to a resource being unavailable func IsUnavailable(err error) bool { return errors.Cause(err) == ErrUnavailable } +// IsNotImplemented returns true if the error is due to not being implemented func IsNotImplemented(err error) bool { return errors.Cause(err) == ErrNotImplemented } diff --git a/vendor/github.com/containerd/containerd/errdefs/grpc.go b/vendor/github.com/containerd/containerd/errdefs/grpc.go index 76fb3eb3fc377..2aa2e11b4bbd4 100644 --- a/vendor/github.com/containerd/containerd/errdefs/grpc.go +++ b/vendor/github.com/containerd/containerd/errdefs/grpc.go @@ -29,17 +29,17 @@ func ToGRPC(err error) error { switch { case IsInvalidArgument(err): - return grpc.Errorf(codes.InvalidArgument, err.Error()) + return status.Errorf(codes.InvalidArgument, err.Error()) case IsNotFound(err): - return grpc.Errorf(codes.NotFound, err.Error()) + return status.Errorf(codes.NotFound, err.Error()) case IsAlreadyExists(err): - return grpc.Errorf(codes.AlreadyExists, err.Error()) + return status.Errorf(codes.AlreadyExists, err.Error()) case IsFailedPrecondition(err): - return grpc.Errorf(codes.FailedPrecondition, err.Error()) + return status.Errorf(codes.FailedPrecondition, err.Error()) case IsUnavailable(err): - return grpc.Errorf(codes.Unavailable, err.Error()) + return status.Errorf(codes.Unavailable, err.Error()) case IsNotImplemented(err): - return grpc.Errorf(codes.Unimplemented, err.Error()) + return status.Errorf(codes.Unimplemented, err.Error()) } return err @@ -53,6 +53,7 @@ func ToGRPCf(err error, format string, args ...interface{}) error { return ToGRPC(errors.Wrapf(err, format, args...)) } +// FromGRPC returns the underlying error from a grpc service based on the grpc error code func FromGRPC(err error) error { if err == nil { return nil diff --git a/vendor/github.com/containerd/containerd/events/events.go b/vendor/github.com/containerd/containerd/events/events.go index 1ae0fc88074c9..efe2f598b92b2 100644 --- a/vendor/github.com/containerd/containerd/events/events.go +++ b/vendor/github.com/containerd/containerd/events/events.go @@ -6,6 +6,7 @@ import ( events "github.com/containerd/containerd/api/services/events/v1" ) +// Event is a generic interface for any type of event type Event interface{} // Publisher posts the event. @@ -13,6 +14,7 @@ type Publisher interface { Publish(ctx context.Context, topic string, event Event) error } +// Forwarder forwards an event to the underlying event bus type Forwarder interface { Forward(ctx context.Context, envelope *events.Envelope) error } @@ -23,6 +25,7 @@ func (fn publisherFunc) Publish(ctx context.Context, topic string, event Event) return fn(ctx, topic, event) } +// Subscriber allows callers to subscribe to events type Subscriber interface { Subscribe(ctx context.Context, filters ...string) (ch <-chan *events.Envelope, errs <-chan error) } diff --git a/vendor/github.com/containerd/containerd/events/exchange.go b/vendor/github.com/containerd/containerd/events/exchange.go index 93f6dfa91d37a..eeeeea36222bc 100644 --- a/vendor/github.com/containerd/containerd/events/exchange.go +++ b/vendor/github.com/containerd/containerd/events/exchange.go @@ -11,17 +11,19 @@ import ( "github.com/containerd/containerd/identifiers" "github.com/containerd/containerd/log" "github.com/containerd/containerd/namespaces" - "github.com/containerd/containerd/typeurl" + "github.com/containerd/typeurl" goevents "github.com/docker/go-events" "github.com/gogo/protobuf/types" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) +// Exchange broadcasts events type Exchange struct { broadcaster *goevents.Broadcaster } +// NewExchange returns a new event Exchange func NewExchange() *Exchange { return &Exchange{ broadcaster: goevents.NewBroadcaster(), diff --git a/vendor/github.com/containerd/containerd/export.go b/vendor/github.com/containerd/containerd/export.go index 8cafa1675c96e..76bebe3cd10ca 100644 --- a/vendor/github.com/containerd/containerd/export.go +++ b/vendor/github.com/containerd/containerd/export.go @@ -9,6 +9,7 @@ import ( "github.com/containerd/containerd/content" "github.com/containerd/containerd/images" + "github.com/containerd/containerd/platforms" ocispecs "github.com/opencontainers/image-spec/specs-go" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" @@ -32,7 +33,7 @@ func (c *Client) exportToOCITar(ctx context.Context, desc ocispec.Descriptor, wr } handlers := images.Handlers( - images.ChildrenHandler(cs), + images.ChildrenHandler(cs, platforms.Default()), images.HandlerFunc(exportHandler), ) diff --git a/vendor/github.com/containerd/containerd/filters/adaptor.go b/vendor/github.com/containerd/containerd/filters/adaptor.go index 27465afd89bb2..5a5ac7ec13404 100644 --- a/vendor/github.com/containerd/containerd/filters/adaptor.go +++ b/vendor/github.com/containerd/containerd/filters/adaptor.go @@ -8,8 +8,10 @@ type Adaptor interface { Field(fieldpath []string) (value string, present bool) } +// AdapterFunc allows implementation specific matching of fieldpaths type AdapterFunc func(fieldpath []string) (string, bool) +// Field returns the field name and true if it exists func (fn AdapterFunc) Field(fieldpath []string) (string, bool) { return fn(fieldpath) } diff --git a/vendor/github.com/containerd/containerd/filters/filter.go b/vendor/github.com/containerd/containerd/filters/filter.go index 2c9c3d7022922..621755762d5b5 100644 --- a/vendor/github.com/containerd/containerd/filters/filter.go +++ b/vendor/github.com/containerd/containerd/filters/filter.go @@ -58,22 +58,28 @@ import ( "github.com/containerd/containerd/log" ) +// Filter matches specific resources based the provided filter type Filter interface { Match(adaptor Adaptor) bool } +// FilterFunc is a function that handles matching with an adaptor type FilterFunc func(Adaptor) bool +// Match matches the FilterFunc returning true if the object matches the filter func (fn FilterFunc) Match(adaptor Adaptor) bool { return fn(adaptor) } +// Always is a filter that always returns true for any type of object var Always FilterFunc = func(adaptor Adaptor) bool { return true } +// Any allows multiple filters to be matched aginst the object type Any []Filter +// Match returns true if any of the provided filters are true func (m Any) Match(adaptor Adaptor) bool { for _, m := range m { if m.Match(adaptor) { @@ -84,8 +90,10 @@ func (m Any) Match(adaptor Adaptor) bool { return false } +// All allows multiple filters to be matched aginst the object type All []Filter +// Match only returns true if all filters match the object func (m All) Match(adaptor Adaptor) bool { for _, m := range m { if !m.Match(adaptor) { diff --git a/vendor/github.com/containerd/containerd/filters/scanner.go b/vendor/github.com/containerd/containerd/filters/scanner.go index 9c3fe2b756d23..5a55e0abf9d35 100644 --- a/vendor/github.com/containerd/containerd/filters/scanner.go +++ b/vendor/github.com/containerd/containerd/filters/scanner.go @@ -67,9 +67,8 @@ func (s *scanner) next() rune { if r == utf8.RuneError { if w > 0 { return tokenIllegal - } else { - return tokenEOF } + return tokenEOF } if r == 0 { diff --git a/vendor/github.com/containerd/containerd/fs/du.go b/vendor/github.com/containerd/containerd/fs/du.go index 8dfdaebdae8b0..61f439d3970fe 100644 --- a/vendor/github.com/containerd/containerd/fs/du.go +++ b/vendor/github.com/containerd/containerd/fs/du.go @@ -1,5 +1,6 @@ package fs +// Usage of disk information type Usage struct { Inodes int64 Size int64 diff --git a/vendor/github.com/containerd/containerd/fs/hardlink.go b/vendor/github.com/containerd/containerd/fs/hardlink.go index 4d5156f400a64..38da93813ce84 100644 --- a/vendor/github.com/containerd/containerd/fs/hardlink.go +++ b/vendor/github.com/containerd/containerd/fs/hardlink.go @@ -2,7 +2,7 @@ package fs import "os" -// GetLinkID returns an identifier representing the node a hardlink is pointing +// GetLinkInfo returns an identifier representing the node a hardlink is pointing // to. If the file is not hard linked then 0 will be returned. func GetLinkInfo(fi os.FileInfo) (uint64, bool) { return getLinkInfo(fi) diff --git a/vendor/github.com/containerd/containerd/gc/gc.go b/vendor/github.com/containerd/containerd/gc/gc.go new file mode 100644 index 0000000000000..70838a7627fa0 --- /dev/null +++ b/vendor/github.com/containerd/containerd/gc/gc.go @@ -0,0 +1,160 @@ +// Package gc experiments with providing central gc tooling to ensure +// deterministic resource removal within containerd. +// +// For now, we just have a single exported implementation that can be used +// under certain use cases. +package gc + +import ( + "context" + "sync" +) + +// ResourceType represents type of resource at a node +type ResourceType uint8 + +// Node presents a resource which has a type and key, +// this node can be used to lookup other nodes. +type Node struct { + Type ResourceType + Namespace string + Key string +} + +// Tricolor implements basic, single-thread tri-color GC. Given the roots, the +// complete set and a refs function, this function returns a map of all +// reachable objects. +// +// Correct usage requires that the caller not allow the arguments to change +// until the result is used to delete objects in the system. +// +// It will allocate memory proportional to the size of the reachable set. +// +// We can probably use this to inform a design for incremental GC by injecting +// callbacks to the set modification algorithms. +func Tricolor(roots []Node, refs func(ref Node) ([]Node, error)) (map[Node]struct{}, error) { + var ( + grays []Node // maintain a gray "stack" + seen = map[Node]struct{}{} // or not "white", basically "seen" + reachable = map[Node]struct{}{} // or "block", in tri-color parlance + ) + + grays = append(grays, roots...) + + for len(grays) > 0 { + // Pick any gray object + id := grays[len(grays)-1] // effectively "depth first" because first element + grays = grays[:len(grays)-1] + seen[id] = struct{}{} // post-mark this as not-white + rs, err := refs(id) + if err != nil { + return nil, err + } + + // mark all the referenced objects as gray + for _, target := range rs { + if _, ok := seen[target]; !ok { + grays = append(grays, target) + } + } + + // mark as black when done + reachable[id] = struct{}{} + } + + return reachable, nil +} + +// ConcurrentMark implements simple, concurrent GC. All the roots are scanned +// and the complete set of references is formed by calling the refs function +// for each seen object. This function returns a map of all object reachable +// from a root. +// +// Correct usage requires that the caller not allow the arguments to change +// until the result is used to delete objects in the system. +// +// It will allocate memory proportional to the size of the reachable set. +func ConcurrentMark(ctx context.Context, root <-chan Node, refs func(context.Context, Node, func(Node)) error) (map[Node]struct{}, error) { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + var ( + grays = make(chan Node) + seen = map[Node]struct{}{} // or not "white", basically "seen" + wg sync.WaitGroup + + errOnce sync.Once + refErr error + ) + + go func() { + for gray := range grays { + if _, ok := seen[gray]; ok { + wg.Done() + continue + } + seen[gray] = struct{}{} // post-mark this as non-white + + go func(gray Node) { + defer wg.Done() + + send := func(n Node) { + wg.Add(1) + select { + case grays <- n: + case <-ctx.Done(): + wg.Done() + } + } + + if err := refs(ctx, gray, send); err != nil { + errOnce.Do(func() { + refErr = err + cancel() + }) + } + + }(gray) + } + }() + + for r := range root { + wg.Add(1) + select { + case grays <- r: + case <-ctx.Done(): + wg.Done() + } + + } + + // Wait for outstanding grays to be processed + wg.Wait() + + close(grays) + + if refErr != nil { + return nil, refErr + } + if cErr := ctx.Err(); cErr != nil { + return nil, cErr + } + + return seen, nil +} + +// Sweep removes all nodes returned through the channel which are not in +// the reachable set by calling the provided remove function. +func Sweep(reachable map[Node]struct{}, all []Node, remove func(Node) error) error { + // All black objects are now reachable, and all white objects are + // unreachable. Free those that are white! + for _, node := range all { + if _, ok := reachable[node]; !ok { + if err := remove(node); err != nil { + return err + } + } + } + + return nil +} diff --git a/vendor/github.com/containerd/containerd/image.go b/vendor/github.com/containerd/containerd/image.go index 88f9b2e0f0439..426e15817edd5 100644 --- a/vendor/github.com/containerd/containerd/image.go +++ b/vendor/github.com/containerd/containerd/image.go @@ -2,11 +2,17 @@ package containerd import ( "context" + "fmt" + "time" + "github.com/containerd/containerd/content" + "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/rootfs" + "github.com/containerd/containerd/snapshot" digest "github.com/opencontainers/go-digest" + "github.com/opencontainers/image-spec/identity" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" ) @@ -25,6 +31,8 @@ type Image interface { Size(ctx context.Context) (int64, error) // Config descriptor for the image. Config(ctx context.Context) (ocispec.Descriptor, error) + // IsUnpacked returns whether or not an image is unpacked. + IsUnpacked(context.Context, string) (bool, error) } var _ = (Image)(&image{}) @@ -45,55 +53,107 @@ func (i *image) Target() ocispec.Descriptor { func (i *image) RootFS(ctx context.Context) ([]digest.Digest, error) { provider := i.client.ContentStore() - return i.i.RootFS(ctx, provider, platforms.Format(platforms.Default())) + return i.i.RootFS(ctx, provider, platforms.Default()) } func (i *image) Size(ctx context.Context) (int64, error) { provider := i.client.ContentStore() - return i.i.Size(ctx, provider) + return i.i.Size(ctx, provider, platforms.Default()) } func (i *image) Config(ctx context.Context) (ocispec.Descriptor, error) { provider := i.client.ContentStore() - return i.i.Config(ctx, provider, platforms.Format(platforms.Default())) + return i.i.Config(ctx, provider, platforms.Default()) +} + +func (i *image) IsUnpacked(ctx context.Context, snapshotterName string) (bool, error) { + sn := i.client.SnapshotService(snapshotterName) + cs := i.client.ContentStore() + + diffs, err := i.i.RootFS(ctx, cs, platforms.Default()) + if err != nil { + return false, err + } + + chainID := identity.ChainID(diffs) + _, err = sn.Stat(ctx, chainID.String()) + if err == nil { + return true, nil + } else if !errdefs.IsNotFound(err) { + return false, err + } + + return false, nil } func (i *image) Unpack(ctx context.Context, snapshotterName string) error { - layers, err := i.getLayers(ctx, platforms.Format(platforms.Default())) + layers, err := i.getLayers(ctx, platforms.Default()) if err != nil { return err } - sn := i.client.SnapshotService(snapshotterName) - a := i.client.DiffService() - cs := i.client.ContentStore() + var ( + sn = i.client.SnapshotService(snapshotterName) + a = i.client.DiffService() + cs = i.client.ContentStore() - var chain []digest.Digest + chain []digest.Digest + unpacked bool + ) for _, layer := range layers { - unpacked, err := rootfs.ApplyLayer(ctx, layer, chain, sn, a) + labels := map[string]string{ + "containerd.io/gc.root": time.Now().UTC().Format(time.RFC3339), + "containerd.io/uncompressed": layer.Diff.Digest.String(), + } + lastUnpacked := unpacked + + unpacked, err = rootfs.ApplyLayer(ctx, layer, chain, sn, a, snapshot.WithLabels(labels)) if err != nil { - // TODO: possibly wait and retry if extraction of same chain id was in progress return err } - if unpacked { - info, err := cs.Info(ctx, layer.Blob.Digest) - if err != nil { - return err + + if lastUnpacked { + info := snapshot.Info{ + Name: identity.ChainID(chain).String(), } - if info.Labels["containerd.io/uncompressed"] != layer.Diff.Digest.String() { - if info.Labels == nil { - info.Labels = map[string]string{} - } - info.Labels["containerd.io/uncompressed"] = layer.Diff.Digest.String() - if _, err := cs.Update(ctx, info, "labels.containerd.io/uncompressed"); err != nil { - return err - } + + // Remove previously created gc.root label + if _, err := sn.Update(ctx, info, "labels.containerd.io/gc.root"); err != nil { + return err } } chain = append(chain, layer.Diff.Digest) } + if unpacked { + desc, err := i.i.Config(ctx, cs, platforms.Default()) + if err != nil { + return err + } + + rootfs := identity.ChainID(chain).String() + + cinfo := content.Info{ + Digest: desc.Digest, + Labels: map[string]string{ + fmt.Sprintf("containerd.io/gc.ref.snapshot.%s", snapshotterName): rootfs, + }, + } + if _, err := cs.Update(ctx, cinfo, fmt.Sprintf("labels.containerd.io/gc.ref.snapshot.%s", snapshotterName)); err != nil { + return err + } + + sinfo := snapshot.Info{ + Name: rootfs, + } + + // Config now referenced snapshot, release root reference + if _, err := sn.Update(ctx, sinfo, "labels.containerd.io/gc.root"); err != nil { + return err + } + } + return nil } diff --git a/vendor/github.com/containerd/containerd/images/handlers.go b/vendor/github.com/containerd/containerd/images/handlers.go index 53248f018229b..63acdb7220b4f 100644 --- a/vendor/github.com/containerd/containerd/images/handlers.go +++ b/vendor/github.com/containerd/containerd/images/handlers.go @@ -2,48 +2,49 @@ package images import ( "context" - "encoding/json" "fmt" "github.com/containerd/containerd/content" - "github.com/containerd/containerd/log" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" "golang.org/x/sync/errgroup" ) var ( - // SkipDesc is used to skip processing of a descriptor and + // ErrSkipDesc is used to skip processing of a descriptor and // its descendants. - SkipDesc = fmt.Errorf("skip descriptor") + ErrSkipDesc = fmt.Errorf("skip descriptor") - // StopHandler is used to signify that the descriptor + // ErrStopHandler is used to signify that the descriptor // has been handled and should not be handled further. // This applies only to a single descriptor in a handler // chain and does not apply to descendant descriptors. - StopHandler = fmt.Errorf("stop handler") + ErrStopHandler = fmt.Errorf("stop handler") ) +// Handler handles image manifests type Handler interface { Handle(ctx context.Context, desc ocispec.Descriptor) (subdescs []ocispec.Descriptor, err error) } +// HandlerFunc function implementing the Handler interface type HandlerFunc func(ctx context.Context, desc ocispec.Descriptor) (subdescs []ocispec.Descriptor, err error) +// Handle image manifests func (fn HandlerFunc) Handle(ctx context.Context, desc ocispec.Descriptor) (subdescs []ocispec.Descriptor, err error) { return fn(ctx, desc) } // Handlers returns a handler that will run the handlers in sequence. // -// A handler may return `StopHandler` to stop calling additional handlers +// A handler may return `ErrStopHandler` to stop calling additional handlers func Handlers(handlers ...Handler) HandlerFunc { return func(ctx context.Context, desc ocispec.Descriptor) (subdescs []ocispec.Descriptor, err error) { var children []ocispec.Descriptor for _, handler := range handlers { ch, err := handler.Handle(ctx, desc) if err != nil { - if errors.Cause(err) == StopHandler { + if errors.Cause(err) == ErrStopHandler { break } return nil, err @@ -66,7 +67,7 @@ func Walk(ctx context.Context, handler Handler, descs ...ocispec.Descriptor) err children, err := handler.Handle(ctx, desc) if err != nil { - if errors.Cause(err) == SkipDesc { + if errors.Cause(err) == ErrSkipDesc { continue // don't traverse the children. } return err @@ -86,7 +87,7 @@ func Walk(ctx context.Context, handler Handler, descs ...ocispec.Descriptor) err // If the handler decode subresources, they will be visited, as well. // // Handlers for siblings are run in parallel on the provided descriptors. A -// handler may return `SkipDesc` to signal to the dispatcher to not traverse +// handler may return `ErrSkipDesc` to signal to the dispatcher to not traverse // any children. // // Typically, this function will be used with `FetchHandler`, often composed @@ -103,7 +104,7 @@ func Dispatch(ctx context.Context, handler Handler, descs ...ocispec.Descriptor) children, err := handler.Handle(ctx, desc) if err != nil { - if errors.Cause(err) == SkipDesc { + if errors.Cause(err) == ErrSkipDesc { return nil // don't traverse the children. } return err @@ -120,53 +121,15 @@ func Dispatch(ctx context.Context, handler Handler, descs ...ocispec.Descriptor) return eg.Wait() } -// ChildrenHandler decodes well-known manifests types and returns their children. +// ChildrenHandler decodes well-known manifest types and returns their children. // // This is useful for supporting recursive fetch and other use cases where you // want to do a full walk of resources. // // One can also replace this with another implementation to allow descending of // arbitrary types. -func ChildrenHandler(provider content.Provider) HandlerFunc { +func ChildrenHandler(provider content.Provider, platform string) HandlerFunc { return func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { - var descs []ocispec.Descriptor - switch desc.MediaType { - case MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest: - p, err := content.ReadBlob(ctx, provider, desc.Digest) - if err != nil { - return nil, err - } - - // TODO(stevvooe): We just assume oci manifest, for now. There may be - // subtle differences from the docker version. - var manifest ocispec.Manifest - if err := json.Unmarshal(p, &manifest); err != nil { - return nil, err - } - - descs = append(descs, manifest.Config) - descs = append(descs, manifest.Layers...) - case MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex: - p, err := content.ReadBlob(ctx, provider, desc.Digest) - if err != nil { - return nil, err - } - - var index ocispec.Index - if err := json.Unmarshal(p, &index); err != nil { - return nil, err - } - - descs = append(descs, index.Manifests...) - case MediaTypeDockerSchema2Layer, MediaTypeDockerSchema2LayerGzip, - MediaTypeDockerSchema2Config, ocispec.MediaTypeImageConfig, - ocispec.MediaTypeImageLayer, ocispec.MediaTypeImageLayerGzip: - // childless data types. - return nil, nil - default: - log.G(ctx).Warnf("encountered unknown type %v; children may not be fetched", desc.MediaType) - } - - return descs, nil + return Children(ctx, provider, desc, platform) } } diff --git a/vendor/github.com/containerd/containerd/images/image.go b/vendor/github.com/containerd/containerd/images/image.go index 674cf087495e2..4c78c6cc2dfb2 100644 --- a/vendor/github.com/containerd/containerd/images/image.go +++ b/vendor/github.com/containerd/containerd/images/image.go @@ -7,6 +7,7 @@ import ( "github.com/containerd/containerd/content" "github.com/containerd/containerd/errdefs" + "github.com/containerd/containerd/log" "github.com/containerd/containerd/platforms" digest "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" @@ -15,12 +16,29 @@ import ( // Image provides the model for how containerd views container images. type Image struct { - Name string - Labels map[string]string - Target ocispec.Descriptor + // Name of the image. + // + // To be pulled, it must be a reference compatible with resolvers. + // + // This field is required. + Name string + + // Labels provide runtime decoration for the image record. + // + // There is no default behavior for how these labels are propagated. They + // only decorate the static metadata object. + // + // This field is optional. + Labels map[string]string + + // Target describes the root content for this image. Typically, this is + // a manifest, index or manifest list. + Target ocispec.Descriptor + CreatedAt, UpdatedAt time.Time } +// Store and interact with images type Store interface { Get(ctx context.Context, name string) (Image, error) List(ctx context.Context, filters ...string) ([]Image, error) @@ -58,7 +76,7 @@ func (image *Image) RootFS(ctx context.Context, provider content.Provider, platf } // Size returns the total size of an image's packed resources. -func (image *Image) Size(ctx context.Context, provider content.Provider) (int64, error) { +func (image *Image) Size(ctx context.Context, provider content.Provider, platform string) (int64, error) { var size int64 return size, Walk(ctx, Handlers(HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { if desc.Size < 0 { @@ -66,9 +84,15 @@ func (image *Image) Size(ctx context.Context, provider content.Provider) (int64, } size += desc.Size return nil, nil - }), ChildrenHandler(provider)), image.Target) + }), ChildrenHandler(provider, platform)), image.Target) } +// Manifest resolves a manifest from the image for the given platform. +// +// TODO(stevvooe): This violates the current platform agnostic approach to this +// package by returning a specific manifest type. We'll need to refactor this +// to return a manifest descriptor or decide that we want to bring the API in +// this direction because this abstraction is not needed.` func Manifest(ctx context.Context, provider content.Provider, image ocispec.Descriptor, platform string) (ocispec.Manifest, error) { var ( matcher platforms.Matcher @@ -146,7 +170,7 @@ func Manifest(ctx context.Context, provider content.Provider, image ocispec.Desc return descs, nil } - return nil, errors.New("could not resolve manifest") + return nil, errors.Wrap(errdefs.ErrNotFound, "could not resolve manifest") }), image); err != nil { return ocispec.Manifest{}, err } @@ -177,7 +201,7 @@ func Platforms(ctx context.Context, provider content.Provider, image ocispec.Des return platformSpecs, Walk(ctx, Handlers(HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { if desc.Platform != nil { platformSpecs = append(platformSpecs, *desc.Platform) - return nil, SkipDesc + return nil, ErrSkipDesc } switch desc.MediaType { @@ -196,7 +220,110 @@ func Platforms(ctx context.Context, provider content.Provider, image ocispec.Des platforms.Normalize(ocispec.Platform{OS: image.OS, Architecture: image.Architecture})) } return nil, nil - }), ChildrenHandler(provider)), image) + }), ChildrenHandler(provider, "")), image) +} + +// Check returns nil if the all components of an image are available in the +// provider for the specified platform. +// +// If available is true, the caller can assume that required represents the +// complete set of content required for the image. +// +// missing will have the components that are part of required but not avaiiable +// in the provider. +// +// If there is a problem resolving content, an error will be returned. +func Check(ctx context.Context, provider content.Provider, image ocispec.Descriptor, platform string) (available bool, required, present, missing []ocispec.Descriptor, err error) { + mfst, err := Manifest(ctx, provider, image, platform) + if err != nil { + if errdefs.IsNotFound(err) { + return false, []ocispec.Descriptor{image}, nil, []ocispec.Descriptor{image}, nil + } + + return false, nil, nil, nil, errors.Wrap(err, "image check failed") + } + + // TODO(stevvooe): It is possible that referenced conponents could have + // children, but this is rare. For now, we ignore this and only verify + // that manfiest components are present. + required = append([]ocispec.Descriptor{mfst.Config}, mfst.Layers...) + + for _, desc := range required { + ra, err := provider.ReaderAt(ctx, desc.Digest) + if err != nil { + if errdefs.IsNotFound(err) { + missing = append(missing, desc) + continue + } else { + return false, nil, nil, nil, err + } + } + ra.Close() + present = append(present, desc) + + } + + return true, required, present, missing, nil +} + +// Children returns the immediate children of content described by the descriptor. +func Children(ctx context.Context, provider content.Provider, desc ocispec.Descriptor, platform string) ([]ocispec.Descriptor, error) { + var descs []ocispec.Descriptor + switch desc.MediaType { + case MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest: + p, err := content.ReadBlob(ctx, provider, desc.Digest) + if err != nil { + return nil, err + } + + // TODO(stevvooe): We just assume oci manifest, for now. There may be + // subtle differences from the docker version. + var manifest ocispec.Manifest + if err := json.Unmarshal(p, &manifest); err != nil { + return nil, err + } + + descs = append(descs, manifest.Config) + descs = append(descs, manifest.Layers...) + case MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex: + p, err := content.ReadBlob(ctx, provider, desc.Digest) + if err != nil { + return nil, err + } + + var index ocispec.Index + if err := json.Unmarshal(p, &index); err != nil { + return nil, err + } + + if platform != "" { + matcher, err := platforms.Parse(platform) + if err != nil { + return nil, err + } + + for _, d := range index.Manifests { + if d.Platform == nil || matcher.Match(*d.Platform) { + descs = append(descs, d) + } + } + } else { + descs = append(descs, index.Manifests...) + } + + case MediaTypeDockerSchema2Layer, MediaTypeDockerSchema2LayerGzip, + MediaTypeDockerSchema2LayerForeign, MediaTypeDockerSchema2LayerForeignGzip, + MediaTypeDockerSchema2Config, ocispec.MediaTypeImageConfig, + ocispec.MediaTypeImageLayer, ocispec.MediaTypeImageLayerGzip, + ocispec.MediaTypeImageLayerNonDistributable, ocispec.MediaTypeImageLayerNonDistributableGzip, + MediaTypeContainerd1Checkpoint, MediaTypeContainerd1CheckpointConfig: + // childless data types. + return nil, nil + default: + log.G(ctx).Warnf("encountered unknown type %v; children may not be fetched", desc.MediaType) + } + + return descs, nil } // RootFS returns the unpacked diffids that make up and images rootfs. diff --git a/vendor/github.com/containerd/containerd/images/mediatypes.go b/vendor/github.com/containerd/containerd/images/mediatypes.go index 445cf2e09bf65..f01f615c4baa0 100644 --- a/vendor/github.com/containerd/containerd/images/mediatypes.go +++ b/vendor/github.com/containerd/containerd/images/mediatypes.go @@ -5,11 +5,13 @@ package images // oci components are generally referenced directly, although we may centralize // here for clarity. const ( - MediaTypeDockerSchema2Layer = "application/vnd.docker.image.rootfs.diff.tar" - MediaTypeDockerSchema2LayerGzip = "application/vnd.docker.image.rootfs.diff.tar.gzip" - MediaTypeDockerSchema2Config = "application/vnd.docker.container.image.v1+json" - MediaTypeDockerSchema2Manifest = "application/vnd.docker.distribution.manifest.v2+json" - MediaTypeDockerSchema2ManifestList = "application/vnd.docker.distribution.manifest.list.v2+json" + MediaTypeDockerSchema2Layer = "application/vnd.docker.image.rootfs.diff.tar" + MediaTypeDockerSchema2LayerForeign = "application/vnd.docker.image.rootfs.foreign.diff.tar" + MediaTypeDockerSchema2LayerGzip = "application/vnd.docker.image.rootfs.diff.tar.gzip" + MediaTypeDockerSchema2LayerForeignGzip = "application/vnd.docker.image.rootfs.foreign.diff.tar.gzip" + MediaTypeDockerSchema2Config = "application/vnd.docker.container.image.v1+json" + MediaTypeDockerSchema2Manifest = "application/vnd.docker.distribution.manifest.v2+json" + MediaTypeDockerSchema2ManifestList = "application/vnd.docker.distribution.manifest.list.v2+json" // Checkpoint/Restore Media Types MediaTypeContainerd1Checkpoint = "application/vnd.containerd.container.criu.checkpoint.criu.tar" MediaTypeContainerd1CheckpointPreDump = "application/vnd.containerd.container.criu.checkpoint.predump.tar" diff --git a/vendor/github.com/containerd/containerd/import.go b/vendor/github.com/containerd/containerd/import.go index a8fe63ffe4424..9f8f9af7d7050 100644 --- a/vendor/github.com/containerd/containerd/import.go +++ b/vendor/github.com/containerd/containerd/import.go @@ -68,6 +68,7 @@ func (c *Client) importFromOCITar(ctx context.Context, ref string, reader io.Rea imgrec := images.Image{ Name: ref, Target: *desc, + Labels: iopts.labels, } is := c.ImageService() if updated, err := is.Update(ctx, imgrec, "target"); err != nil { diff --git a/vendor/github.com/containerd/containerd/io.go b/vendor/github.com/containerd/containerd/io.go index 108af6bb2ea61..48c06f12e243d 100644 --- a/vendor/github.com/containerd/containerd/io.go +++ b/vendor/github.com/containerd/containerd/io.go @@ -68,6 +68,10 @@ func (c *cio) Close() error { type IOCreation func(id string) (IO, error) // IOAttach allows callers to reattach to running tasks +// +// There should only be one reader for a task's IO set +// because fifo's can only be read from one reader or the output +// will be sent only to the first reads type IOAttach func(*FIFOSet) (IO, error) // NewIO returns an IOCreation that will provide IO sets without a terminal diff --git a/vendor/github.com/containerd/containerd/io_unix.go b/vendor/github.com/containerd/containerd/io_unix.go index 3da6de2cac067..08aba14bac803 100644 --- a/vendor/github.com/containerd/containerd/io_unix.go +++ b/vendor/github.com/containerd/containerd/io_unix.go @@ -16,7 +16,7 @@ import ( // NewFifos returns a new set of fifos for the task func NewFifos(id string) (*FIFOSet, error) { - root := filepath.Join(os.TempDir(), "containerd") + root := "/run/containerd/fifo" if err := os.MkdirAll(root, 0700); err != nil { return nil, err } @@ -119,6 +119,7 @@ func NewDirectIO(ctx context.Context, terminal bool) (*DirectIO, error) { return f, nil } +// DirectIO allows task IO to be handled externally by the caller type DirectIO struct { Stdin io.WriteCloser Stdout io.ReadCloser @@ -128,14 +129,17 @@ type DirectIO struct { terminal bool } +// IOCreate returns IO avaliable for use with task creation func (f *DirectIO) IOCreate(id string) (IO, error) { return f, nil } +// IOAttach returns IO avaliable for use with task attachment func (f *DirectIO) IOAttach(set *FIFOSet) (IO, error) { return f, nil } +// Config returns the IOConfig func (f *DirectIO) Config() IOConfig { return IOConfig{ Terminal: f.terminal, @@ -145,14 +149,21 @@ func (f *DirectIO) Config() IOConfig { } } +// Cancel stops any IO copy operations +// +// Not applicable for DirectIO func (f *DirectIO) Cancel() { // nothing to cancel as all operations are handled externally } +// Wait on any IO copy operations +// +// Not applicable for DirectIO func (f *DirectIO) Wait() { // nothing to wait on as all operations are handled externally } +// Close closes all open fds func (f *DirectIO) Close() error { err := f.Stdin.Close() if err2 := f.Stdout.Close(); err == nil { @@ -164,6 +175,7 @@ func (f *DirectIO) Close() error { return err } +// Delete removes the underlying directory containing fifos func (f *DirectIO) Delete() error { if f.set.Dir == "" { return nil diff --git a/vendor/github.com/containerd/containerd/labels/validate.go b/vendor/github.com/containerd/containerd/labels/validate.go new file mode 100644 index 0000000000000..b05fe1857c7d3 --- /dev/null +++ b/vendor/github.com/containerd/containerd/labels/validate.go @@ -0,0 +1,21 @@ +package labels + +import ( + "github.com/containerd/containerd/errdefs" + "github.com/pkg/errors" +) + +const ( + maxSize = 4096 +) + +// Validate a label's key and value are under 4096 bytes +func Validate(k, v string) error { + if (len(k) + len(v)) > maxSize { + if len(k) > 10 { + k = k[:10] + } + return errors.Wrapf(errdefs.ErrInvalidArgument, "label key and value greater than maximum size (%d bytes), key: %s", maxSize, k) + } + return nil +} diff --git a/vendor/github.com/containerd/containerd/linux/runcopts/runc.pb.go b/vendor/github.com/containerd/containerd/linux/runcopts/runc.pb.go index 0a5c3b72f8b30..0415e23d57898 100644 --- a/vendor/github.com/containerd/containerd/linux/runcopts/runc.pb.go +++ b/vendor/github.com/containerd/containerd/linux/runcopts/runc.pb.go @@ -57,6 +57,8 @@ type CreateOptions struct { CgroupsMode string `protobuf:"bytes,7,opt,name=cgroups_mode,json=cgroupsMode,proto3" json:"cgroups_mode,omitempty"` NoNewKeyring bool `protobuf:"varint,8,opt,name=no_new_keyring,json=noNewKeyring,proto3" json:"no_new_keyring,omitempty"` ShimCgroup string `protobuf:"bytes,9,opt,name=shim_cgroup,json=shimCgroup,proto3" json:"shim_cgroup,omitempty"` + IoUid uint32 `protobuf:"varint,10,opt,name=io_uid,json=ioUid,proto3" json:"io_uid,omitempty"` + IoGid uint32 `protobuf:"varint,11,opt,name=io_gid,json=ioGid,proto3" json:"io_gid,omitempty"` } func (m *CreateOptions) Reset() { *m = CreateOptions{} } @@ -230,6 +232,16 @@ func (m *CreateOptions) MarshalTo(dAtA []byte) (int, error) { i = encodeVarintRunc(dAtA, i, uint64(len(m.ShimCgroup))) i += copy(dAtA[i:], m.ShimCgroup) } + if m.IoUid != 0 { + dAtA[i] = 0x50 + i++ + i = encodeVarintRunc(dAtA, i, uint64(m.IoUid)) + } + if m.IoGid != 0 { + dAtA[i] = 0x58 + i++ + i = encodeVarintRunc(dAtA, i, uint64(m.IoGid)) + } return i, nil } @@ -405,6 +417,12 @@ func (m *CreateOptions) Size() (n int) { if l > 0 { n += 1 + l + sovRunc(uint64(l)) } + if m.IoUid != 0 { + n += 1 + sovRunc(uint64(m.IoUid)) + } + if m.IoGid != 0 { + n += 1 + sovRunc(uint64(m.IoGid)) + } return n } @@ -479,6 +497,8 @@ func (this *CreateOptions) String() string { `CgroupsMode:` + fmt.Sprintf("%v", this.CgroupsMode) + `,`, `NoNewKeyring:` + fmt.Sprintf("%v", this.NoNewKeyring) + `,`, `ShimCgroup:` + fmt.Sprintf("%v", this.ShimCgroup) + `,`, + `IoUid:` + fmt.Sprintf("%v", this.IoUid) + `,`, + `IoGid:` + fmt.Sprintf("%v", this.IoGid) + `,`, `}`, }, "") return s @@ -900,6 +920,44 @@ func (m *CreateOptions) Unmarshal(dAtA []byte) error { } m.ShimCgroup = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IoUid", wireType) + } + m.IoUid = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRunc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.IoUid |= (uint32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IoGid", wireType) + } + m.IoGid = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRunc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.IoGid |= (uint32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipRunc(dAtA[iNdEx:]) @@ -1239,35 +1297,36 @@ func init() { } var fileDescriptorRunc = []byte{ - // 467 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x93, 0x41, 0x6f, 0xd3, 0x40, - 0x10, 0x85, 0xbb, 0x6d, 0x69, 0x9d, 0x4d, 0x53, 0x60, 0xa1, 0x92, 0x29, 0xc2, 0x84, 0x08, 0xa4, - 0x70, 0x49, 0x24, 0xb8, 0x20, 0xb8, 0x91, 0x23, 0x50, 0x2a, 0x03, 0x17, 0x2e, 0x2b, 0x77, 0x33, - 0x24, 0xab, 0xd8, 0x33, 0xab, 0xdd, 0x35, 0x75, 0x6e, 0xfc, 0x02, 0x7e, 0x57, 0x8f, 0x88, 0x13, - 0x47, 0x9a, 0x3f, 0x02, 0xf2, 0xda, 0x2e, 0x5c, 0xb9, 0x72, 0x7b, 0xf3, 0xbd, 0xb1, 0xe7, 0xe9, - 0x49, 0xcb, 0x9f, 0x2f, 0xb4, 0x5f, 0x96, 0x67, 0x13, 0x45, 0xc5, 0x54, 0x11, 0xfa, 0x4c, 0x23, - 0xd8, 0xf9, 0xdf, 0x32, 0xd7, 0x58, 0x56, 0x53, 0x5b, 0xa2, 0x22, 0xe3, 0x5d, 0x10, 0x13, 0x63, - 0xc9, 0x93, 0x38, 0xfa, 0xb3, 0x35, 0x09, 0x5b, 0x93, 0xda, 0x3c, 0xbe, 0xbd, 0xa0, 0x05, 0x85, - 0x8d, 0x69, 0xad, 0x9a, 0xe5, 0xd1, 0x57, 0xc6, 0xfb, 0x69, 0x89, 0xea, 0xad, 0xf1, 0x9a, 0xd0, - 0x89, 0x98, 0xef, 0xdb, 0x12, 0xbd, 0x2e, 0x20, 0x66, 0x43, 0x36, 0xee, 0xa5, 0xdd, 0x28, 0x1e, - 0xf0, 0x83, 0x56, 0x4a, 0x4b, 0xe4, 0xe3, 0xed, 0x60, 0xf7, 0x5b, 0x96, 0x12, 0x79, 0x71, 0x97, - 0xf7, 0x94, 0xd5, 0xa5, 0x34, 0x99, 0x5f, 0xc6, 0x3b, 0xc1, 0x8f, 0x6a, 0x70, 0x9a, 0xf9, 0xa5, - 0x78, 0xc4, 0x0f, 0xdd, 0xda, 0x79, 0x28, 0xe6, 0x52, 0x2d, 0x2c, 0x95, 0x26, 0xde, 0x1d, 0xb2, - 0x71, 0x94, 0x0e, 0x5a, 0x3a, 0x0b, 0x70, 0xf4, 0x7d, 0x9b, 0x0f, 0x66, 0x16, 0x32, 0x0f, 0x5d, - 0xa4, 0x11, 0x1f, 0x20, 0x49, 0xa3, 0x3f, 0x93, 0x6f, 0x2e, 0xb3, 0xf0, 0x5d, 0x1f, 0xe9, 0xb4, - 0x66, 0xe1, 0xf2, 0x1d, 0x1e, 0x91, 0x01, 0x94, 0x5e, 0x99, 0x10, 0x2c, 0x4a, 0xf7, 0xeb, 0xf9, - 0xbd, 0x32, 0xe2, 0x09, 0x3f, 0x82, 0xca, 0x83, 0xc5, 0x2c, 0x97, 0x25, 0xea, 0x4a, 0x3a, 0x52, - 0x2b, 0xf0, 0x2e, 0x04, 0x8c, 0xd2, 0x5b, 0x9d, 0xf9, 0x01, 0x75, 0xf5, 0xae, 0xb1, 0xc4, 0x31, - 0x8f, 0x3c, 0xd8, 0x42, 0x63, 0x96, 0xb7, 0x29, 0xaf, 0x66, 0x71, 0x8f, 0xf3, 0x4f, 0x3a, 0x07, - 0x99, 0x93, 0x5a, 0xb9, 0xf8, 0x5a, 0x70, 0x7b, 0x35, 0x79, 0x5d, 0x03, 0xf1, 0x98, 0xdf, 0x80, - 0xc2, 0xf8, 0xb5, 0xc4, 0xac, 0x00, 0x67, 0x32, 0x05, 0x2e, 0xde, 0x1b, 0xee, 0x8c, 0x7b, 0xe9, - 0xf5, 0xc0, 0x4f, 0xae, 0x70, 0xdd, 0x68, 0xd3, 0x84, 0x93, 0x05, 0xcd, 0x21, 0xde, 0x6f, 0x1a, - 0x6d, 0xd9, 0x1b, 0x9a, 0x83, 0x78, 0xc8, 0x0f, 0x91, 0x24, 0xc2, 0xb9, 0x5c, 0xc1, 0xda, 0x6a, - 0x5c, 0xc4, 0x51, 0x38, 0x78, 0x80, 0x74, 0x02, 0xe7, 0xaf, 0x1a, 0x26, 0xee, 0xf3, 0xbe, 0x5b, - 0xea, 0xa2, 0xeb, 0xb5, 0x17, 0xfe, 0xc3, 0x6b, 0xd4, 0x96, 0xfa, 0x8b, 0xf1, 0x9b, 0xb3, 0x25, - 0xa8, 0x95, 0x21, 0x8d, 0xbe, 0x2b, 0x56, 0xf0, 0x5d, 0xa8, 0x74, 0xd7, 0x67, 0xd0, 0xff, 0x6b, - 0x91, 0x2f, 0xd3, 0x8b, 0xcb, 0x64, 0xeb, 0xc7, 0x65, 0xb2, 0xf5, 0x65, 0x93, 0xb0, 0x8b, 0x4d, - 0xc2, 0xbe, 0x6d, 0x12, 0xf6, 0x73, 0x93, 0xb0, 0x8f, 0xcf, 0xfe, 0xf1, 0xa9, 0xbd, 0xe8, 0xc4, - 0xd9, 0x5e, 0x78, 0x42, 0x4f, 0x7f, 0x07, 0x00, 0x00, 0xff, 0xff, 0xe6, 0x26, 0x29, 0x60, 0xad, - 0x03, 0x00, 0x00, + // 495 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x93, 0x31, 0x6f, 0xd3, 0x40, + 0x14, 0xc7, 0x7b, 0xb4, 0x4d, 0x9c, 0x4b, 0x53, 0xe0, 0x20, 0xd2, 0x51, 0x84, 0x09, 0x11, 0x48, + 0x61, 0x49, 0x24, 0x58, 0x10, 0x6c, 0x64, 0x60, 0x00, 0x4a, 0x65, 0xe8, 0xc2, 0x72, 0x72, 0xcf, + 0x87, 0xf3, 0x94, 0xf8, 0xde, 0xe9, 0xee, 0x4c, 0x93, 0xad, 0x9f, 0x80, 0xcf, 0xd5, 0x91, 0x91, + 0x91, 0xe6, 0x8b, 0x80, 0x7c, 0xb6, 0x0b, 0x2b, 0x2b, 0xdb, 0xff, 0xfd, 0xfe, 0xcf, 0x7e, 0x4f, + 0xff, 0xd3, 0xa3, 0x2f, 0x73, 0xf0, 0x8b, 0xf2, 0x6c, 0x2a, 0xb1, 0x98, 0x49, 0xd4, 0x3e, 0x05, + 0xad, 0x6c, 0xf6, 0xb7, 0x5c, 0x81, 0x2e, 0xd7, 0x33, 0x5b, 0x6a, 0x89, 0xc6, 0xbb, 0x20, 0xa6, + 0xc6, 0xa2, 0x47, 0x36, 0xfc, 0xd3, 0x35, 0x0d, 0x5d, 0xd3, 0xca, 0x3c, 0xba, 0x9b, 0x63, 0x8e, + 0xa1, 0x63, 0x56, 0xa9, 0xba, 0x79, 0xfc, 0x8d, 0xd0, 0x7e, 0x52, 0x6a, 0xf9, 0xc1, 0x78, 0x40, + 0xed, 0x18, 0xa7, 0x5d, 0x5b, 0x6a, 0x0f, 0x85, 0xe2, 0x64, 0x44, 0x26, 0xbd, 0xa4, 0x2d, 0xd9, + 0x23, 0x7a, 0xd0, 0x48, 0x61, 0x11, 0x3d, 0xbf, 0x11, 0xec, 0x7e, 0xc3, 0x12, 0x44, 0xcf, 0xee, + 0xd3, 0x9e, 0xb4, 0x50, 0x0a, 0x93, 0xfa, 0x05, 0xdf, 0x0d, 0x7e, 0x54, 0x81, 0x93, 0xd4, 0x2f, + 0xd8, 0x13, 0x7a, 0xe8, 0x36, 0xce, 0xab, 0x22, 0x13, 0x32, 0xb7, 0x58, 0x1a, 0xbe, 0x37, 0x22, + 0x93, 0x28, 0x19, 0x34, 0x74, 0x1e, 0xe0, 0xf8, 0x62, 0x97, 0x0e, 0xe6, 0x56, 0xa5, 0x5e, 0xb5, + 0x2b, 0x8d, 0xe9, 0x40, 0xa3, 0x30, 0xf0, 0x15, 0x7d, 0x3d, 0x99, 0x84, 0xef, 0xfa, 0x1a, 0x4f, + 0x2a, 0x16, 0x26, 0xdf, 0xa3, 0x11, 0x1a, 0xa5, 0x85, 0x97, 0x26, 0x2c, 0x16, 0x25, 0xdd, 0xaa, + 0xfe, 0x24, 0x0d, 0x7b, 0x46, 0x87, 0x6a, 0xed, 0x95, 0xd5, 0xe9, 0x4a, 0x94, 0x1a, 0xd6, 0xc2, + 0xa1, 0x5c, 0x2a, 0xef, 0xc2, 0x82, 0x51, 0x72, 0xa7, 0x35, 0x4f, 0x35, 0xac, 0x3f, 0xd6, 0x16, + 0x3b, 0xa2, 0x91, 0x57, 0xb6, 0x00, 0x9d, 0xae, 0x9a, 0x2d, 0xaf, 0x6b, 0xf6, 0x80, 0xd2, 0x2f, + 0xb0, 0x52, 0x62, 0x85, 0x72, 0xe9, 0xf8, 0x7e, 0x70, 0x7b, 0x15, 0x79, 0x57, 0x01, 0xf6, 0x94, + 0xde, 0x52, 0x85, 0xf1, 0x1b, 0xa1, 0xd3, 0x42, 0x39, 0x93, 0x4a, 0xe5, 0x78, 0x67, 0xb4, 0x3b, + 0xe9, 0x25, 0x37, 0x03, 0x3f, 0xbe, 0xc6, 0x55, 0xa2, 0x75, 0x12, 0x4e, 0x14, 0x98, 0x29, 0xde, + 0xad, 0x13, 0x6d, 0xd8, 0x7b, 0xcc, 0x14, 0x7b, 0x4c, 0x0f, 0x35, 0x0a, 0xad, 0xce, 0xc5, 0x52, + 0x6d, 0x2c, 0xe8, 0x9c, 0x47, 0x61, 0xe0, 0x81, 0xc6, 0x63, 0x75, 0xfe, 0xb6, 0x66, 0xec, 0x21, + 0xed, 0xbb, 0x05, 0x14, 0x6d, 0xae, 0xbd, 0xf0, 0x1f, 0x5a, 0xa1, 0x3a, 0x54, 0x36, 0xa4, 0x1d, + 0x40, 0x51, 0x42, 0xc6, 0xe9, 0x88, 0x4c, 0x06, 0xc9, 0x3e, 0xe0, 0x29, 0x64, 0x0d, 0xce, 0x21, + 0xe3, 0xfd, 0x16, 0xbf, 0x81, 0x6c, 0xfc, 0x8b, 0xd0, 0xdb, 0xf3, 0x85, 0x92, 0x4b, 0x83, 0xa0, + 0x7d, 0xfb, 0x0c, 0x8c, 0xee, 0xa9, 0x35, 0xb4, 0xe9, 0x07, 0xfd, 0xbf, 0xc6, 0xfe, 0x3a, 0xb9, + 0xbc, 0x8a, 0x77, 0x7e, 0x5c, 0xc5, 0x3b, 0x17, 0xdb, 0x98, 0x5c, 0x6e, 0x63, 0xf2, 0x7d, 0x1b, + 0x93, 0x9f, 0xdb, 0x98, 0x7c, 0x7e, 0xf1, 0x8f, 0x87, 0xf9, 0xaa, 0x15, 0x67, 0x9d, 0x70, 0x70, + 0xcf, 0x7f, 0x07, 0x00, 0x00, 0xff, 0xff, 0xbe, 0xbb, 0xf0, 0x6c, 0xdb, 0x03, 0x00, 0x00, } diff --git a/vendor/github.com/containerd/containerd/linux/runcopts/runc.proto b/vendor/github.com/containerd/containerd/linux/runcopts/runc.proto index bf31d2bb51203..3d10dc9dc3f47 100644 --- a/vendor/github.com/containerd/containerd/linux/runcopts/runc.proto +++ b/vendor/github.com/containerd/containerd/linux/runcopts/runc.proto @@ -23,6 +23,8 @@ message CreateOptions { string cgroups_mode = 7; bool no_new_keyring = 8; string shim_cgroup = 9; + uint32 io_uid = 10; + uint32 io_gid = 11; } message CheckpointOptions { diff --git a/vendor/github.com/containerd/containerd/metadata/bolt.go b/vendor/github.com/containerd/containerd/metadata/bolt.go index 221dba5a28ff8..2e4c352705340 100644 --- a/vendor/github.com/containerd/containerd/metadata/bolt.go +++ b/vendor/github.com/containerd/containerd/metadata/bolt.go @@ -17,9 +17,14 @@ func WithTransactionContext(ctx context.Context, tx *bolt.Tx) context.Context { return context.WithValue(ctx, transactionKey{}, tx) } +type transactor interface { + View(fn func(*bolt.Tx) error) error + Update(fn func(*bolt.Tx) error) error +} + // view gets a bolt db transaction either from the context // or starts a new one with the provided bolt database. -func view(ctx context.Context, db *bolt.DB, fn func(*bolt.Tx) error) error { +func view(ctx context.Context, db transactor, fn func(*bolt.Tx) error) error { tx, ok := ctx.Value(transactionKey{}).(*bolt.Tx) if !ok { return db.View(fn) @@ -29,7 +34,7 @@ func view(ctx context.Context, db *bolt.DB, fn func(*bolt.Tx) error) error { // update gets a writable bolt db transaction either from the context // or starts a new one with the provided bolt database. -func update(ctx context.Context, db *bolt.DB, fn func(*bolt.Tx) error) error { +func update(ctx context.Context, db transactor, fn func(*bolt.Tx) error) error { tx, ok := ctx.Value(transactionKey{}).(*bolt.Tx) if !ok { return db.Update(fn) diff --git a/vendor/github.com/containerd/containerd/metadata/buckets.go b/vendor/github.com/containerd/containerd/metadata/buckets.go index 57dcb89e5c04d..43849e0804295 100644 --- a/vendor/github.com/containerd/containerd/metadata/buckets.go +++ b/vendor/github.com/containerd/containerd/metadata/buckets.go @@ -28,7 +28,8 @@ import ( // key: object-specific key identifying the storage bucket for the objects // contents. var ( - bucketKeyVersion = []byte("v1") + bucketKeyVersion = []byte(schemaVersion) + bucketKeyDBVersion = []byte("version") // stores the version of the schema bucketKeyObjectLabels = []byte("labels") // stores the labels for a namespace. bucketKeyObjectIndexes = []byte("indexes") // reserved bucketKeyObjectImages = []byte("images") // stores image objects @@ -45,11 +46,13 @@ var ( bucketKeyRuntime = []byte("runtime") bucketKeyName = []byte("name") bucketKeyParent = []byte("parent") + bucketKeyChildren = []byte("children") bucketKeyOptions = []byte("options") bucketKeySpec = []byte("spec") bucketKeySnapshotKey = []byte("snapshotKey") bucketKeySnapshotter = []byte("snapshotter") bucketKeyTarget = []byte("target") + bucketKeyExtensions = []byte("extensions") ) func getBucket(tx *bolt.Tx, keys ...[]byte) *bolt.Bucket { diff --git a/vendor/github.com/containerd/containerd/metadata/containers.go b/vendor/github.com/containerd/containerd/metadata/containers.go index 2f384c45a8aae..c9d8ab6469396 100644 --- a/vendor/github.com/containerd/containerd/metadata/containers.go +++ b/vendor/github.com/containerd/containerd/metadata/containers.go @@ -10,6 +10,7 @@ import ( "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/filters" "github.com/containerd/containerd/identifiers" + "github.com/containerd/containerd/labels" "github.com/containerd/containerd/metadata/boltutil" "github.com/containerd/containerd/namespaces" "github.com/gogo/protobuf/proto" @@ -21,6 +22,7 @@ type containerStore struct { tx *bolt.Tx } +// NewContainerStore returns a Store backed by an underlying bolt DB func NewContainerStore(tx *bolt.Tx) containers.Store { return &containerStore{ tx: tx, @@ -146,7 +148,7 @@ func (s *containerStore) Update(ctx context.Context, container containers.Contai if len(fieldpaths) == 0 { // only allow updates to these field on full replace. - fieldpaths = []string{"labels", "spec"} + fieldpaths = []string{"labels", "spec", "extensions"} // Fields that are immutable must cause an error when no field paths // are provided. This allows these fields to become mutable in the @@ -181,11 +183,22 @@ func (s *containerStore) Update(ctx context.Context, container containers.Contai continue } + if strings.HasPrefix(path, "extensions.") { + if updated.Extensions == nil { + updated.Extensions = map[string]types.Any{} + } + key := strings.TrimPrefix(path, "extensions.") + updated.Extensions[key] = container.Extensions[key] + continue + } + switch path { case "labels": updated.Labels = container.Labels case "spec": updated.Spec = container.Spec + case "extensions": + updated.Extensions = container.Extensions default: return containers.Container{}, errors.Wrapf(errdefs.ErrInvalidArgument, "cannot update %q field on %q", path, container.ID) } @@ -226,7 +239,19 @@ func validateContainer(container *containers.Container) error { return errors.Wrapf(err, "container.ID validation error") } - // labels and image have no validation + for k := range container.Extensions { + if k == "" { + return errors.Wrapf(errdefs.ErrInvalidArgument, "container.Extension keys must not be zero-length") + } + } + + // image has no validation + for k, v := range container.Labels { + if err := labels.Validate(k, v); err == nil { + return errors.Wrapf(err, "containers.Labels") + } + } + if container.Runtime.Name == "" { return errors.Wrapf(errdefs.ErrInvalidArgument, "container.Runtime.Name must be set") } @@ -288,6 +313,27 @@ func readContainer(container *containers.Container, bkt *bolt.Bucket) error { container.SnapshotKey = string(v) case string(bucketKeySnapshotter): container.Snapshotter = string(v) + case string(bucketKeyExtensions): + ebkt := bkt.Bucket(bucketKeyExtensions) + if ebkt == nil { + return nil + } + + extensions := make(map[string]types.Any) + if err := ebkt.ForEach(func(k, v []byte) error { + var a types.Any + if err := proto.Unmarshal(v, &a); err != nil { + return err + } + + extensions[string(k)] = a + return nil + }); err != nil { + + return err + } + + container.Extensions = extensions } return nil @@ -335,6 +381,24 @@ func writeContainer(bkt *bolt.Bucket, container *containers.Container) error { return err } + if len(container.Extensions) > 0 { + ebkt, err := bkt.CreateBucketIfNotExists(bucketKeyExtensions) + if err != nil { + return err + } + + for name, ext := range container.Extensions { + p, err := proto.Marshal(&ext) + if err != nil { + return err + } + + if err := ebkt.Put([]byte(name), p); err != nil { + return err + } + } + } + if container.Runtime.Options != nil { data, err := proto.Marshal(container.Runtime.Options) if err != nil { diff --git a/vendor/github.com/containerd/containerd/metadata/content.go b/vendor/github.com/containerd/containerd/metadata/content.go index 744cf253861e3..293539aa10ac2 100644 --- a/vendor/github.com/containerd/containerd/metadata/content.go +++ b/vendor/github.com/containerd/containerd/metadata/content.go @@ -4,12 +4,15 @@ import ( "context" "encoding/binary" "strings" + "sync" "time" "github.com/boltdb/bolt" "github.com/containerd/containerd/content" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/filters" + "github.com/containerd/containerd/labels" + "github.com/containerd/containerd/log" "github.com/containerd/containerd/metadata/boltutil" "github.com/containerd/containerd/namespaces" digest "github.com/opencontainers/go-digest" @@ -18,12 +21,13 @@ import ( type contentStore struct { content.Store - db *bolt.DB + db *DB + l sync.RWMutex } -// NewContentStore returns a namespaced content store using an existing +// newContentStore returns a namespaced content store using an existing // content store interface. -func NewContentStore(db *bolt.DB, cs content.Store) content.Store { +func newContentStore(db *DB, cs content.Store) *contentStore { return &contentStore{ Store: cs, db: db, @@ -58,6 +62,9 @@ func (cs *contentStore) Update(ctx context.Context, info content.Info, fieldpath return content.Info{}, err } + cs.l.RLock() + defer cs.l.RUnlock() + updated := content.Info{ Digest: info.Digest, } @@ -94,6 +101,9 @@ func (cs *contentStore) Update(ctx context.Context, info content.Info, fieldpath // Set mutable fields updated.Labels = info.Labels } + if err := validateInfo(&updated); err != nil { + return err + } updated.UpdatedAt = time.Now().UTC() return writeInfo(&updated, bkt) @@ -162,15 +172,25 @@ func (cs *contentStore) Delete(ctx context.Context, dgst digest.Digest) error { return err } + cs.l.RLock() + defer cs.l.RUnlock() + return update(ctx, cs.db, func(tx *bolt.Tx) error { bkt := getBlobBucket(tx, ns, dgst) if bkt == nil { return errors.Wrapf(errdefs.ErrNotFound, "content digest %v", dgst) } - // Just remove local reference, garbage collector is responsible for - // cleaning up on disk content - return getBlobsBucket(tx, ns).DeleteBucket([]byte(dgst.String())) + if err := getBlobsBucket(tx, ns).DeleteBucket([]byte(dgst.String())); err != nil { + return err + } + + // Mark content store as dirty for triggering garbage collection + cs.db.dirtyL.Lock() + cs.db.dirtyCS = true + cs.db.dirtyL.Unlock() + + return nil }) } @@ -265,6 +285,9 @@ func (cs *contentStore) Abort(ctx context.Context, ref string) error { return err } + cs.l.RLock() + defer cs.l.RUnlock() + return update(ctx, cs.db, func(tx *bolt.Tx) error { bkt := getIngestBucket(tx, ns) if bkt == nil { @@ -289,6 +312,9 @@ func (cs *contentStore) Writer(ctx context.Context, ref string, size int64, expe return nil, err } + cs.l.RLock() + defer cs.l.RUnlock() + var w content.Writer if err := update(ctx, cs.db, func(tx *bolt.Tx) error { if expected != "" { @@ -342,6 +368,7 @@ func (cs *contentStore) Writer(ctx context.Context, ref string, size int64, expe ref: ref, namespace: ns, db: cs.db, + l: &cs.l, }, nil } @@ -349,10 +376,14 @@ type namespacedWriter struct { content.Writer ref string namespace string - db *bolt.DB + db transactor + l *sync.RWMutex } func (nw *namespacedWriter) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) error { + nw.l.RLock() + defer nw.l.RUnlock() + return update(ctx, nw.db, func(tx *bolt.Tx) error { bkt := getIngestBucket(tx, nw.namespace) if bkt != nil { @@ -371,6 +402,10 @@ func (nw *namespacedWriter) commit(ctx context.Context, tx *bolt.Tx, size int64, return err } } + if err := validateInfo(&base); err != nil { + return err + } + status, err := nw.Writer.Status() if err != nil { return err @@ -398,7 +433,7 @@ func (nw *namespacedWriter) commit(ctx context.Context, tx *bolt.Tx, size int64, commitTime := time.Now().UTC() - sizeEncoded, err := encodeSize(size) + sizeEncoded, err := encodeInt(size) if err != nil { return err } @@ -409,11 +444,7 @@ func (nw *namespacedWriter) commit(ctx context.Context, tx *bolt.Tx, size int64, if err := boltutil.WriteLabels(bkt, base.Labels); err != nil { return err } - if err := bkt.Put(bucketKeySize, sizeEncoded); err != nil { - return err - } - - return nil + return bkt.Put(bucketKeySize, sizeEncoded) } func (nw *namespacedWriter) Status() (content.Status, error) { @@ -446,6 +477,16 @@ func (cs *contentStore) checkAccess(ctx context.Context, dgst digest.Digest) err }) } +func validateInfo(info *content.Info) error { + for k, v := range info.Labels { + if err := labels.Validate(k, v); err == nil { + return errors.Wrapf(err, "info.Labels") + } + } + + return nil +} + func readInfo(info *content.Info, bkt *bolt.Bucket) error { if err := boltutil.ReadTimestamps(bkt, &info.CreatedAt, &info.UpdatedAt); err != nil { return err @@ -474,14 +515,64 @@ func writeInfo(info *content.Info, bkt *bolt.Bucket) error { } // Write size - sizeEncoded, err := encodeSize(info.Size) + sizeEncoded, err := encodeInt(info.Size) if err != nil { return err } - if err := bkt.Put(bucketKeySize, sizeEncoded); err != nil { + return bkt.Put(bucketKeySize, sizeEncoded) +} + +func (cs *contentStore) garbageCollect(ctx context.Context) error { + lt1 := time.Now() + cs.l.Lock() + defer func() { + cs.l.Unlock() + log.G(ctx).WithField("t", time.Now().Sub(lt1)).Debugf("content garbage collected") + }() + + seen := map[string]struct{}{} + if err := cs.db.View(func(tx *bolt.Tx) error { + v1bkt := tx.Bucket(bucketKeyVersion) + if v1bkt == nil { + return nil + } + + // iterate through each namespace + v1c := v1bkt.Cursor() + + for k, v := v1c.First(); k != nil; k, v = v1c.Next() { + if v != nil { + continue + } + + cbkt := v1bkt.Bucket(k).Bucket(bucketKeyObjectContent) + if cbkt == nil { + continue + } + bbkt := cbkt.Bucket(bucketKeyObjectBlob) + if err := bbkt.ForEach(func(ck, cv []byte) error { + if cv == nil { + seen[string(ck)] = struct{}{} + } + return nil + }); err != nil { + return err + } + } + + return nil + }); err != nil { return err } - return nil + return cs.Store.Walk(ctx, func(info content.Info) error { + if _, ok := seen[info.Digest.String()]; !ok { + if err := cs.Store.Delete(ctx, info.Digest); err != nil { + return err + } + log.G(ctx).WithField("digest", info.Digest).Debug("removed content") + } + return nil + }) } diff --git a/vendor/github.com/containerd/containerd/metadata/db.go b/vendor/github.com/containerd/containerd/metadata/db.go new file mode 100644 index 0000000000000..7c366ebcc48b1 --- /dev/null +++ b/vendor/github.com/containerd/containerd/metadata/db.go @@ -0,0 +1,328 @@ +package metadata + +import ( + "context" + "encoding/binary" + "strings" + "sync" + "time" + + "github.com/boltdb/bolt" + "github.com/containerd/containerd/content" + "github.com/containerd/containerd/gc" + "github.com/containerd/containerd/log" + "github.com/containerd/containerd/snapshot" + "github.com/pkg/errors" +) + +const ( + // schemaVersion represents the schema version of + // the database. This schema version represents the + // structure of the data in the database. The schema + // can envolve at any time but any backwards + // incompatible changes or structural changes require + // bumping the schema version. + schemaVersion = "v1" + + // dbVersion represents updates to the schema + // version which are additions and compatible with + // prior version of the same schema. + dbVersion = 1 +) + +// DB represents a metadata database backed by a bolt +// database. The database is fully namespaced and stores +// image, container, namespace, snapshot, and content data +// while proxying data shared across namespaces to backend +// datastores for content and snapshots. +type DB struct { + db *bolt.DB + ss map[string]*snapshotter + cs *contentStore + + // wlock is used to protect access to the data structures during garbage + // collection. While the wlock is held no writable transactions can be + // opened, preventing changes from occurring between the mark and + // sweep phases without preventing read transactions. + wlock sync.RWMutex + + // dirty flags and lock keeps track of datastores which have had deletions + // since the last garbage collection. These datastores will will be garbage + // collected during the next garbage collection. + dirtyL sync.Mutex + dirtySS map[string]struct{} + dirtyCS bool + + // TODO: Keep track of stats such as pause time, number of collected objects, errors + lastCollection time.Time +} + +// NewDB creates a new metadata database using the provided +// bolt database, content store, and snapshotters. +func NewDB(db *bolt.DB, cs content.Store, ss map[string]snapshot.Snapshotter) *DB { + m := &DB{ + db: db, + ss: make(map[string]*snapshotter, len(ss)), + dirtySS: map[string]struct{}{}, + } + + // Initialize data stores + m.cs = newContentStore(m, cs) + for name, sn := range ss { + m.ss[name] = newSnapshotter(m, name, sn) + } + + return m +} + +// Init ensures the database is at the correct version +// and performs any needed migrations. +func (m *DB) Init(ctx context.Context) error { + // errSkip is used when no migration or version needs to be written + // to the database and the transaction can be immediately rolled + // back rather than performing a much slower and unnecessary commit. + var errSkip = errors.New("skip update") + + err := m.db.Update(func(tx *bolt.Tx) error { + var ( + // current schema and version + schema = "v0" + version = 0 + ) + + // i represents the index of the first migration + // which must be run to get the database up to date. + // The migration's version will be checked in reverse + // order, decrementing i for each migration which + // represents a version newer than the current + // database version + i := len(migrations) + + for ; i > 0; i-- { + migration := migrations[i-1] + + bkt := tx.Bucket([]byte(migration.schema)) + if bkt == nil { + // Hasn't encountered another schema, go to next migration + if schema == "v0" { + continue + } + break + } + if schema == "v0" { + schema = migration.schema + vb := bkt.Get(bucketKeyDBVersion) + if vb != nil { + v, _ := binary.Varint(vb) + version = int(v) + } + } + + if version >= migration.version { + break + } + } + + // Previous version fo database found + if schema != "v0" { + updates := migrations[i:] + + // No migration updates, return immediately + if len(updates) == 0 { + return errSkip + } + + for _, m := range updates { + t0 := time.Now() + if err := m.migrate(tx); err != nil { + return errors.Wrapf(err, "failed to migrate to %s.%d", m.schema, m.version) + } + log.G(ctx).WithField("d", time.Now().Sub(t0)).Debugf("database migration to %s.%d finished", m.schema, m.version) + } + } + + bkt, err := tx.CreateBucketIfNotExists(bucketKeyVersion) + if err != nil { + return err + } + + versionEncoded, err := encodeInt(dbVersion) + if err != nil { + return err + } + + return bkt.Put(bucketKeyDBVersion, versionEncoded) + }) + if err == errSkip { + err = nil + } + return err +} + +// ContentStore returns a namespaced content store +// proxied to a content store. +func (m *DB) ContentStore() content.Store { + if m.cs == nil { + return nil + } + return m.cs +} + +// Snapshotter returns a namespaced content store for +// the requested snapshotter name proxied to a snapshotter. +func (m *DB) Snapshotter(name string) snapshot.Snapshotter { + sn, ok := m.ss[name] + if !ok { + return nil + } + return sn +} + +// View runs a readonly transaction on the metadata store. +func (m *DB) View(fn func(*bolt.Tx) error) error { + return m.db.View(fn) +} + +// Update runs a writable transation on the metadata store. +func (m *DB) Update(fn func(*bolt.Tx) error) error { + m.wlock.RLock() + defer m.wlock.RUnlock() + return m.db.Update(fn) +} + +// GarbageCollect starts garbage collection +func (m *DB) GarbageCollect(ctx context.Context) error { + lt1 := time.Now() + m.wlock.Lock() + defer func() { + m.wlock.Unlock() + log.G(ctx).WithField("d", time.Now().Sub(lt1)).Debug("metadata garbage collected") + }() + + marked, err := m.getMarked(ctx) + if err != nil { + return err + } + + m.dirtyL.Lock() + defer m.dirtyL.Unlock() + + if err := m.db.Update(func(tx *bolt.Tx) error { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + rm := func(ctx context.Context, n gc.Node) error { + if _, ok := marked[n]; ok { + return nil + } + + if n.Type == ResourceSnapshot { + if idx := strings.IndexRune(n.Key, '/'); idx > 0 { + m.dirtySS[n.Key[:idx]] = struct{}{} + } + } else if n.Type == ResourceContent { + m.dirtyCS = true + } + return remove(ctx, tx, n) + } + + if err := scanAll(ctx, tx, rm); err != nil { + return errors.Wrap(err, "failed to scan and remove") + } + + return nil + }); err != nil { + return err + } + + m.lastCollection = time.Now() + + if len(m.dirtySS) > 0 { + for snapshotterName := range m.dirtySS { + log.G(ctx).WithField("snapshotter", snapshotterName).Debug("scheduling snapshotter cleanup") + go m.cleanupSnapshotter(snapshotterName) + } + m.dirtySS = map[string]struct{}{} + } + + if m.dirtyCS { + log.G(ctx).Debug("scheduling content cleanup") + go m.cleanupContent() + m.dirtyCS = false + } + + return nil +} + +func (m *DB) getMarked(ctx context.Context) (map[gc.Node]struct{}, error) { + var marked map[gc.Node]struct{} + if err := m.db.View(func(tx *bolt.Tx) error { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + var ( + nodes []gc.Node + wg sync.WaitGroup + roots = make(chan gc.Node) + ) + wg.Add(1) + go func() { + defer wg.Done() + for n := range roots { + nodes = append(nodes, n) + } + }() + // Call roots + if err := scanRoots(ctx, tx, roots); err != nil { + cancel() + return err + } + close(roots) + wg.Wait() + + refs := func(n gc.Node) ([]gc.Node, error) { + var sn []gc.Node + if err := references(ctx, tx, n, func(nn gc.Node) { + sn = append(sn, nn) + }); err != nil { + return nil, err + } + return sn, nil + } + + reachable, err := gc.Tricolor(nodes, refs) + if err != nil { + return err + } + marked = reachable + return nil + }); err != nil { + return nil, err + } + return marked, nil +} + +func (m *DB) cleanupSnapshotter(name string) { + ctx := context.Background() + sn, ok := m.ss[name] + if !ok { + return + } + + err := sn.garbageCollect(ctx) + if err != nil { + log.G(ctx).WithError(err).WithField("snapshotter", name).Warn("garbage collection failed") + } +} + +func (m *DB) cleanupContent() { + ctx := context.Background() + if m.cs == nil { + return + } + + err := m.cs.garbageCollect(ctx) + if err != nil { + log.G(ctx).WithError(err).Warn("content garbage collection failed") + } +} diff --git a/vendor/github.com/containerd/containerd/metadata/gc.go b/vendor/github.com/containerd/containerd/metadata/gc.go new file mode 100644 index 0000000000000..63d1852e05bef --- /dev/null +++ b/vendor/github.com/containerd/containerd/metadata/gc.go @@ -0,0 +1,340 @@ +package metadata + +import ( + "context" + "fmt" + "strings" + + "github.com/boltdb/bolt" + "github.com/containerd/containerd/gc" + "github.com/containerd/containerd/log" + "github.com/pkg/errors" +) + +const ( + // ResourceUnknown specifies an unknown resource + ResourceUnknown gc.ResourceType = iota + // ResourceContent specifies a content resource + ResourceContent + // ResourceSnapshot specifies a snapshot resource + ResourceSnapshot + // ResourceContainer specifies a container resource + ResourceContainer + // ResourceTask specifies a task resource + ResourceTask +) + +var ( + labelGCRoot = []byte("containerd.io/gc.root") + labelGCSnapRef = []byte("containerd.io/gc.ref.snapshot.") + labelGCContentRef = []byte("containerd.io/gc.ref.content") +) + +func scanRoots(ctx context.Context, tx *bolt.Tx, nc chan<- gc.Node) error { + v1bkt := tx.Bucket(bucketKeyVersion) + if v1bkt == nil { + return nil + } + + // iterate through each namespace + v1c := v1bkt.Cursor() + + for k, v := v1c.First(); k != nil; k, v = v1c.Next() { + if v != nil { + continue + } + nbkt := v1bkt.Bucket(k) + ns := string(k) + + ibkt := nbkt.Bucket(bucketKeyObjectImages) + if ibkt != nil { + if err := ibkt.ForEach(func(k, v []byte) error { + if v != nil { + return nil + } + + target := ibkt.Bucket(k).Bucket(bucketKeyTarget) + if target != nil { + contentKey := string(target.Get(bucketKeyDigest)) + select { + case nc <- gcnode(ResourceContent, ns, contentKey): + case <-ctx.Done(): + return ctx.Err() + } + } + return sendSnapshotRefs(ns, ibkt.Bucket(k), func(n gc.Node) { + select { + case nc <- n: + case <-ctx.Done(): + } + }) + }); err != nil { + return err + } + } + + cbkt := nbkt.Bucket(bucketKeyObjectContent) + if cbkt != nil { + cbkt = cbkt.Bucket(bucketKeyObjectBlob) + } + if cbkt != nil { + if err := cbkt.ForEach(func(k, v []byte) error { + if v != nil { + return nil + } + return sendRootRef(ctx, nc, gcnode(ResourceContent, ns, string(k)), cbkt.Bucket(k)) + }); err != nil { + return err + } + } + + cbkt = nbkt.Bucket(bucketKeyObjectContainers) + if cbkt != nil { + if err := cbkt.ForEach(func(k, v []byte) error { + if v != nil { + return nil + } + snapshotter := string(cbkt.Bucket(k).Get(bucketKeySnapshotter)) + if snapshotter != "" { + ss := string(cbkt.Bucket(k).Get(bucketKeySnapshotKey)) + select { + case nc <- gcnode(ResourceSnapshot, ns, fmt.Sprintf("%s/%s", snapshotter, ss)): + case <-ctx.Done(): + return ctx.Err() + } + } + + // TODO: Send additional snapshot refs through labels + return sendSnapshotRefs(ns, cbkt.Bucket(k), func(n gc.Node) { + select { + case nc <- n: + case <-ctx.Done(): + } + }) + }); err != nil { + return err + } + } + + sbkt := nbkt.Bucket(bucketKeyObjectSnapshots) + if sbkt != nil { + if err := sbkt.ForEach(func(sk, sv []byte) error { + if sv != nil { + return nil + } + snbkt := sbkt.Bucket(sk) + + return snbkt.ForEach(func(k, v []byte) error { + if v != nil { + return nil + } + + return sendRootRef(ctx, nc, gcnode(ResourceSnapshot, ns, fmt.Sprintf("%s/%s", sk, k)), snbkt.Bucket(k)) + }) + }); err != nil { + return err + } + } + } + return nil +} + +func references(ctx context.Context, tx *bolt.Tx, node gc.Node, fn func(gc.Node)) error { + if node.Type == ResourceContent { + bkt := getBucket(tx, bucketKeyVersion, []byte(node.Namespace), bucketKeyObjectContent, bucketKeyObjectBlob, []byte(node.Key)) + if bkt == nil { + // Node may be created from dead edge + return nil + } + + if err := sendSnapshotRefs(node.Namespace, bkt, fn); err != nil { + return err + } + return sendContentRefs(node.Namespace, bkt, fn) + } else if node.Type == ResourceSnapshot { + parts := strings.SplitN(node.Key, "/", 2) + if len(parts) != 2 { + return errors.Errorf("invalid snapshot gc key %s", node.Key) + } + ss := parts[0] + name := parts[1] + + bkt := getBucket(tx, bucketKeyVersion, []byte(node.Namespace), bucketKeyObjectSnapshots, []byte(ss), []byte(name)) + if bkt == nil { + getBucket(tx, bucketKeyVersion, []byte(node.Namespace), bucketKeyObjectSnapshots).ForEach(func(k, v []byte) error { + return nil + }) + + // Node may be created from dead edge + return nil + } + + if pv := bkt.Get(bucketKeyParent); len(pv) > 0 { + fn(gcnode(ResourceSnapshot, node.Namespace, fmt.Sprintf("%s/%s", ss, pv))) + } + + return sendSnapshotRefs(node.Namespace, bkt, fn) + } + + return nil +} + +func scanAll(ctx context.Context, tx *bolt.Tx, fn func(ctx context.Context, n gc.Node) error) error { + v1bkt := tx.Bucket(bucketKeyVersion) + if v1bkt == nil { + return nil + } + + // iterate through each namespace + v1c := v1bkt.Cursor() + + for k, v := v1c.First(); k != nil; k, v = v1c.Next() { + if v != nil { + continue + } + nbkt := v1bkt.Bucket(k) + ns := string(k) + + sbkt := nbkt.Bucket(bucketKeyObjectSnapshots) + if sbkt != nil { + if err := sbkt.ForEach(func(sk, sv []byte) error { + if sv != nil { + return nil + } + snbkt := sbkt.Bucket(sk) + return snbkt.ForEach(func(k, v []byte) error { + if v != nil { + return nil + } + node := gcnode(ResourceSnapshot, ns, fmt.Sprintf("%s/%s", sk, k)) + return fn(ctx, node) + }) + }); err != nil { + return err + } + } + + cbkt := nbkt.Bucket(bucketKeyObjectContent) + if cbkt != nil { + cbkt = cbkt.Bucket(bucketKeyObjectBlob) + } + if cbkt != nil { + if err := cbkt.ForEach(func(k, v []byte) error { + if v != nil { + return nil + } + node := gcnode(ResourceContent, ns, string(k)) + return fn(ctx, node) + }); err != nil { + return err + } + } + } + + return nil +} + +func remove(ctx context.Context, tx *bolt.Tx, node gc.Node) error { + v1bkt := tx.Bucket(bucketKeyVersion) + if v1bkt == nil { + return nil + } + + nsbkt := v1bkt.Bucket([]byte(node.Namespace)) + if nsbkt == nil { + return nil + } + + switch node.Type { + case ResourceContent: + cbkt := nsbkt.Bucket(bucketKeyObjectContent) + if cbkt != nil { + cbkt = cbkt.Bucket(bucketKeyObjectBlob) + } + if cbkt != nil { + log.G(ctx).WithField("key", node.Key).Debug("delete content") + return cbkt.DeleteBucket([]byte(node.Key)) + } + case ResourceSnapshot: + sbkt := nsbkt.Bucket(bucketKeyObjectSnapshots) + if sbkt != nil { + parts := strings.SplitN(node.Key, "/", 2) + if len(parts) != 2 { + return errors.Errorf("invalid snapshot gc key %s", node.Key) + } + ssbkt := sbkt.Bucket([]byte(parts[0])) + if ssbkt != nil { + log.G(ctx).WithField("key", parts[1]).WithField("snapshotter", parts[0]).Debug("delete snapshot") + return ssbkt.DeleteBucket([]byte(parts[1])) + } + } + } + + return nil +} + +// sendSnapshotRefs sends all snapshot references referred to by the labels in the bkt +func sendSnapshotRefs(ns string, bkt *bolt.Bucket, fn func(gc.Node)) error { + lbkt := bkt.Bucket(bucketKeyObjectLabels) + if lbkt != nil { + lc := lbkt.Cursor() + + for k, v := lc.Seek(labelGCSnapRef); k != nil && strings.HasPrefix(string(k), string(labelGCSnapRef)); k, v = lc.Next() { + snapshotter := string(k[len(labelGCSnapRef):]) + fn(gcnode(ResourceSnapshot, ns, fmt.Sprintf("%s/%s", snapshotter, v))) + } + } + return nil +} + +// sendContentRefs sends all content references referred to by the labels in the bkt +func sendContentRefs(ns string, bkt *bolt.Bucket, fn func(gc.Node)) error { + lbkt := bkt.Bucket(bucketKeyObjectLabels) + if lbkt != nil { + lc := lbkt.Cursor() + + labelRef := string(labelGCContentRef) + for k, v := lc.Seek(labelGCContentRef); k != nil && strings.HasPrefix(string(k), labelRef); k, v = lc.Next() { + if ks := string(k); ks != labelRef { + // Allow reference naming, ignore names + if ks[len(labelRef)] != '.' { + continue + } + } + + fn(gcnode(ResourceContent, ns, string(v))) + } + } + return nil +} + +func isRootRef(bkt *bolt.Bucket) bool { + lbkt := bkt.Bucket(bucketKeyObjectLabels) + if lbkt != nil { + rv := lbkt.Get(labelGCRoot) + if rv != nil { + // TODO: interpret rv as a timestamp and skip if expired + return true + } + } + return false +} + +func sendRootRef(ctx context.Context, nc chan<- gc.Node, n gc.Node, bkt *bolt.Bucket) error { + if isRootRef(bkt) { + select { + case nc <- n: + case <-ctx.Done(): + return ctx.Err() + } + } + return nil +} + +func gcnode(t gc.ResourceType, ns, key string) gc.Node { + return gc.Node{ + Type: t, + Namespace: ns, + Key: key, + } +} diff --git a/vendor/github.com/containerd/containerd/metadata/images.go b/vendor/github.com/containerd/containerd/metadata/images.go index a44b3a7f49b5b..7e5e3c76e3229 100644 --- a/vendor/github.com/containerd/containerd/metadata/images.go +++ b/vendor/github.com/containerd/containerd/metadata/images.go @@ -11,9 +11,11 @@ import ( "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/filters" "github.com/containerd/containerd/images" + "github.com/containerd/containerd/labels" "github.com/containerd/containerd/metadata/boltutil" "github.com/containerd/containerd/namespaces" digest "github.com/opencontainers/go-digest" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" ) @@ -21,6 +23,7 @@ type imageStore struct { tx *bolt.Tx } +// NewImageStore returns a store backed by a bolt DB func NewImageStore(tx *bolt.Tx) images.Store { return &imageStore{tx: tx} } @@ -101,6 +104,10 @@ func (s *imageStore) Create(ctx context.Context, image images.Image) (images.Ima return images.Image{}, errors.Wrapf(errdefs.ErrInvalidArgument, "image name is required for create") } + if err := validateImage(&image); err != nil { + return images.Image{}, err + } + return image, withImagesBucket(s.tx, namespace, func(bkt *bolt.Bucket) error { ibkt, err := bkt.CreateBucket([]byte(image.Name)) if err != nil { @@ -170,6 +177,10 @@ func (s *imageStore) Update(ctx context.Context, image images.Image, fieldpaths updated = image } + if err := validateImage(&image); err != nil { + return err + } + updated.CreatedAt = createdat updated.UpdatedAt = time.Now().UTC() return writeImage(ibkt, &updated) @@ -191,6 +202,38 @@ func (s *imageStore) Delete(ctx context.Context, name string) error { }) } +func validateImage(image *images.Image) error { + if image.Name == "" { + return errors.Wrapf(errdefs.ErrInvalidArgument, "image name must not be empty") + } + + for k, v := range image.Labels { + if err := labels.Validate(k, v); err != nil { + return errors.Wrapf(err, "image.Labels") + } + } + + return validateTarget(&image.Target) +} + +func validateTarget(target *ocispec.Descriptor) error { + // NOTE(stevvooe): Only validate fields we actually store. + + if err := target.Digest.Validate(); err != nil { + return errors.Wrapf(errdefs.ErrInvalidArgument, "Target.Digest %q invalid: %v", target.Digest, err) + } + + if target.Size <= 0 { + return errors.Wrapf(errdefs.ErrInvalidArgument, "Target.Size must be greater than zero") + } + + if target.MediaType == "" { + return errors.Wrapf(errdefs.ErrInvalidArgument, "Target.MediaType must be set") + } + + return nil +} + func readImage(image *images.Image, bkt *bolt.Bucket) error { if err := boltutil.ReadTimestamps(bkt, &image.CreatedAt, &image.UpdatedAt); err != nil { return err @@ -241,7 +284,7 @@ func writeImage(bkt *bolt.Bucket, image *images.Image) error { return err } - sizeEncoded, err := encodeSize(image.Target.Size) + sizeEncoded, err := encodeInt(image.Target.Size) if err != nil { return err } @@ -259,15 +302,15 @@ func writeImage(bkt *bolt.Bucket, image *images.Image) error { return nil } -func encodeSize(size int64) ([]byte, error) { +func encodeInt(i int64) ([]byte, error) { var ( - buf [binary.MaxVarintLen64]byte - sizeEncoded []byte = buf[:] + buf [binary.MaxVarintLen64]byte + iEncoded = buf[:] ) - sizeEncoded = sizeEncoded[:binary.PutVarint(sizeEncoded, size)] + iEncoded = iEncoded[:binary.PutVarint(iEncoded, i)] - if len(sizeEncoded) == 0 { - return nil, fmt.Errorf("failed encoding size = %v", size) + if len(iEncoded) == 0 { + return nil, fmt.Errorf("failed encoding integer = %v", i) } - return sizeEncoded, nil + return iEncoded, nil } diff --git a/vendor/github.com/containerd/containerd/metadata/migrations.go b/vendor/github.com/containerd/containerd/metadata/migrations.go new file mode 100644 index 0000000000000..997aee298da57 --- /dev/null +++ b/vendor/github.com/containerd/containerd/metadata/migrations.go @@ -0,0 +1,85 @@ +package metadata + +import "github.com/boltdb/bolt" + +type migration struct { + schema string + version int + migrate func(*bolt.Tx) error +} + +// migrations stores the list of database migrations +// for each update to the database schema. The migrations +// array MUST be ordered by version from least to greatest. +// The last entry in the array should correspond to the +// schemaVersion and dbVersion constants. +// A migration test MUST be added for each migration in +// the array. +// The migrate function can safely assume the version +// of the data it is migrating from is the previous version +// of the database. +var migrations = []migration{ + { + schema: "v1", + version: 1, + migrate: addChildLinks, + }, +} + +// addChildLinks Adds children key to the snapshotters to enforce snapshot +// entries cannot be removed which have children +func addChildLinks(tx *bolt.Tx) error { + v1bkt := tx.Bucket(bucketKeyVersion) + if v1bkt == nil { + return nil + } + + // iterate through each namespace + v1c := v1bkt.Cursor() + + for k, v := v1c.First(); k != nil; k, v = v1c.Next() { + if v != nil { + continue + } + nbkt := v1bkt.Bucket(k) + + sbkt := nbkt.Bucket(bucketKeyObjectSnapshots) + if sbkt != nil { + // Iterate through each snapshotter + if err := sbkt.ForEach(func(sk, sv []byte) error { + if sv != nil { + return nil + } + snbkt := sbkt.Bucket(sk) + + // Iterate through each snapshot + return snbkt.ForEach(func(k, v []byte) error { + if v != nil { + return nil + } + parent := snbkt.Bucket(k).Get(bucketKeyParent) + if len(parent) > 0 { + pbkt := snbkt.Bucket(parent) + if pbkt == nil { + // Not enforcing consistency during migration, skip + return nil + } + cbkt, err := pbkt.CreateBucketIfNotExists(bucketKeyChildren) + if err != nil { + return err + } + if err := cbkt.Put(k, nil); err != nil { + return err + } + } + + return nil + }) + }); err != nil { + return err + } + } + } + + return nil +} diff --git a/vendor/github.com/containerd/containerd/metadata/namespaces.go b/vendor/github.com/containerd/containerd/metadata/namespaces.go index 4053733c5b197..4b4c4e5fe7f63 100644 --- a/vendor/github.com/containerd/containerd/metadata/namespaces.go +++ b/vendor/github.com/containerd/containerd/metadata/namespaces.go @@ -5,6 +5,7 @@ import ( "github.com/boltdb/bolt" "github.com/containerd/containerd/errdefs" + l "github.com/containerd/containerd/labels" "github.com/containerd/containerd/namespaces" "github.com/pkg/errors" ) @@ -13,6 +14,7 @@ type namespaceStore struct { tx *bolt.Tx } +// NewNamespaceStore returns a store backed by a bolt DB func NewNamespaceStore(tx *bolt.Tx) namespaces.Store { return &namespaceStore{tx: tx} } @@ -27,6 +29,12 @@ func (s *namespaceStore) Create(ctx context.Context, namespace string, labels ma return err } + for k, v := range labels { + if err := l.Validate(k, v); err != nil { + return errors.Wrapf(err, "namespace.Labels") + } + } + // provides the already exists error. bkt, err := topbkt.CreateBucket([]byte(namespace)) if err != nil { @@ -70,6 +78,10 @@ func (s *namespaceStore) Labels(ctx context.Context, namespace string) (map[stri } func (s *namespaceStore) SetLabel(ctx context.Context, namespace, key, value string) error { + if err := l.Validate(key, value); err != nil { + return errors.Wrapf(err, "namespace.Labels") + } + return withNamespacesLabelsBucket(s.tx, namespace, func(bkt *bolt.Bucket) error { if value == "" { return bkt.Delete([]byte(key)) diff --git a/vendor/github.com/containerd/containerd/metadata/snapshot.go b/vendor/github.com/containerd/containerd/metadata/snapshot.go index 5ca4a6fa1617c..ad38e5915bdff 100644 --- a/vendor/github.com/containerd/containerd/metadata/snapshot.go +++ b/vendor/github.com/containerd/containerd/metadata/snapshot.go @@ -4,10 +4,13 @@ import ( "context" "fmt" "strings" + "sync" "time" "github.com/boltdb/bolt" "github.com/containerd/containerd/errdefs" + "github.com/containerd/containerd/labels" + "github.com/containerd/containerd/log" "github.com/containerd/containerd/metadata/boltutil" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/namespaces" @@ -18,12 +21,13 @@ import ( type snapshotter struct { snapshot.Snapshotter name string - db *bolt.DB + db *DB + l sync.RWMutex } -// NewSnapshotter returns a new Snapshotter which namespaces the given snapshot -// using the provided name and metadata store. -func NewSnapshotter(db *bolt.DB, name string, sn snapshot.Snapshotter) snapshot.Snapshotter { +// newSnapshotter returns a new Snapshotter which namespaces the given snapshot +// using the provided name and database. +func newSnapshotter(db *DB, name string, sn snapshot.Snapshotter) *snapshotter { return &snapshotter{ Snapshotter: sn, name: name, @@ -124,6 +128,9 @@ func (s *snapshotter) Stat(ctx context.Context, key string) (snapshot.Info, erro } func (s *snapshotter) Update(ctx context.Context, info snapshot.Info, fieldpaths ...string) (snapshot.Info, error) { + s.l.RLock() + defer s.l.RUnlock() + ns, err := namespaces.NamespaceRequired(ctx) if err != nil { return snapshot.Info{}, err @@ -180,6 +187,9 @@ func (s *snapshotter) Update(ctx context.Context, info snapshot.Info, fieldpaths } else { local.Labels = info.Labels } + if err := validateSnapshot(&local); err != nil { + return err + } local.Updated = time.Now().UTC() if err := boltutil.WriteTimestamps(sbkt, local.Created, local.Updated); err != nil { @@ -245,6 +255,9 @@ func (s *snapshotter) View(ctx context.Context, key, parent string, opts ...snap } func (s *snapshotter) createSnapshot(ctx context.Context, key, parent string, readonly bool, opts []snapshot.Opt) ([]mount.Mount, error) { + s.l.RLock() + defer s.l.RUnlock() + ns, err := namespaces.NamespaceRequired(ctx) if err != nil { return nil, err @@ -257,6 +270,10 @@ func (s *snapshotter) createSnapshot(ctx context.Context, key, parent string, re } } + if err := validateSnapshot(&base); err != nil { + return nil, err + } + var m []mount.Mount if err := update(ctx, s.db, func(tx *bolt.Tx) error { bkt, err := createSnapshotterBucket(tx, ns, s.name) @@ -275,10 +292,18 @@ func (s *snapshotter) createSnapshot(ctx context.Context, key, parent string, re if parent != "" { pbkt := bkt.Bucket([]byte(parent)) if pbkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "snapshot %v does not exist", parent) + return errors.Wrapf(errdefs.ErrNotFound, "parent snapshot %v does not exist", parent) } bparent = string(pbkt.Get(bucketKeyName)) + cbkt, err := pbkt.CreateBucketIfNotExists(bucketKeyChildren) + if err != nil { + return err + } + if err := cbkt.Put([]byte(key), nil); err != nil { + return err + } + if err := bbkt.Put(bucketKeyParent, []byte(parent)); err != nil { return err } @@ -316,6 +341,9 @@ func (s *snapshotter) createSnapshot(ctx context.Context, key, parent string, re } func (s *snapshotter) Commit(ctx context.Context, name, key string, opts ...snapshot.Opt) error { + s.l.RLock() + defer s.l.RUnlock() + ns, err := namespaces.NamespaceRequired(ctx) if err != nil { return err @@ -328,6 +356,10 @@ func (s *snapshotter) Commit(ctx context.Context, name, key string, opts ...snap } } + if err := validateSnapshot(&base); err != nil { + return err + } + return update(ctx, s.db, func(tx *bolt.Tx) error { bkt := getSnapshotterBucket(tx, ns, s.name) if bkt == nil { @@ -348,7 +380,6 @@ func (s *snapshotter) Commit(ctx context.Context, name, key string, opts ...snap } bkey := string(obkt.Get(bucketKeyName)) - parent := string(obkt.Get(bucketKeyParent)) sid, err := bkt.NextSequence() if err != nil { @@ -360,8 +391,28 @@ func (s *snapshotter) Commit(ctx context.Context, name, key string, opts ...snap if err := bbkt.Put(bucketKeyName, []byte(nameKey)); err != nil { return err } - if err := bbkt.Put(bucketKeyParent, []byte(parent)); err != nil { - return err + + parent := obkt.Get(bucketKeyParent) + if len(parent) > 0 { + pbkt := bkt.Bucket(parent) + if pbkt == nil { + return errors.Wrapf(errdefs.ErrNotFound, "parent snapshot %v does not exist", string(parent)) + } + + cbkt, err := pbkt.CreateBucketIfNotExists(bucketKeyChildren) + if err != nil { + return err + } + if err := cbkt.Delete([]byte(key)); err != nil { + return err + } + if err := cbkt.Put([]byte(name), nil); err != nil { + return err + } + + if err := bbkt.Put(bucketKeyParent, parent); err != nil { + return err + } } ts := time.Now().UTC() if err := boltutil.WriteTimestamps(bbkt, ts, ts); err != nil { @@ -382,29 +433,55 @@ func (s *snapshotter) Commit(ctx context.Context, name, key string, opts ...snap } func (s *snapshotter) Remove(ctx context.Context, key string) error { + s.l.RLock() + defer s.l.RUnlock() + ns, err := namespaces.NamespaceRequired(ctx) if err != nil { return err } return update(ctx, s.db, func(tx *bolt.Tx) error { - var bkey string + var sbkt *bolt.Bucket bkt := getSnapshotterBucket(tx, ns, s.name) if bkt != nil { - sbkt := bkt.Bucket([]byte(key)) - if sbkt != nil { - bkey = string(sbkt.Get(bucketKeyName)) - } + sbkt = bkt.Bucket([]byte(key)) } - if bkey == "" { + if sbkt == nil { return errors.Wrapf(errdefs.ErrNotFound, "snapshot %v does not exist", key) } + cbkt := sbkt.Bucket(bucketKeyChildren) + if cbkt != nil { + if child, _ := cbkt.Cursor().First(); child != nil { + return errors.Wrap(errdefs.ErrFailedPrecondition, "cannot remove snapshot with child") + } + } + + parent := sbkt.Get(bucketKeyParent) + if len(parent) > 0 { + pbkt := bkt.Bucket(parent) + if pbkt == nil { + return errors.Wrapf(errdefs.ErrNotFound, "parent snapshot %v does not exist", string(parent)) + } + cbkt := pbkt.Bucket(bucketKeyChildren) + if cbkt != nil { + if err := cbkt.Delete([]byte(key)); err != nil { + return errors.Wrap(err, "failed to remove child link") + } + } + } + if err := bkt.DeleteBucket([]byte(key)); err != nil { return err } - return s.Snapshotter.Remove(ctx, bkey) + // Mark snapshotter as dirty for triggering garbage collection + s.db.dirtyL.Lock() + s.db.dirtySS[s.name] = struct{}{} + s.db.dirtyL.Unlock() + + return nil }) } @@ -502,3 +579,144 @@ func (s *snapshotter) Walk(ctx context.Context, fn func(context.Context, snapsho return nil } + +func validateSnapshot(info *snapshot.Info) error { + for k, v := range info.Labels { + if err := labels.Validate(k, v); err != nil { + return errors.Wrapf(err, "info.Labels") + } + } + + return nil +} + +func (s *snapshotter) garbageCollect(ctx context.Context) error { + logger := log.G(ctx).WithField("snapshotter", s.name) + lt1 := time.Now() + s.l.Lock() + defer func() { + s.l.Unlock() + logger.WithField("t", time.Now().Sub(lt1)).Debugf("garbage collected") + }() + + seen := map[string]struct{}{} + if err := s.db.View(func(tx *bolt.Tx) error { + v1bkt := tx.Bucket(bucketKeyVersion) + if v1bkt == nil { + return nil + } + + // iterate through each namespace + v1c := v1bkt.Cursor() + + for k, v := v1c.First(); k != nil; k, v = v1c.Next() { + if v != nil { + continue + } + + sbkt := v1bkt.Bucket(k).Bucket(bucketKeyObjectSnapshots) + if sbkt == nil { + continue + } + + // Load specific snapshotter + ssbkt := sbkt.Bucket([]byte(s.name)) + if ssbkt == nil { + continue + } + + if err := ssbkt.ForEach(func(sk, sv []byte) error { + if sv == nil { + bkey := ssbkt.Bucket(sk).Get(bucketKeyName) + if len(bkey) > 0 { + seen[string(bkey)] = struct{}{} + } + } + return nil + }); err != nil { + return err + } + } + + return nil + }); err != nil { + return err + } + + roots, err := s.walkTree(ctx, seen) + if err != nil { + return err + } + + // TODO: Unlock before prune (once nodes are fully unavailable) + + for _, node := range roots { + if err := s.pruneBranch(ctx, node); err != nil { + return err + } + } + + return nil +} + +type treeNode struct { + info snapshot.Info + remove bool + children []*treeNode +} + +func (s *snapshotter) walkTree(ctx context.Context, seen map[string]struct{}) ([]*treeNode, error) { + roots := []*treeNode{} + nodes := map[string]*treeNode{} + + if err := s.Snapshotter.Walk(ctx, func(ctx context.Context, info snapshot.Info) error { + _, isSeen := seen[info.Name] + node, ok := nodes[info.Name] + if !ok { + node = &treeNode{} + nodes[info.Name] = node + } + + node.remove = !isSeen + node.info = info + + if info.Parent == "" { + roots = append(roots, node) + } else { + parent, ok := nodes[info.Parent] + if !ok { + parent = &treeNode{} + nodes[info.Parent] = parent + } + parent.children = append(parent.children, node) + } + + return nil + }); err != nil { + return nil, err + } + + return roots, nil +} + +func (s *snapshotter) pruneBranch(ctx context.Context, node *treeNode) error { + for _, child := range node.children { + if err := s.pruneBranch(ctx, child); err != nil { + return err + } + } + + if node.remove { + logger := log.G(ctx).WithField("snapshotter", s.name) + if err := s.Snapshotter.Remove(ctx, node.info.Name); err != nil { + if !errdefs.IsFailedPrecondition(err) { + return err + } + logger.WithError(err).WithField("key", node.info.Name).Warnf("snapshot removal failed") + } else { + logger.WithField("key", node.info.Name).Debug("removed snapshot") + } + } + + return nil +} diff --git a/vendor/github.com/containerd/containerd/mount/lookup_unix.go b/vendor/github.com/containerd/containerd/mount/lookup_unix.go index ae1b6a337830a..df9625a968d72 100644 --- a/vendor/github.com/containerd/containerd/mount/lookup_unix.go +++ b/vendor/github.com/containerd/containerd/mount/lookup_unix.go @@ -4,6 +4,9 @@ package mount import ( "fmt" + "path/filepath" + "sort" + "strings" "syscall" "github.com/pkg/errors" @@ -12,6 +15,7 @@ import ( // Lookup returns the mount info corresponds to the path. func Lookup(dir string) (Info, error) { var dirStat syscall.Stat_t + dir = filepath.Clean(dir) if err := syscall.Stat(dir, &dirStat); err != nil { return Info{}, errors.Wrapf(err, "failed to access %q", dir) } @@ -20,6 +24,11 @@ func Lookup(dir string) (Info, error) { if err != nil { return Info{}, err } + + // Sort descending order by Info.Mountpoint + sort.Slice(mounts, func(i, j int) bool { + return mounts[j].Mountpoint < mounts[i].Mountpoint + }) for _, m := range mounts { // Note that m.{Major, Minor} are generally unreliable for our purpose here // https://www.spinics.net/lists/linux-btrfs/msg58908.html @@ -28,7 +37,7 @@ func Lookup(dir string) (Info, error) { // may fail; ignore err continue } - if st.Dev == dirStat.Dev { + if st.Dev == dirStat.Dev && strings.HasPrefix(dir, m.Mountpoint) { return m, nil } } diff --git a/vendor/github.com/containerd/containerd/mount/mount.go b/vendor/github.com/containerd/containerd/mount/mount.go index 94086f178644b..94c2c9f927ee6 100644 --- a/vendor/github.com/containerd/containerd/mount/mount.go +++ b/vendor/github.com/containerd/containerd/mount/mount.go @@ -13,8 +13,8 @@ type Mount struct { Options []string } -// MountAll mounts all the provided mounts to the provided target -func MountAll(mounts []Mount, target string) error { +// All mounts all the provided mounts to the provided target +func All(mounts []Mount, target string) error { for _, m := range mounts { if err := m.Mount(target); err != nil { return err diff --git a/vendor/github.com/containerd/containerd/mount/mount_linux.go b/vendor/github.com/containerd/containerd/mount/mount_linux.go index 906703c15e89a..474792d8eb571 100644 --- a/vendor/github.com/containerd/containerd/mount/mount_linux.go +++ b/vendor/github.com/containerd/containerd/mount/mount_linux.go @@ -6,6 +6,7 @@ import ( "golang.org/x/sys/unix" ) +// Mount to the provided target path func (m *Mount) Mount(target string) error { flags, data := parseMountOptions(m.Options) @@ -40,6 +41,7 @@ func (m *Mount) Mount(target string) error { return nil } +// Unmount the provided mount path with the flags func Unmount(mount string, flags int) error { return unix.Unmount(mount, flags) } diff --git a/vendor/github.com/containerd/containerd/mount/mount_solaris.go b/vendor/github.com/containerd/containerd/mount/mount_solaris.go deleted file mode 100644 index 3b6c35d7481bf..0000000000000 --- a/vendor/github.com/containerd/containerd/mount/mount_solaris.go +++ /dev/null @@ -1,83 +0,0 @@ -package mount - -// On Solaris we can't invoke the mount system call directly. First, -// the mount system call takes more than 6 arguments, and go doesn't -// support invoking system calls that take more than 6 arguments. Past -// that, the mount system call is a private interfaces. For example, -// the arguments and data structures passed to the kernel to create an -// nfs mount are private and can change at any time. The only public -// and stable interface for creating mounts on Solaris is the mount.8 -// command, so we'll invoke that here. - -import ( - "bytes" - "errors" - "fmt" - "os/exec" - "strings" - - "golang.org/x/sys/unix" -) - -const ( - mountCmd = "/usr/sbin/mount" -) - -func doMount(arg ...string) error { - cmd := exec.Command(mountCmd, arg...) - - /* Setup Stdin, Stdout, and Stderr */ - stderr := new(bytes.Buffer) - cmd.Stdin = nil - cmd.Stdout = nil - cmd.Stderr = stderr - - /* - * Run the command. If the command fails create a new error - * object to return that includes stderr output. - */ - err := cmd.Start() - if err != nil { - return err - } - err = cmd.Wait() - if err != nil { - return errors.New(fmt.Sprintf("%v: %s", err, stderr.String())) - } - return nil -} - -func (m *Mount) Mount(target string) error { - var err error - - if len(m.Options) == 0 { - err = doMount("-F", m.Type, m.Source, target) - } else { - err = doMount("-F", m.Type, "-o", strings.Join(m.Options, ","), - m.Source, target) - } - return err -} - -func Unmount(mount string, flags int) error { - return unix.Unmount(mount, flags) -} - -// UnmountAll repeatedly unmounts the given mount point until there -// are no mounts remaining (EINVAL is returned by mount), which is -// useful for undoing a stack of mounts on the same mount point. -func UnmountAll(mount string, flags int) error { - for { - if err := Unmount(mount, flags); err != nil { - // EINVAL is returned if the target is not a - // mount point, indicating that we are - // done. It can also indicate a few other - // things (such as invalid flags) which we - // unfortunately end up squelching here too. - if err == unix.EINVAL { - return nil - } - return err - } - } -} diff --git a/vendor/github.com/containerd/containerd/mount/mount_windows.go b/vendor/github.com/containerd/containerd/mount/mount_windows.go index 8eeca681747b2..8ad7eab1291e2 100644 --- a/vendor/github.com/containerd/containerd/mount/mount_windows.go +++ b/vendor/github.com/containerd/containerd/mount/mount_windows.go @@ -3,17 +3,21 @@ package mount import "github.com/pkg/errors" var ( + // ErrNotImplementOnWindows is returned when an action is not implemented for windows ErrNotImplementOnWindows = errors.New("not implemented under windows") ) +// Mount to the provided target func (m *Mount) Mount(target string) error { return ErrNotImplementOnWindows } +// Unmount the mount at the provided path func Unmount(mount string, flags int) error { return ErrNotImplementOnWindows } +// UnmountAll mounts at the provided path func UnmountAll(mount string, flags int) error { return ErrNotImplementOnWindows } diff --git a/vendor/github.com/containerd/containerd/mount/mountinfo_solaris.go b/vendor/github.com/containerd/containerd/mount/mountinfo_solaris.go deleted file mode 100644 index 9ba5c3d4447c4..0000000000000 --- a/vendor/github.com/containerd/containerd/mount/mountinfo_solaris.go +++ /dev/null @@ -1,43 +0,0 @@ -// +build solaris,cgo - -package mount - -/* -#include -#include -*/ -import "C" - -import ( - "fmt" -) - -// Self retrieves a list of mounts for the current running process. -func Self() ([]Info, error) { - mnttab := C.fopen(C.CString(C.MNTTAB), C.CString("r")) - if mnttab == nil { - return nil, fmt.Errorf("Failed to open %s", C.MNTTAB) - } - - var out []Info - var mp C.struct_mnttab - - ret := C.getmntent(mnttab, &mp) - for ret == 0 { - var mountinfo Info - mountinfo.Mountpoint = C.GoString(mp.mnt_mountp) - mountinfo.Source = C.GoString(mp.mnt_special) - mountinfo.FSType = C.GoString(mp.mnt_fstype) - mountinfo.Options = C.GoString(mp.mnt_mntopts) - out = append(out, mountinfo) - ret = C.getmntent(mnttab, &mp) - } - - C.fclose(mnttab) - return out, nil -} - -// PID collects the mounts for a specific process ID. -func PID(pid int) ([]Info, error) { - return nil, fmt.Errorf("mountinfo.PID is not implemented on solaris") -} diff --git a/vendor/github.com/containerd/containerd/namespaces/context.go b/vendor/github.com/containerd/containerd/namespaces/context.go index 6f9faf8a3aa77..70871148735d0 100644 --- a/vendor/github.com/containerd/containerd/namespaces/context.go +++ b/vendor/github.com/containerd/containerd/namespaces/context.go @@ -9,8 +9,10 @@ import ( ) const ( + // NamespaceEnvVar is the environment variable key name NamespaceEnvVar = "CONTAINERD_NAMESPACE" - Default = "default" + // Default is the name of the default namespace + Default = "default" ) type namespaceKey struct{} diff --git a/vendor/github.com/containerd/containerd/platforms/defaults.go b/vendor/github.com/containerd/containerd/platforms/defaults.go index d49912052f1fd..2b57b49795355 100644 --- a/vendor/github.com/containerd/containerd/platforms/defaults.go +++ b/vendor/github.com/containerd/containerd/platforms/defaults.go @@ -6,8 +6,13 @@ import ( specs "github.com/opencontainers/image-spec/specs-go/v1" ) -// Default returns the current platform's default platform specification. -func Default() specs.Platform { +// Default returns the default specifier for the platform. +func Default() string { + return Format(DefaultSpec()) +} + +// DefaultSpec returns the current platform's default platform specification. +func DefaultSpec() specs.Platform { return specs.Platform{ OS: runtime.GOOS, Architecture: runtime.GOARCH, diff --git a/vendor/github.com/containerd/containerd/plugin/context.go b/vendor/github.com/containerd/containerd/plugin/context.go index dc5fb1528a31f..67ad2aa440a9e 100644 --- a/vendor/github.com/containerd/containerd/plugin/context.go +++ b/vendor/github.com/containerd/containerd/plugin/context.go @@ -2,44 +2,129 @@ package plugin import ( "context" - "fmt" "path/filepath" + "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/events" "github.com/containerd/containerd/log" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/pkg/errors" ) -func NewContext(ctx context.Context, plugins map[PluginType]map[string]interface{}, root, state, id string) *InitContext { - return &InitContext{ - plugins: plugins, - Root: filepath.Join(root, id), - State: filepath.Join(state, id), - Context: log.WithModule(ctx, id), - } -} - +// InitContext is used for plugin inititalization type InitContext struct { + Context context.Context Root string State string - Address string - Context context.Context Config interface{} + Address string Events *events.Exchange - plugins map[PluginType]map[string]interface{} + Meta *Meta // plugins can fill in metadata at init. + + plugins *Set +} + +// NewContext returns a new plugin InitContext +func NewContext(ctx context.Context, r *Registration, plugins *Set, root, state string) *InitContext { + return &InitContext{ + Context: log.WithModule(ctx, r.URI()), + Root: filepath.Join(root, r.URI()), + State: filepath.Join(state, r.URI()), + Meta: &Meta{ + Exports: map[string]string{}, + }, + plugins: plugins, + } +} + +// Get returns the first plugin by its type +func (i *InitContext) Get(t Type) (interface{}, error) { + return i.plugins.Get(t) +} + +// Meta contains information gathered from the registration and initialization +// process. +type Meta struct { + Platforms []ocispec.Platform // platforms supported by plugin + Exports map[string]string // values exported by plugin + Capabilities []string // feature switches for plugin } -func (i *InitContext) Get(t PluginType) (interface{}, error) { - for _, v := range i.plugins[t] { - return v, nil +// Plugin represents an initialized plugin, used with an init context. +type Plugin struct { + Registration *Registration // registration, as initialized + Config interface{} // config, as initialized + Meta *Meta + + instance interface{} + err error // will be set if there was an error initializing the plugin +} + +// Err returns the errors during initialization. +// returns nil if not error was encountered +func (p *Plugin) Err() error { + return p.err +} + +// Instance returns the instance and any initialization error of the plugin +func (p *Plugin) Instance() (interface{}, error) { + return p.instance, p.err +} + +// Set defines a plugin collection, used with InitContext. +// +// This maintains ordering and unique indexing over the set. +// +// After iteratively instantiating plugins, this set should represent, the +// ordered, initialization set of plugins for a containerd instance. +type Set struct { + ordered []*Plugin // order of initialization + byTypeAndID map[Type]map[string]*Plugin +} + +// NewPluginSet returns an initialized plugin set +func NewPluginSet() *Set { + return &Set{ + byTypeAndID: make(map[Type]map[string]*Plugin), } - return nil, fmt.Errorf("no plugins registered for %s", t) } -func (i *InitContext) GetAll(t PluginType) (map[string]interface{}, error) { - p, ok := i.plugins[t] +// Add a plugin to the set +func (ps *Set) Add(p *Plugin) error { + if byID, typeok := ps.byTypeAndID[p.Registration.Type]; !typeok { + ps.byTypeAndID[p.Registration.Type] = map[string]*Plugin{ + p.Registration.ID: p, + } + } else if _, idok := byID[p.Registration.ID]; !idok { + byID[p.Registration.ID] = p + } else { + return errors.Wrapf(errdefs.ErrAlreadyExists, "plugin %v already initialized", p.Registration.URI()) + } + + ps.ordered = append(ps.ordered, p) + return nil +} + +// Get returns the first plugin by its type +func (ps *Set) Get(t Type) (interface{}, error) { + for _, v := range ps.byTypeAndID[t] { + return v.Instance() + } + return nil, errors.Wrapf(errdefs.ErrNotFound, "no plugins registered for %s", t) +} + +// GetAll plugins in the set +func (i *InitContext) GetAll() []*Plugin { + return i.plugins.ordered +} + +// GetByType returns all plugins with the specific type. +func (i *InitContext) GetByType(t Type) (map[string]*Plugin, error) { + p, ok := i.plugins.byTypeAndID[t] if !ok { - return nil, fmt.Errorf("no plugins registered for %s", t) + return nil, errors.Wrapf(errdefs.ErrNotFound, "no plugins registered for %s", t) } + return p, nil } diff --git a/vendor/github.com/containerd/containerd/plugin/differ.go b/vendor/github.com/containerd/containerd/plugin/differ.go deleted file mode 100644 index 80c3c61819570..0000000000000 --- a/vendor/github.com/containerd/containerd/plugin/differ.go +++ /dev/null @@ -1,12 +0,0 @@ -package plugin - -import ( - "github.com/containerd/containerd/mount" - ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "golang.org/x/net/context" -) - -type Differ interface { - Apply(ctx context.Context, desc ocispec.Descriptor, mount []mount.Mount) (ocispec.Descriptor, error) - DiffMounts(ctx context.Context, lower, upper []mount.Mount, media, ref string) (ocispec.Descriptor, error) -} diff --git a/vendor/github.com/containerd/containerd/plugin/plugin.go b/vendor/github.com/containerd/containerd/plugin/plugin.go index 7f8461790c795..9bda46cbfabad 100644 --- a/vendor/github.com/containerd/containerd/plugin/plugin.go +++ b/vendor/github.com/containerd/containerd/plugin/plugin.go @@ -9,55 +9,94 @@ import ( ) var ( - ErrNoPluginType = errors.New("plugin: no type") - ErrNoPluginID = errors.New("plugin: no id") + // ErrNoType is returned when no type is specified + ErrNoType = errors.New("plugin: no type") + // ErrNoPluginID is returned when no id is specified + ErrNoPluginID = errors.New("plugin: no id") - // SkipPlugin is used when a plugin is not initialized and should not be loaded, + // ErrSkipPlugin is used when a plugin is not initialized and should not be loaded, // this allows the plugin loader differentiate between a plugin which is configured // not to load and one that fails to load. - SkipPlugin = errors.New("skip plugin") + ErrSkipPlugin = errors.New("skip plugin") + + // ErrInvalidRequires will be thrown if the requirements for a plugin are + // defined in an invalid manner. + ErrInvalidRequires = errors.New("invalid requires") ) // IsSkipPlugin returns true if the error is skipping the plugin func IsSkipPlugin(err error) bool { - if errors.Cause(err) == SkipPlugin { + if errors.Cause(err) == ErrSkipPlugin { return true } return false } -type PluginType string +// Type is the type of the plugin +type Type string + +func (t Type) String() string { return string(t) } const ( - RuntimePlugin PluginType = "io.containerd.runtime.v1" - GRPCPlugin PluginType = "io.containerd.grpc.v1" - SnapshotPlugin PluginType = "io.containerd.snapshotter.v1" - TaskMonitorPlugin PluginType = "io.containerd.monitor.v1" - DiffPlugin PluginType = "io.containerd.differ.v1" - MetadataPlugin PluginType = "io.containerd.metadata.v1" - ContentPlugin PluginType = "io.containerd.content.v1" + // AllPlugins declares that the plugin should be initialized after all others. + AllPlugins Type = "*" + // RuntimePlugin implements a runtime + RuntimePlugin Type = "io.containerd.runtime.v1" + // GRPCPlugin implements a grpc service + GRPCPlugin Type = "io.containerd.grpc.v1" + // SnapshotPlugin implements a snapshotter + SnapshotPlugin Type = "io.containerd.snapshotter.v1" + // TaskMonitorPlugin implements a task monitor + TaskMonitorPlugin Type = "io.containerd.monitor.v1" + // DiffPlugin implements a differ + DiffPlugin Type = "io.containerd.differ.v1" + // MetadataPlugin implements a metadata store + MetadataPlugin Type = "io.containerd.metadata.v1" + // ContentPlugin implements a content store + ContentPlugin Type = "io.containerd.content.v1" ) +// Registration contains information for registering a plugin type Registration struct { - Type PluginType - ID string - Config interface{} - Requires []PluginType - Init func(*InitContext) (interface{}, error) + // Type of the plugin + Type Type + // ID of the plugin + ID string + // Config specific to the plugin + Config interface{} + // Requires is a list of plugins that the registered plugin requires to be available + Requires []Type + + // InitFn is called when initializing a plugin. The registration and + // context are passed in. The init function may modify the registration to + // add exports, capabilites and platform support declarations. + InitFn func(*InitContext) (interface{}, error) +} - added bool +// Init the registered plugin +func (r *Registration) Init(ic *InitContext) *Plugin { + p, err := r.InitFn(ic) + return &Plugin{ + Registration: r, + Config: ic.Config, + Meta: ic.Meta, + instance: p, + err: err, + } } +// URI returns the full plugin URI func (r *Registration) URI() string { return fmt.Sprintf("%s.%s", r.Type, r.ID) } +// Service allows GRPC services to be registered with the underlying server type Service interface { Register(*grpc.Server) error } var register = struct { - sync.Mutex + sync.RWMutex r []*Registration }{} @@ -75,37 +114,55 @@ func Load(path string) (err error) { return loadPlugins(path) } +// Register allows plugins to register func Register(r *Registration) { register.Lock() defer register.Unlock() if r.Type == "" { - panic(ErrNoPluginType) + panic(ErrNoType) } if r.ID == "" { panic(ErrNoPluginID) } + + var last bool + for _, requires := range r.Requires { + if requires == "*" { + last = true + } + } + if last && len(r.Requires) != 1 { + panic(ErrInvalidRequires) + } + register.r = append(register.r, r) } +// Graph returns an ordered list of registered plugins for initialization func Graph() (ordered []*Registration) { + register.RLock() + defer register.RUnlock() + + added := map[*Registration]bool{} for _, r := range register.r { - children(r.Requires, &ordered) - if !r.added { + + children(r.ID, r.Requires, added, &ordered) + if !added[r] { ordered = append(ordered, r) - r.added = true + added[r] = true } } return ordered } -func children(types []PluginType, ordered *[]*Registration) { +func children(id string, types []Type, added map[*Registration]bool, ordered *[]*Registration) { for _, t := range types { for _, r := range register.r { - if r.Type == t { - children(r.Requires, ordered) - if !r.added { + if r.ID != id && (t == "*" || r.Type == t) { + children(r.ID, r.Requires, added, ordered) + if !added[r] { *ordered = append(*ordered, r) - r.added = true + added[r] = true } } } diff --git a/vendor/github.com/containerd/containerd/process.go b/vendor/github.com/containerd/containerd/process.go index 536d8a85ef3e1..e51367aaa14c2 100644 --- a/vendor/github.com/containerd/containerd/process.go +++ b/vendor/github.com/containerd/containerd/process.go @@ -6,11 +6,8 @@ import ( "syscall" "time" - eventsapi "github.com/containerd/containerd/api/services/events/v1" "github.com/containerd/containerd/api/services/tasks/v1" "github.com/containerd/containerd/errdefs" - "github.com/containerd/containerd/runtime" - "github.com/containerd/containerd/typeurl" "github.com/pkg/errors" ) @@ -121,54 +118,26 @@ func (p *process) Kill(ctx context.Context, s syscall.Signal, opts ...KillOpts) } func (p *process) Wait(ctx context.Context) (<-chan ExitStatus, error) { - cancellable, cancel := context.WithCancel(ctx) - eventstream, err := p.task.client.EventService().Subscribe(cancellable, &eventsapi.SubscribeRequest{ - Filters: []string{"topic==" + runtime.TaskExitEventTopic}, - }) - if err != nil { - cancel() - return nil, err - } - // first check if the task has exited - status, err := p.Status(ctx) - if err != nil { - cancel() - return nil, errdefs.FromGRPC(err) - } - - chStatus := make(chan ExitStatus, 1) - if status.Status == Stopped { - cancel() - chStatus <- ExitStatus{code: status.ExitStatus, exitedAt: status.ExitTime} - return chStatus, nil - } - + c := make(chan ExitStatus, 1) go func() { - defer cancel() - chStatus <- ExitStatus{} // signal that the goroutine is running - for { - evt, err := eventstream.Recv() - if err != nil { - chStatus <- ExitStatus{code: UnknownExitStatus, err: err} - return - } - if typeurl.Is(evt.Event, &eventsapi.TaskExit{}) { - v, err := typeurl.UnmarshalAny(evt.Event) - if err != nil { - chStatus <- ExitStatus{code: UnknownExitStatus, err: err} - return - } - e := v.(*eventsapi.TaskExit) - if e.ID == p.id && e.ContainerID == p.task.id { - chStatus <- ExitStatus{code: e.ExitStatus, exitedAt: e.ExitedAt} - return - } + defer close(c) + r, err := p.task.client.TaskService().Wait(ctx, &tasks.WaitRequest{ + ContainerID: p.task.id, + ExecID: p.id, + }) + if err != nil { + c <- ExitStatus{ + code: UnknownExitStatus, + err: err, } + return + } + c <- ExitStatus{ + code: r.ExitStatus, + exitedAt: r.ExitedAt, } }() - - <-chStatus // wait for the goroutine to be running - return chStatus, nil + return c, nil } func (p *process) CloseIO(ctx context.Context, opts ...IOCloserOpts) error { diff --git a/vendor/github.com/containerd/containerd/protobuf/google/rpc/README.md b/vendor/github.com/containerd/containerd/protobuf/google/rpc/README.md new file mode 100644 index 0000000000000..b7f6bf0cbb065 --- /dev/null +++ b/vendor/github.com/containerd/containerd/protobuf/google/rpc/README.md @@ -0,0 +1,18 @@ +This package copies definitions used with GRPC to represent error conditions +within GRPC data types. These files are licensed under the provisions outlined +at the top of each file. + +## `containerd` + +This is moved from the [googleapis +project](https://github.com/googleapis/googleapis/tree/master/google/rpc) to +allow us to regenerate these types for use with gogoprotobuf. We can move this +away if google can generate these sensibly. + +These files were imported from changes after +7f47d894837ac1701ee555fd5c3d70e5d4a796b1. Updates should not be required. + +The other option is to get these into an upstream project, like gogoprotobuf. + +Note that the `go_package` option has been changed so that they generate +correctly in a common package in the containerd project. diff --git a/vendor/github.com/containerd/containerd/protobuf/google/rpc/code.pb.go b/vendor/github.com/containerd/containerd/protobuf/google/rpc/code.pb.go new file mode 100644 index 0000000000000..74537b7e611ba --- /dev/null +++ b/vendor/github.com/containerd/containerd/protobuf/google/rpc/code.pb.go @@ -0,0 +1,270 @@ +// Code generated by protoc-gen-gogo. +// source: github.com/containerd/containerd/protobuf/google/rpc/code.proto +// DO NOT EDIT! + +/* +Package rpc is a generated protocol buffer package. + +It is generated from these files: + github.com/containerd/containerd/protobuf/google/rpc/code.proto + github.com/containerd/containerd/protobuf/google/rpc/error_details.proto + github.com/containerd/containerd/protobuf/google/rpc/status.proto + +It has these top-level messages: + RetryInfo + DebugInfo + QuotaFailure + PreconditionFailure + BadRequest + RequestInfo + ResourceInfo + Help + LocalizedMessage + Status +*/ +package rpc + +import proto "github.com/gogo/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +// The canonical error codes for Google APIs. +// +// +// Sometimes multiple error codes may apply. Services should return +// the most specific error code that applies. For example, prefer +// `OUT_OF_RANGE` over `FAILED_PRECONDITION` if both codes apply. +// Similarly prefer `NOT_FOUND` or `ALREADY_EXISTS` over `FAILED_PRECONDITION`. +type Code int32 + +const ( + // Not an error; returned on success + // + // HTTP Mapping: 200 OK + Code_OK Code = 0 + // The operation was cancelled, typically by the caller. + // + // HTTP Mapping: 499 Client Closed Request + Code_CANCELLED Code = 1 + // Unknown error. For example, this error may be returned when + // a `Status` value received from another address space belongs to + // an error space that is not known in this address space. Also + // errors raised by APIs that do not return enough error information + // may be converted to this error. + // + // HTTP Mapping: 500 Internal Server Error + Code_UNKNOWN Code = 2 + // The client specified an invalid argument. Note that this differs + // from `FAILED_PRECONDITION`. `INVALID_ARGUMENT` indicates arguments + // that are problematic regardless of the state of the system + // (e.g., a malformed file name). + // + // HTTP Mapping: 400 Bad Request + Code_INVALID_ARGUMENT Code = 3 + // The deadline expired before the operation could complete. For operations + // that change the state of the system, this error may be returned + // even if the operation has completed successfully. For example, a + // successful response from a server could have been delayed long + // enough for the deadline to expire. + // + // HTTP Mapping: 504 Gateway Timeout + Code_DEADLINE_EXCEEDED Code = 4 + // Some requested entity (e.g., file or directory) was not found. + // + // Note to server developers: if a request is denied for an entire class + // of users, such as gradual feature rollout or undocumented whitelist, + // `NOT_FOUND` may be used. If a request is denied for some users within + // a class of users, such as user-based access control, `PERMISSION_DENIED` + // must be used. + // + // HTTP Mapping: 404 Not Found + Code_NOT_FOUND Code = 5 + // The entity that a client attempted to create (e.g., file or directory) + // already exists. + // + // HTTP Mapping: 409 Conflict + Code_ALREADY_EXISTS Code = 6 + // The caller does not have permission to execute the specified + // operation. `PERMISSION_DENIED` must not be used for rejections + // caused by exhausting some resource (use `RESOURCE_EXHAUSTED` + // instead for those errors). `PERMISSION_DENIED` must not be + // used if the caller can not be identified (use `UNAUTHENTICATED` + // instead for those errors). This error code does not imply the + // request is valid or the requested entity exists or satisfies + // other pre-conditions. + // + // HTTP Mapping: 403 Forbidden + Code_PERMISSION_DENIED Code = 7 + // The request does not have valid authentication credentials for the + // operation. + // + // HTTP Mapping: 401 Unauthorized + Code_UNAUTHENTICATED Code = 16 + // Some resource has been exhausted, perhaps a per-user quota, or + // perhaps the entire file system is out of space. + // + // HTTP Mapping: 429 Too Many Requests + Code_RESOURCE_EXHAUSTED Code = 8 + // The operation was rejected because the system is not in a state + // required for the operation's execution. For example, the directory + // to be deleted is non-empty, an rmdir operation is applied to + // a non-directory, etc. + // + // Service implementors can use the following guidelines to decide + // between `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`: + // (a) Use `UNAVAILABLE` if the client can retry just the failing call. + // (b) Use `ABORTED` if the client should retry at a higher level + // (e.g., when a client-specified test-and-set fails, indicating the + // client should restart a read-modify-write sequence). + // (c) Use `FAILED_PRECONDITION` if the client should not retry until + // the system state has been explicitly fixed. E.g., if an "rmdir" + // fails because the directory is non-empty, `FAILED_PRECONDITION` + // should be returned since the client should not retry unless + // the files are deleted from the directory. + // + // HTTP Mapping: 400 Bad Request + Code_FAILED_PRECONDITION Code = 9 + // The operation was aborted, typically due to a concurrency issue such as + // a sequencer check failure or transaction abort. + // + // See the guidelines above for deciding between `FAILED_PRECONDITION`, + // `ABORTED`, and `UNAVAILABLE`. + // + // HTTP Mapping: 409 Conflict + Code_ABORTED Code = 10 + // The operation was attempted past the valid range. E.g., seeking or + // reading past end-of-file. + // + // Unlike `INVALID_ARGUMENT`, this error indicates a problem that may + // be fixed if the system state changes. For example, a 32-bit file + // system will generate `INVALID_ARGUMENT` if asked to read at an + // offset that is not in the range [0,2^32-1], but it will generate + // `OUT_OF_RANGE` if asked to read from an offset past the current + // file size. + // + // There is a fair bit of overlap between `FAILED_PRECONDITION` and + // `OUT_OF_RANGE`. We recommend using `OUT_OF_RANGE` (the more specific + // error) when it applies so that callers who are iterating through + // a space can easily look for an `OUT_OF_RANGE` error to detect when + // they are done. + // + // HTTP Mapping: 400 Bad Request + Code_OUT_OF_RANGE Code = 11 + // The operation is not implemented or is not supported/enabled in this + // service. + // + // HTTP Mapping: 501 Not Implemented + Code_UNIMPLEMENTED Code = 12 + // Internal errors. This means that some invariants expected by the + // underlying system have been broken. This error code is reserved + // for serious errors. + // + // HTTP Mapping: 500 Internal Server Error + Code_INTERNAL Code = 13 + // The service is currently unavailable. This is most likely a + // transient condition, which can be corrected by retrying with + // a backoff. + // + // See the guidelines above for deciding between `FAILED_PRECONDITION`, + // `ABORTED`, and `UNAVAILABLE`. + // + // HTTP Mapping: 503 Service Unavailable + Code_UNAVAILABLE Code = 14 + // Unrecoverable data loss or corruption. + // + // HTTP Mapping: 500 Internal Server Error + Code_DATA_LOSS Code = 15 +) + +var Code_name = map[int32]string{ + 0: "OK", + 1: "CANCELLED", + 2: "UNKNOWN", + 3: "INVALID_ARGUMENT", + 4: "DEADLINE_EXCEEDED", + 5: "NOT_FOUND", + 6: "ALREADY_EXISTS", + 7: "PERMISSION_DENIED", + 16: "UNAUTHENTICATED", + 8: "RESOURCE_EXHAUSTED", + 9: "FAILED_PRECONDITION", + 10: "ABORTED", + 11: "OUT_OF_RANGE", + 12: "UNIMPLEMENTED", + 13: "INTERNAL", + 14: "UNAVAILABLE", + 15: "DATA_LOSS", +} +var Code_value = map[string]int32{ + "OK": 0, + "CANCELLED": 1, + "UNKNOWN": 2, + "INVALID_ARGUMENT": 3, + "DEADLINE_EXCEEDED": 4, + "NOT_FOUND": 5, + "ALREADY_EXISTS": 6, + "PERMISSION_DENIED": 7, + "UNAUTHENTICATED": 16, + "RESOURCE_EXHAUSTED": 8, + "FAILED_PRECONDITION": 9, + "ABORTED": 10, + "OUT_OF_RANGE": 11, + "UNIMPLEMENTED": 12, + "INTERNAL": 13, + "UNAVAILABLE": 14, + "DATA_LOSS": 15, +} + +func (x Code) String() string { + return proto.EnumName(Code_name, int32(x)) +} +func (Code) EnumDescriptor() ([]byte, []int) { return fileDescriptorCode, []int{0} } + +func init() { + proto.RegisterEnum("google.rpc.Code", Code_name, Code_value) +} + +func init() { + proto.RegisterFile("github.com/containerd/containerd/protobuf/google/rpc/code.proto", fileDescriptorCode) +} + +var fileDescriptorCode = []byte{ + // 405 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x91, 0xbb, 0x72, 0x13, 0x31, + 0x14, 0x86, 0xbd, 0x4e, 0x70, 0x62, 0xf9, 0x76, 0xa2, 0x70, 0xe9, 0xf6, 0x01, 0x28, 0xec, 0x82, + 0x86, 0x19, 0x0a, 0xe6, 0x78, 0x75, 0x9c, 0x68, 0x22, 0x1f, 0xed, 0x68, 0xa5, 0x10, 0x68, 0x76, + 0xf0, 0xda, 0x98, 0xcc, 0x90, 0xac, 0x67, 0xc7, 0xee, 0x79, 0x16, 0x5e, 0x82, 0x57, 0x48, 0x49, + 0x49, 0x49, 0xfc, 0x24, 0x8c, 0x4c, 0x01, 0x35, 0x9d, 0xe6, 0xff, 0x75, 0x2e, 0xff, 0x77, 0xc4, + 0xdb, 0xf5, 0xed, 0xf6, 0xf3, 0x6e, 0x31, 0xae, 0xea, 0xbb, 0x49, 0x55, 0xdf, 0x6f, 0x3f, 0xde, + 0xde, 0xaf, 0x9a, 0xe5, 0xbf, 0xcf, 0x4d, 0x53, 0x6f, 0xeb, 0xc5, 0xee, 0xd3, 0x64, 0x5d, 0xd7, + 0xeb, 0x2f, 0xab, 0x49, 0xb3, 0xa9, 0x26, 0x55, 0xbd, 0x5c, 0x8d, 0x0f, 0x86, 0x14, 0x7f, 0xe4, + 0x71, 0xb3, 0xa9, 0x5e, 0x7e, 0x6f, 0x8b, 0xe3, 0xac, 0x5e, 0xae, 0x64, 0x47, 0xb4, 0xed, 0x15, + 0xb4, 0xe4, 0x40, 0x74, 0x33, 0xe4, 0x8c, 0x8c, 0x21, 0x05, 0x89, 0xec, 0x89, 0x93, 0xc0, 0x57, + 0x6c, 0xdf, 0x31, 0xb4, 0xe5, 0x53, 0x01, 0x9a, 0xaf, 0xd1, 0x68, 0x55, 0xa2, 0xbb, 0x08, 0x73, + 0x62, 0x0f, 0x47, 0xf2, 0x99, 0x38, 0x53, 0x84, 0xca, 0x68, 0xa6, 0x92, 0x6e, 0x32, 0x22, 0x45, + 0x0a, 0x8e, 0x63, 0x23, 0xb6, 0xbe, 0x9c, 0xd9, 0xc0, 0x0a, 0x9e, 0x48, 0x29, 0x86, 0x68, 0x1c, + 0xa1, 0x7a, 0x5f, 0xd2, 0x8d, 0x2e, 0x7c, 0x01, 0x9d, 0x58, 0x99, 0x93, 0x9b, 0xeb, 0xa2, 0xd0, + 0x96, 0x4b, 0x45, 0xac, 0x49, 0xc1, 0x89, 0x3c, 0x17, 0xa3, 0xc0, 0x18, 0xfc, 0x25, 0xb1, 0xd7, + 0x19, 0x7a, 0x52, 0x00, 0xf2, 0xb9, 0x90, 0x8e, 0x0a, 0x1b, 0x5c, 0x16, 0xa7, 0x5c, 0x62, 0x28, + 0xa2, 0x7e, 0x2a, 0x5f, 0x88, 0xf3, 0x19, 0x6a, 0x43, 0xaa, 0xcc, 0x1d, 0x65, 0x96, 0x95, 0xf6, + 0xda, 0x32, 0x74, 0xe3, 0xe6, 0x38, 0xb5, 0x2e, 0xfe, 0x12, 0x12, 0x44, 0xdf, 0x06, 0x5f, 0xda, + 0x59, 0xe9, 0x90, 0x2f, 0x08, 0x7a, 0xf2, 0x4c, 0x0c, 0x02, 0xeb, 0x79, 0x6e, 0x28, 0xc6, 0x20, + 0x05, 0x7d, 0xd9, 0x17, 0xa7, 0x9a, 0x3d, 0x39, 0x46, 0x03, 0x03, 0x39, 0x12, 0xbd, 0xc0, 0x78, + 0x8d, 0xda, 0xe0, 0xd4, 0x10, 0x0c, 0x63, 0x20, 0x85, 0x1e, 0x4b, 0x63, 0x8b, 0x02, 0x46, 0xd3, + 0xdd, 0xc3, 0x63, 0xda, 0xfa, 0xf9, 0x98, 0xb6, 0xbe, 0xee, 0xd3, 0xe4, 0x61, 0x9f, 0x26, 0x3f, + 0xf6, 0x69, 0xf2, 0x6b, 0x9f, 0x26, 0x62, 0x58, 0xd5, 0x77, 0xe3, 0xbf, 0x8c, 0xa7, 0xdd, 0x08, + 0x38, 0x8f, 0xe8, 0xf3, 0xe4, 0xc3, 0xeb, 0xff, 0xb9, 0xde, 0x9b, 0x66, 0x53, 0x7d, 0x6b, 0x1f, + 0xb9, 0x3c, 0x5b, 0x74, 0x0e, 0xf6, 0xab, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xf2, 0x0a, 0x2d, + 0x67, 0x06, 0x02, 0x00, 0x00, +} diff --git a/vendor/github.com/containerd/containerd/protobuf/google/rpc/code.proto b/vendor/github.com/containerd/containerd/protobuf/google/rpc/code.proto new file mode 100644 index 0000000000000..adf4704ca247b --- /dev/null +++ b/vendor/github.com/containerd/containerd/protobuf/google/rpc/code.proto @@ -0,0 +1,186 @@ +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.rpc; + +option go_package = "github.com/containerd/containerd/protobuf/google/rpc;rpc"; +option java_multiple_files = true; +option java_outer_classname = "CodeProto"; +option java_package = "com.google.rpc"; +option objc_class_prefix = "RPC"; + + +// The canonical error codes for Google APIs. +// +// +// Sometimes multiple error codes may apply. Services should return +// the most specific error code that applies. For example, prefer +// `OUT_OF_RANGE` over `FAILED_PRECONDITION` if both codes apply. +// Similarly prefer `NOT_FOUND` or `ALREADY_EXISTS` over `FAILED_PRECONDITION`. +enum Code { + // Not an error; returned on success + // + // HTTP Mapping: 200 OK + OK = 0; + + // The operation was cancelled, typically by the caller. + // + // HTTP Mapping: 499 Client Closed Request + CANCELLED = 1; + + // Unknown error. For example, this error may be returned when + // a `Status` value received from another address space belongs to + // an error space that is not known in this address space. Also + // errors raised by APIs that do not return enough error information + // may be converted to this error. + // + // HTTP Mapping: 500 Internal Server Error + UNKNOWN = 2; + + // The client specified an invalid argument. Note that this differs + // from `FAILED_PRECONDITION`. `INVALID_ARGUMENT` indicates arguments + // that are problematic regardless of the state of the system + // (e.g., a malformed file name). + // + // HTTP Mapping: 400 Bad Request + INVALID_ARGUMENT = 3; + + // The deadline expired before the operation could complete. For operations + // that change the state of the system, this error may be returned + // even if the operation has completed successfully. For example, a + // successful response from a server could have been delayed long + // enough for the deadline to expire. + // + // HTTP Mapping: 504 Gateway Timeout + DEADLINE_EXCEEDED = 4; + + // Some requested entity (e.g., file or directory) was not found. + // + // Note to server developers: if a request is denied for an entire class + // of users, such as gradual feature rollout or undocumented whitelist, + // `NOT_FOUND` may be used. If a request is denied for some users within + // a class of users, such as user-based access control, `PERMISSION_DENIED` + // must be used. + // + // HTTP Mapping: 404 Not Found + NOT_FOUND = 5; + + // The entity that a client attempted to create (e.g., file or directory) + // already exists. + // + // HTTP Mapping: 409 Conflict + ALREADY_EXISTS = 6; + + // The caller does not have permission to execute the specified + // operation. `PERMISSION_DENIED` must not be used for rejections + // caused by exhausting some resource (use `RESOURCE_EXHAUSTED` + // instead for those errors). `PERMISSION_DENIED` must not be + // used if the caller can not be identified (use `UNAUTHENTICATED` + // instead for those errors). This error code does not imply the + // request is valid or the requested entity exists or satisfies + // other pre-conditions. + // + // HTTP Mapping: 403 Forbidden + PERMISSION_DENIED = 7; + + // The request does not have valid authentication credentials for the + // operation. + // + // HTTP Mapping: 401 Unauthorized + UNAUTHENTICATED = 16; + + // Some resource has been exhausted, perhaps a per-user quota, or + // perhaps the entire file system is out of space. + // + // HTTP Mapping: 429 Too Many Requests + RESOURCE_EXHAUSTED = 8; + + // The operation was rejected because the system is not in a state + // required for the operation's execution. For example, the directory + // to be deleted is non-empty, an rmdir operation is applied to + // a non-directory, etc. + // + // Service implementors can use the following guidelines to decide + // between `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`: + // (a) Use `UNAVAILABLE` if the client can retry just the failing call. + // (b) Use `ABORTED` if the client should retry at a higher level + // (e.g., when a client-specified test-and-set fails, indicating the + // client should restart a read-modify-write sequence). + // (c) Use `FAILED_PRECONDITION` if the client should not retry until + // the system state has been explicitly fixed. E.g., if an "rmdir" + // fails because the directory is non-empty, `FAILED_PRECONDITION` + // should be returned since the client should not retry unless + // the files are deleted from the directory. + // + // HTTP Mapping: 400 Bad Request + FAILED_PRECONDITION = 9; + + // The operation was aborted, typically due to a concurrency issue such as + // a sequencer check failure or transaction abort. + // + // See the guidelines above for deciding between `FAILED_PRECONDITION`, + // `ABORTED`, and `UNAVAILABLE`. + // + // HTTP Mapping: 409 Conflict + ABORTED = 10; + + // The operation was attempted past the valid range. E.g., seeking or + // reading past end-of-file. + // + // Unlike `INVALID_ARGUMENT`, this error indicates a problem that may + // be fixed if the system state changes. For example, a 32-bit file + // system will generate `INVALID_ARGUMENT` if asked to read at an + // offset that is not in the range [0,2^32-1], but it will generate + // `OUT_OF_RANGE` if asked to read from an offset past the current + // file size. + // + // There is a fair bit of overlap between `FAILED_PRECONDITION` and + // `OUT_OF_RANGE`. We recommend using `OUT_OF_RANGE` (the more specific + // error) when it applies so that callers who are iterating through + // a space can easily look for an `OUT_OF_RANGE` error to detect when + // they are done. + // + // HTTP Mapping: 400 Bad Request + OUT_OF_RANGE = 11; + + // The operation is not implemented or is not supported/enabled in this + // service. + // + // HTTP Mapping: 501 Not Implemented + UNIMPLEMENTED = 12; + + // Internal errors. This means that some invariants expected by the + // underlying system have been broken. This error code is reserved + // for serious errors. + // + // HTTP Mapping: 500 Internal Server Error + INTERNAL = 13; + + // The service is currently unavailable. This is most likely a + // transient condition, which can be corrected by retrying with + // a backoff. + // + // See the guidelines above for deciding between `FAILED_PRECONDITION`, + // `ABORTED`, and `UNAVAILABLE`. + // + // HTTP Mapping: 503 Service Unavailable + UNAVAILABLE = 14; + + // Unrecoverable data loss or corruption. + // + // HTTP Mapping: 500 Internal Server Error + DATA_LOSS = 15; +} diff --git a/vendor/github.com/containerd/containerd/protobuf/google/rpc/doc.go b/vendor/github.com/containerd/containerd/protobuf/google/rpc/doc.go new file mode 100644 index 0000000000000..9ab1e3e8e788d --- /dev/null +++ b/vendor/github.com/containerd/containerd/protobuf/google/rpc/doc.go @@ -0,0 +1 @@ +package rpc diff --git a/vendor/github.com/containerd/containerd/protobuf/google/rpc/error_details.pb.go b/vendor/github.com/containerd/containerd/protobuf/google/rpc/error_details.pb.go new file mode 100644 index 0000000000000..a61229d733417 --- /dev/null +++ b/vendor/github.com/containerd/containerd/protobuf/google/rpc/error_details.pb.go @@ -0,0 +1,2555 @@ +// Code generated by protoc-gen-gogo. +// source: github.com/containerd/containerd/protobuf/google/rpc/error_details.proto +// DO NOT EDIT! + +package rpc + +import proto "github.com/gogo/protobuf/proto" +import fmt "fmt" +import math "math" +import google_protobuf "github.com/gogo/protobuf/types" + +import strings "strings" +import reflect "reflect" + +import io "io" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// Describes when the clients can retry a failed request. Clients could ignore +// the recommendation here or retry when this information is missing from error +// responses. +// +// It's always recommended that clients should use exponential backoff when +// retrying. +// +// Clients should wait until `retry_delay` amount of time has passed since +// receiving the error response before retrying. If retrying requests also +// fail, clients should use an exponential backoff scheme to gradually increase +// the delay between retries based on `retry_delay`, until either a maximum +// number of retires have been reached or a maximum retry delay cap has been +// reached. +type RetryInfo struct { + // Clients should wait at least this long between retrying the same request. + RetryDelay *google_protobuf.Duration `protobuf:"bytes,1,opt,name=retry_delay,json=retryDelay" json:"retry_delay,omitempty"` +} + +func (m *RetryInfo) Reset() { *m = RetryInfo{} } +func (*RetryInfo) ProtoMessage() {} +func (*RetryInfo) Descriptor() ([]byte, []int) { return fileDescriptorErrorDetails, []int{0} } + +// Describes additional debugging info. +type DebugInfo struct { + // The stack trace entries indicating where the error occurred. + StackEntries []string `protobuf:"bytes,1,rep,name=stack_entries,json=stackEntries" json:"stack_entries,omitempty"` + // Additional debugging information provided by the server. + Detail string `protobuf:"bytes,2,opt,name=detail,proto3" json:"detail,omitempty"` +} + +func (m *DebugInfo) Reset() { *m = DebugInfo{} } +func (*DebugInfo) ProtoMessage() {} +func (*DebugInfo) Descriptor() ([]byte, []int) { return fileDescriptorErrorDetails, []int{1} } + +// Describes how a quota check failed. +// +// For example if a daily limit was exceeded for the calling project, +// a service could respond with a QuotaFailure detail containing the project +// id and the description of the quota limit that was exceeded. If the +// calling project hasn't enabled the service in the developer console, then +// a service could respond with the project id and set `service_disabled` +// to true. +// +// Also see RetryDetail and Help types for other details about handling a +// quota failure. +type QuotaFailure struct { + // Describes all quota violations. + Violations []*QuotaFailure_Violation `protobuf:"bytes,1,rep,name=violations" json:"violations,omitempty"` +} + +func (m *QuotaFailure) Reset() { *m = QuotaFailure{} } +func (*QuotaFailure) ProtoMessage() {} +func (*QuotaFailure) Descriptor() ([]byte, []int) { return fileDescriptorErrorDetails, []int{2} } + +// A message type used to describe a single quota violation. For example, a +// daily quota or a custom quota that was exceeded. +type QuotaFailure_Violation struct { + // The subject on which the quota check failed. + // For example, "clientip:" or "project:". + Subject string `protobuf:"bytes,1,opt,name=subject,proto3" json:"subject,omitempty"` + // A description of how the quota check failed. Clients can use this + // description to find more about the quota configuration in the service's + // public documentation, or find the relevant quota limit to adjust through + // developer console. + // + // For example: "Service disabled" or "Daily Limit for read operations + // exceeded". + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` +} + +func (m *QuotaFailure_Violation) Reset() { *m = QuotaFailure_Violation{} } +func (*QuotaFailure_Violation) ProtoMessage() {} +func (*QuotaFailure_Violation) Descriptor() ([]byte, []int) { + return fileDescriptorErrorDetails, []int{2, 0} +} + +// Describes what preconditions have failed. +// +// For example, if an RPC failed because it required the Terms of Service to be +// acknowledged, it could list the terms of service violation in the +// PreconditionFailure message. +type PreconditionFailure struct { + // Describes all precondition violations. + Violations []*PreconditionFailure_Violation `protobuf:"bytes,1,rep,name=violations" json:"violations,omitempty"` +} + +func (m *PreconditionFailure) Reset() { *m = PreconditionFailure{} } +func (*PreconditionFailure) ProtoMessage() {} +func (*PreconditionFailure) Descriptor() ([]byte, []int) { return fileDescriptorErrorDetails, []int{3} } + +// A message type used to describe a single precondition failure. +type PreconditionFailure_Violation struct { + // The type of PreconditionFailure. We recommend using a service-specific + // enum type to define the supported precondition violation types. For + // example, "TOS" for "Terms of Service violation". + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + // The subject, relative to the type, that failed. + // For example, "google.com/cloud" relative to the "TOS" type would + // indicate which terms of service is being referenced. + Subject string `protobuf:"bytes,2,opt,name=subject,proto3" json:"subject,omitempty"` + // A description of how the precondition failed. Developers can use this + // description to understand how to fix the failure. + // + // For example: "Terms of service not accepted". + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` +} + +func (m *PreconditionFailure_Violation) Reset() { *m = PreconditionFailure_Violation{} } +func (*PreconditionFailure_Violation) ProtoMessage() {} +func (*PreconditionFailure_Violation) Descriptor() ([]byte, []int) { + return fileDescriptorErrorDetails, []int{3, 0} +} + +// Describes violations in a client request. This error type focuses on the +// syntactic aspects of the request. +type BadRequest struct { + // Describes all violations in a client request. + FieldViolations []*BadRequest_FieldViolation `protobuf:"bytes,1,rep,name=field_violations,json=fieldViolations" json:"field_violations,omitempty"` +} + +func (m *BadRequest) Reset() { *m = BadRequest{} } +func (*BadRequest) ProtoMessage() {} +func (*BadRequest) Descriptor() ([]byte, []int) { return fileDescriptorErrorDetails, []int{4} } + +// A message type used to describe a single bad request field. +type BadRequest_FieldViolation struct { + // A path leading to a field in the request body. The value will be a + // sequence of dot-separated identifiers that identify a protocol buffer + // field. E.g., "field_violations.field" would identify this field. + Field string `protobuf:"bytes,1,opt,name=field,proto3" json:"field,omitempty"` + // A description of why the request element is bad. + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` +} + +func (m *BadRequest_FieldViolation) Reset() { *m = BadRequest_FieldViolation{} } +func (*BadRequest_FieldViolation) ProtoMessage() {} +func (*BadRequest_FieldViolation) Descriptor() ([]byte, []int) { + return fileDescriptorErrorDetails, []int{4, 0} +} + +// Contains metadata about the request that clients can attach when filing a bug +// or providing other forms of feedback. +type RequestInfo struct { + // An opaque string that should only be interpreted by the service generating + // it. For example, it can be used to identify requests in the service's logs. + RequestID string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` + // Any data that was used to serve this request. For example, an encrypted + // stack trace that can be sent back to the service provider for debugging. + ServingData string `protobuf:"bytes,2,opt,name=serving_data,json=servingData,proto3" json:"serving_data,omitempty"` +} + +func (m *RequestInfo) Reset() { *m = RequestInfo{} } +func (*RequestInfo) ProtoMessage() {} +func (*RequestInfo) Descriptor() ([]byte, []int) { return fileDescriptorErrorDetails, []int{5} } + +// Describes the resource that is being accessed. +type ResourceInfo struct { + // A name for the type of resource being accessed, e.g. "sql table", + // "cloud storage bucket", "file", "Google calendar"; or the type URL + // of the resource: e.g. "type.googleapis.com/google.pubsub.v1.Topic". + ResourceType string `protobuf:"bytes,1,opt,name=resource_type,json=resourceType,proto3" json:"resource_type,omitempty"` + // The name of the resource being accessed. For example, a shared calendar + // name: "example.com_4fghdhgsrgh@group.calendar.google.com", if the current + // error is [google.rpc.Code.PERMISSION_DENIED][google.rpc.Code.PERMISSION_DENIED]. + ResourceName string `protobuf:"bytes,2,opt,name=resource_name,json=resourceName,proto3" json:"resource_name,omitempty"` + // The owner of the resource (optional). + // For example, "user:" or "project:". + Owner string `protobuf:"bytes,3,opt,name=owner,proto3" json:"owner,omitempty"` + // Describes what error is encountered when accessing this resource. + // For example, updating a cloud project may require the `writer` permission + // on the developer console project. + Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"` +} + +func (m *ResourceInfo) Reset() { *m = ResourceInfo{} } +func (*ResourceInfo) ProtoMessage() {} +func (*ResourceInfo) Descriptor() ([]byte, []int) { return fileDescriptorErrorDetails, []int{6} } + +// Provides links to documentation or for performing an out of band action. +// +// For example, if a quota check failed with an error indicating the calling +// project hasn't enabled the accessed service, this can contain a URL pointing +// directly to the right place in the developer console to flip the bit. +type Help struct { + // URL(s) pointing to additional information on handling the current error. + Links []*Help_Link `protobuf:"bytes,1,rep,name=links" json:"links,omitempty"` +} + +func (m *Help) Reset() { *m = Help{} } +func (*Help) ProtoMessage() {} +func (*Help) Descriptor() ([]byte, []int) { return fileDescriptorErrorDetails, []int{7} } + +// Describes a URL link. +type Help_Link struct { + // Describes what the link offers. + Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` + // The URL of the link. + Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"` +} + +func (m *Help_Link) Reset() { *m = Help_Link{} } +func (*Help_Link) ProtoMessage() {} +func (*Help_Link) Descriptor() ([]byte, []int) { return fileDescriptorErrorDetails, []int{7, 0} } + +// Provides a localized error message that is safe to return to the user +// which can be attached to an RPC error. +type LocalizedMessage struct { + // The locale used following the specification defined at + // http://www.rfc-editor.org/rfc/bcp/bcp47.txt. + // Examples are: "en-US", "fr-CH", "es-MX" + Locale string `protobuf:"bytes,1,opt,name=locale,proto3" json:"locale,omitempty"` + // The localized error message in the above locale. + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` +} + +func (m *LocalizedMessage) Reset() { *m = LocalizedMessage{} } +func (*LocalizedMessage) ProtoMessage() {} +func (*LocalizedMessage) Descriptor() ([]byte, []int) { return fileDescriptorErrorDetails, []int{8} } + +func init() { + proto.RegisterType((*RetryInfo)(nil), "google.rpc.RetryInfo") + proto.RegisterType((*DebugInfo)(nil), "google.rpc.DebugInfo") + proto.RegisterType((*QuotaFailure)(nil), "google.rpc.QuotaFailure") + proto.RegisterType((*QuotaFailure_Violation)(nil), "google.rpc.QuotaFailure.Violation") + proto.RegisterType((*PreconditionFailure)(nil), "google.rpc.PreconditionFailure") + proto.RegisterType((*PreconditionFailure_Violation)(nil), "google.rpc.PreconditionFailure.Violation") + proto.RegisterType((*BadRequest)(nil), "google.rpc.BadRequest") + proto.RegisterType((*BadRequest_FieldViolation)(nil), "google.rpc.BadRequest.FieldViolation") + proto.RegisterType((*RequestInfo)(nil), "google.rpc.RequestInfo") + proto.RegisterType((*ResourceInfo)(nil), "google.rpc.ResourceInfo") + proto.RegisterType((*Help)(nil), "google.rpc.Help") + proto.RegisterType((*Help_Link)(nil), "google.rpc.Help.Link") + proto.RegisterType((*LocalizedMessage)(nil), "google.rpc.LocalizedMessage") +} +func (m *RetryInfo) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RetryInfo) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.RetryDelay != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintErrorDetails(dAtA, i, uint64(m.RetryDelay.Size())) + n1, err := m.RetryDelay.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n1 + } + return i, nil +} + +func (m *DebugInfo) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DebugInfo) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.StackEntries) > 0 { + for _, s := range m.StackEntries { + dAtA[i] = 0xa + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } + if len(m.Detail) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintErrorDetails(dAtA, i, uint64(len(m.Detail))) + i += copy(dAtA[i:], m.Detail) + } + return i, nil +} + +func (m *QuotaFailure) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QuotaFailure) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Violations) > 0 { + for _, msg := range m.Violations { + dAtA[i] = 0xa + i++ + i = encodeVarintErrorDetails(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *QuotaFailure_Violation) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QuotaFailure_Violation) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Subject) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintErrorDetails(dAtA, i, uint64(len(m.Subject))) + i += copy(dAtA[i:], m.Subject) + } + if len(m.Description) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintErrorDetails(dAtA, i, uint64(len(m.Description))) + i += copy(dAtA[i:], m.Description) + } + return i, nil +} + +func (m *PreconditionFailure) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PreconditionFailure) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Violations) > 0 { + for _, msg := range m.Violations { + dAtA[i] = 0xa + i++ + i = encodeVarintErrorDetails(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *PreconditionFailure_Violation) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PreconditionFailure_Violation) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Type) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintErrorDetails(dAtA, i, uint64(len(m.Type))) + i += copy(dAtA[i:], m.Type) + } + if len(m.Subject) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintErrorDetails(dAtA, i, uint64(len(m.Subject))) + i += copy(dAtA[i:], m.Subject) + } + if len(m.Description) > 0 { + dAtA[i] = 0x1a + i++ + i = encodeVarintErrorDetails(dAtA, i, uint64(len(m.Description))) + i += copy(dAtA[i:], m.Description) + } + return i, nil +} + +func (m *BadRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *BadRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.FieldViolations) > 0 { + for _, msg := range m.FieldViolations { + dAtA[i] = 0xa + i++ + i = encodeVarintErrorDetails(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *BadRequest_FieldViolation) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *BadRequest_FieldViolation) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Field) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintErrorDetails(dAtA, i, uint64(len(m.Field))) + i += copy(dAtA[i:], m.Field) + } + if len(m.Description) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintErrorDetails(dAtA, i, uint64(len(m.Description))) + i += copy(dAtA[i:], m.Description) + } + return i, nil +} + +func (m *RequestInfo) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RequestInfo) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.RequestID) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintErrorDetails(dAtA, i, uint64(len(m.RequestID))) + i += copy(dAtA[i:], m.RequestID) + } + if len(m.ServingData) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintErrorDetails(dAtA, i, uint64(len(m.ServingData))) + i += copy(dAtA[i:], m.ServingData) + } + return i, nil +} + +func (m *ResourceInfo) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceInfo) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.ResourceType) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintErrorDetails(dAtA, i, uint64(len(m.ResourceType))) + i += copy(dAtA[i:], m.ResourceType) + } + if len(m.ResourceName) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintErrorDetails(dAtA, i, uint64(len(m.ResourceName))) + i += copy(dAtA[i:], m.ResourceName) + } + if len(m.Owner) > 0 { + dAtA[i] = 0x1a + i++ + i = encodeVarintErrorDetails(dAtA, i, uint64(len(m.Owner))) + i += copy(dAtA[i:], m.Owner) + } + if len(m.Description) > 0 { + dAtA[i] = 0x22 + i++ + i = encodeVarintErrorDetails(dAtA, i, uint64(len(m.Description))) + i += copy(dAtA[i:], m.Description) + } + return i, nil +} + +func (m *Help) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Help) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Links) > 0 { + for _, msg := range m.Links { + dAtA[i] = 0xa + i++ + i = encodeVarintErrorDetails(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *Help_Link) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Help_Link) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Description) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintErrorDetails(dAtA, i, uint64(len(m.Description))) + i += copy(dAtA[i:], m.Description) + } + if len(m.Url) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintErrorDetails(dAtA, i, uint64(len(m.Url))) + i += copy(dAtA[i:], m.Url) + } + return i, nil +} + +func (m *LocalizedMessage) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LocalizedMessage) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Locale) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintErrorDetails(dAtA, i, uint64(len(m.Locale))) + i += copy(dAtA[i:], m.Locale) + } + if len(m.Message) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintErrorDetails(dAtA, i, uint64(len(m.Message))) + i += copy(dAtA[i:], m.Message) + } + return i, nil +} + +func encodeFixed64ErrorDetails(dAtA []byte, offset int, v uint64) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) + dAtA[offset+4] = uint8(v >> 32) + dAtA[offset+5] = uint8(v >> 40) + dAtA[offset+6] = uint8(v >> 48) + dAtA[offset+7] = uint8(v >> 56) + return offset + 8 +} +func encodeFixed32ErrorDetails(dAtA []byte, offset int, v uint32) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) + return offset + 4 +} +func encodeVarintErrorDetails(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *RetryInfo) Size() (n int) { + var l int + _ = l + if m.RetryDelay != nil { + l = m.RetryDelay.Size() + n += 1 + l + sovErrorDetails(uint64(l)) + } + return n +} + +func (m *DebugInfo) Size() (n int) { + var l int + _ = l + if len(m.StackEntries) > 0 { + for _, s := range m.StackEntries { + l = len(s) + n += 1 + l + sovErrorDetails(uint64(l)) + } + } + l = len(m.Detail) + if l > 0 { + n += 1 + l + sovErrorDetails(uint64(l)) + } + return n +} + +func (m *QuotaFailure) Size() (n int) { + var l int + _ = l + if len(m.Violations) > 0 { + for _, e := range m.Violations { + l = e.Size() + n += 1 + l + sovErrorDetails(uint64(l)) + } + } + return n +} + +func (m *QuotaFailure_Violation) Size() (n int) { + var l int + _ = l + l = len(m.Subject) + if l > 0 { + n += 1 + l + sovErrorDetails(uint64(l)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovErrorDetails(uint64(l)) + } + return n +} + +func (m *PreconditionFailure) Size() (n int) { + var l int + _ = l + if len(m.Violations) > 0 { + for _, e := range m.Violations { + l = e.Size() + n += 1 + l + sovErrorDetails(uint64(l)) + } + } + return n +} + +func (m *PreconditionFailure_Violation) Size() (n int) { + var l int + _ = l + l = len(m.Type) + if l > 0 { + n += 1 + l + sovErrorDetails(uint64(l)) + } + l = len(m.Subject) + if l > 0 { + n += 1 + l + sovErrorDetails(uint64(l)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovErrorDetails(uint64(l)) + } + return n +} + +func (m *BadRequest) Size() (n int) { + var l int + _ = l + if len(m.FieldViolations) > 0 { + for _, e := range m.FieldViolations { + l = e.Size() + n += 1 + l + sovErrorDetails(uint64(l)) + } + } + return n +} + +func (m *BadRequest_FieldViolation) Size() (n int) { + var l int + _ = l + l = len(m.Field) + if l > 0 { + n += 1 + l + sovErrorDetails(uint64(l)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovErrorDetails(uint64(l)) + } + return n +} + +func (m *RequestInfo) Size() (n int) { + var l int + _ = l + l = len(m.RequestID) + if l > 0 { + n += 1 + l + sovErrorDetails(uint64(l)) + } + l = len(m.ServingData) + if l > 0 { + n += 1 + l + sovErrorDetails(uint64(l)) + } + return n +} + +func (m *ResourceInfo) Size() (n int) { + var l int + _ = l + l = len(m.ResourceType) + if l > 0 { + n += 1 + l + sovErrorDetails(uint64(l)) + } + l = len(m.ResourceName) + if l > 0 { + n += 1 + l + sovErrorDetails(uint64(l)) + } + l = len(m.Owner) + if l > 0 { + n += 1 + l + sovErrorDetails(uint64(l)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovErrorDetails(uint64(l)) + } + return n +} + +func (m *Help) Size() (n int) { + var l int + _ = l + if len(m.Links) > 0 { + for _, e := range m.Links { + l = e.Size() + n += 1 + l + sovErrorDetails(uint64(l)) + } + } + return n +} + +func (m *Help_Link) Size() (n int) { + var l int + _ = l + l = len(m.Description) + if l > 0 { + n += 1 + l + sovErrorDetails(uint64(l)) + } + l = len(m.Url) + if l > 0 { + n += 1 + l + sovErrorDetails(uint64(l)) + } + return n +} + +func (m *LocalizedMessage) Size() (n int) { + var l int + _ = l + l = len(m.Locale) + if l > 0 { + n += 1 + l + sovErrorDetails(uint64(l)) + } + l = len(m.Message) + if l > 0 { + n += 1 + l + sovErrorDetails(uint64(l)) + } + return n +} + +func sovErrorDetails(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozErrorDetails(x uint64) (n int) { + return sovErrorDetails(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *RetryInfo) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&RetryInfo{`, + `RetryDelay:` + strings.Replace(fmt.Sprintf("%v", this.RetryDelay), "Duration", "google_protobuf.Duration", 1) + `,`, + `}`, + }, "") + return s +} +func (this *DebugInfo) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&DebugInfo{`, + `StackEntries:` + fmt.Sprintf("%v", this.StackEntries) + `,`, + `Detail:` + fmt.Sprintf("%v", this.Detail) + `,`, + `}`, + }, "") + return s +} +func (this *QuotaFailure) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&QuotaFailure{`, + `Violations:` + strings.Replace(fmt.Sprintf("%v", this.Violations), "QuotaFailure_Violation", "QuotaFailure_Violation", 1) + `,`, + `}`, + }, "") + return s +} +func (this *QuotaFailure_Violation) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&QuotaFailure_Violation{`, + `Subject:` + fmt.Sprintf("%v", this.Subject) + `,`, + `Description:` + fmt.Sprintf("%v", this.Description) + `,`, + `}`, + }, "") + return s +} +func (this *PreconditionFailure) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PreconditionFailure{`, + `Violations:` + strings.Replace(fmt.Sprintf("%v", this.Violations), "PreconditionFailure_Violation", "PreconditionFailure_Violation", 1) + `,`, + `}`, + }, "") + return s +} +func (this *PreconditionFailure_Violation) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PreconditionFailure_Violation{`, + `Type:` + fmt.Sprintf("%v", this.Type) + `,`, + `Subject:` + fmt.Sprintf("%v", this.Subject) + `,`, + `Description:` + fmt.Sprintf("%v", this.Description) + `,`, + `}`, + }, "") + return s +} +func (this *BadRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&BadRequest{`, + `FieldViolations:` + strings.Replace(fmt.Sprintf("%v", this.FieldViolations), "BadRequest_FieldViolation", "BadRequest_FieldViolation", 1) + `,`, + `}`, + }, "") + return s +} +func (this *BadRequest_FieldViolation) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&BadRequest_FieldViolation{`, + `Field:` + fmt.Sprintf("%v", this.Field) + `,`, + `Description:` + fmt.Sprintf("%v", this.Description) + `,`, + `}`, + }, "") + return s +} +func (this *RequestInfo) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&RequestInfo{`, + `RequestID:` + fmt.Sprintf("%v", this.RequestID) + `,`, + `ServingData:` + fmt.Sprintf("%v", this.ServingData) + `,`, + `}`, + }, "") + return s +} +func (this *ResourceInfo) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ResourceInfo{`, + `ResourceType:` + fmt.Sprintf("%v", this.ResourceType) + `,`, + `ResourceName:` + fmt.Sprintf("%v", this.ResourceName) + `,`, + `Owner:` + fmt.Sprintf("%v", this.Owner) + `,`, + `Description:` + fmt.Sprintf("%v", this.Description) + `,`, + `}`, + }, "") + return s +} +func (this *Help) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&Help{`, + `Links:` + strings.Replace(fmt.Sprintf("%v", this.Links), "Help_Link", "Help_Link", 1) + `,`, + `}`, + }, "") + return s +} +func (this *Help_Link) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&Help_Link{`, + `Description:` + fmt.Sprintf("%v", this.Description) + `,`, + `Url:` + fmt.Sprintf("%v", this.Url) + `,`, + `}`, + }, "") + return s +} +func (this *LocalizedMessage) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&LocalizedMessage{`, + `Locale:` + fmt.Sprintf("%v", this.Locale) + `,`, + `Message:` + fmt.Sprintf("%v", this.Message) + `,`, + `}`, + }, "") + return s +} +func valueToStringErrorDetails(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *RetryInfo) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RetryInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RetryInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RetryDelay", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthErrorDetails + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.RetryDelay == nil { + m.RetryDelay = &google_protobuf.Duration{} + } + if err := m.RetryDelay.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipErrorDetails(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthErrorDetails + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DebugInfo) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DebugInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DebugInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StackEntries", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthErrorDetails + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.StackEntries = append(m.StackEntries, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Detail", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthErrorDetails + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Detail = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipErrorDetails(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthErrorDetails + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QuotaFailure) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QuotaFailure: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuotaFailure: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Violations", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthErrorDetails + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Violations = append(m.Violations, &QuotaFailure_Violation{}) + if err := m.Violations[len(m.Violations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipErrorDetails(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthErrorDetails + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QuotaFailure_Violation) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Violation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Violation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Subject", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthErrorDetails + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Subject = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthErrorDetails + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipErrorDetails(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthErrorDetails + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PreconditionFailure) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PreconditionFailure: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PreconditionFailure: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Violations", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthErrorDetails + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Violations = append(m.Violations, &PreconditionFailure_Violation{}) + if err := m.Violations[len(m.Violations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipErrorDetails(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthErrorDetails + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PreconditionFailure_Violation) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Violation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Violation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthErrorDetails + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Type = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Subject", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthErrorDetails + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Subject = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthErrorDetails + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipErrorDetails(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthErrorDetails + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *BadRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: BadRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BadRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FieldViolations", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthErrorDetails + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FieldViolations = append(m.FieldViolations, &BadRequest_FieldViolation{}) + if err := m.FieldViolations[len(m.FieldViolations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipErrorDetails(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthErrorDetails + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *BadRequest_FieldViolation) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: FieldViolation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: FieldViolation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Field", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthErrorDetails + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Field = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthErrorDetails + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipErrorDetails(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthErrorDetails + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RequestInfo) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RequestInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RequestInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RequestID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthErrorDetails + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RequestID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ServingData", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthErrorDetails + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ServingData = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipErrorDetails(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthErrorDetails + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResourceInfo) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceType", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthErrorDetails + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ResourceType = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthErrorDetails + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ResourceName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthErrorDetails + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Owner = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthErrorDetails + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipErrorDetails(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthErrorDetails + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Help) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Help: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Help: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Links", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthErrorDetails + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Links = append(m.Links, &Help_Link{}) + if err := m.Links[len(m.Links)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipErrorDetails(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthErrorDetails + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Help_Link) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Link: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Link: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthErrorDetails + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Url", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthErrorDetails + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Url = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipErrorDetails(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthErrorDetails + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LocalizedMessage) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LocalizedMessage: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LocalizedMessage: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Locale", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthErrorDetails + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Locale = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthErrorDetails + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Message = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipErrorDetails(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthErrorDetails + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipErrorDetails(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthErrorDetails + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowErrorDetails + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipErrorDetails(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthErrorDetails = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowErrorDetails = fmt.Errorf("proto: integer overflow") +) + +func init() { + proto.RegisterFile("github.com/containerd/containerd/protobuf/google/rpc/error_details.proto", fileDescriptorErrorDetails) +} + +var fileDescriptorErrorDetails = []byte{ + // 637 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x94, 0x4f, 0x6f, 0xd3, 0x30, + 0x18, 0xc6, 0xe7, 0xb5, 0x1b, 0xca, 0xdb, 0x6e, 0x8c, 0xf0, 0x47, 0xa5, 0x87, 0x50, 0x82, 0x90, + 0x86, 0x40, 0xa9, 0x34, 0x2e, 0x68, 0xdc, 0x4a, 0xb6, 0x75, 0xd2, 0x40, 0x25, 0x42, 0x1c, 0x40, + 0x22, 0x72, 0x93, 0xb7, 0xc5, 0x2c, 0x8d, 0x83, 0xe3, 0x0c, 0x0d, 0x09, 0x89, 0x8f, 0xc0, 0x9d, + 0x1b, 0x27, 0xbe, 0x04, 0xf7, 0x1d, 0x39, 0x72, 0x42, 0xac, 0x9f, 0x04, 0x39, 0x71, 0xd6, 0x6c, + 0x1d, 0x08, 0x71, 0xf3, 0xf3, 0xfa, 0xe7, 0x27, 0xcf, 0x6b, 0x3b, 0x86, 0xfe, 0x98, 0xc9, 0xd7, + 0xd9, 0xd0, 0x09, 0xf8, 0xa4, 0x1b, 0xf0, 0x58, 0x52, 0x16, 0xa3, 0x08, 0xab, 0xc3, 0x44, 0x70, + 0xc9, 0x87, 0xd9, 0xa8, 0x3b, 0xe6, 0x7c, 0x1c, 0x61, 0x57, 0x24, 0x41, 0x17, 0x85, 0xe0, 0xc2, + 0x0f, 0x51, 0x52, 0x16, 0xa5, 0x4e, 0x4e, 0x98, 0x50, 0xcc, 0x3b, 0x22, 0x09, 0xda, 0x96, 0x66, + 0x4f, 0xd6, 0x86, 0x99, 0xa0, 0x92, 0xf1, 0xb8, 0x60, 0xed, 0x1d, 0x30, 0x3c, 0x94, 0xe2, 0x70, + 0x37, 0x1e, 0x71, 0x73, 0x13, 0x1a, 0x42, 0x09, 0x3f, 0xc4, 0x88, 0x1e, 0xb6, 0x48, 0x87, 0xac, + 0x37, 0x36, 0xae, 0x3b, 0xda, 0xae, 0xb4, 0x70, 0x5c, 0x6d, 0xe1, 0x41, 0x4e, 0xbb, 0x0a, 0xb6, + 0xfb, 0x60, 0xb8, 0x38, 0xcc, 0xc6, 0xb9, 0xd1, 0x2d, 0x58, 0x49, 0x25, 0x0d, 0xf6, 0x7d, 0x8c, + 0xa5, 0x60, 0x98, 0xb6, 0x48, 0xa7, 0xb6, 0x6e, 0x78, 0xcd, 0xbc, 0xb8, 0x55, 0xd4, 0xcc, 0x6b, + 0xb0, 0x5c, 0xe4, 0x6e, 0x2d, 0x76, 0xc8, 0xba, 0xe1, 0x69, 0x65, 0x7f, 0x26, 0xd0, 0x7c, 0x9a, + 0x71, 0x49, 0xb7, 0x29, 0x8b, 0x32, 0x81, 0x66, 0x0f, 0xe0, 0x80, 0xf1, 0x28, 0xff, 0x66, 0x61, + 0xd5, 0xd8, 0xb0, 0x9d, 0x59, 0x93, 0x4e, 0x95, 0x76, 0x9e, 0x97, 0xa8, 0x57, 0x59, 0xd5, 0xde, + 0x01, 0xe3, 0x64, 0xc2, 0x6c, 0xc1, 0x85, 0x34, 0x1b, 0xbe, 0xc1, 0x40, 0xe6, 0x3d, 0x1a, 0x5e, + 0x29, 0xcd, 0x0e, 0x34, 0x42, 0x4c, 0x03, 0xc1, 0x12, 0x05, 0xea, 0x60, 0xd5, 0x92, 0xfd, 0x8d, + 0xc0, 0xe5, 0x81, 0xc0, 0x80, 0xc7, 0x21, 0x53, 0x85, 0x32, 0xe4, 0xee, 0x39, 0x21, 0xef, 0x54, + 0x43, 0x9e, 0xb3, 0xe8, 0x0f, 0x59, 0x5f, 0x56, 0xb3, 0x9a, 0x50, 0x97, 0x87, 0x09, 0xea, 0xa0, + 0xf9, 0xb8, 0x9a, 0x7f, 0xf1, 0xaf, 0xf9, 0x6b, 0xf3, 0xf9, 0xbf, 0x12, 0x80, 0x1e, 0x0d, 0x3d, + 0x7c, 0x9b, 0x61, 0x2a, 0xcd, 0x01, 0xac, 0x8d, 0x18, 0x46, 0xa1, 0x3f, 0x17, 0xfe, 0x76, 0x35, + 0xfc, 0x6c, 0x85, 0xb3, 0xad, 0xf0, 0x59, 0xf0, 0x8b, 0xa3, 0x53, 0x3a, 0x6d, 0xf7, 0x61, 0xf5, + 0x34, 0x62, 0x5e, 0x81, 0xa5, 0x1c, 0xd2, 0x3d, 0x14, 0xe2, 0x1f, 0xb6, 0xfa, 0x15, 0x34, 0xf4, + 0x47, 0xf3, 0x4b, 0x75, 0x0f, 0x40, 0x14, 0xd2, 0x67, 0xda, 0xab, 0xb7, 0x32, 0xfd, 0x79, 0xc3, + 0x28, 0x21, 0xd7, 0x33, 0x34, 0xb0, 0x1b, 0x9a, 0x37, 0xa1, 0x99, 0xa2, 0x38, 0x60, 0xf1, 0xd8, + 0x0f, 0xa9, 0xa4, 0xa5, 0xbf, 0xae, 0xb9, 0x54, 0x52, 0xfb, 0x13, 0x81, 0xa6, 0x87, 0x29, 0xcf, + 0x44, 0x80, 0xe5, 0xb5, 0x15, 0x5a, 0xfb, 0x95, 0x4d, 0x6f, 0x96, 0xc5, 0x67, 0x6a, 0xf3, 0xab, + 0x50, 0x4c, 0x27, 0xa8, 0x9d, 0x4f, 0xa0, 0x27, 0x74, 0x82, 0xaa, 0x65, 0xfe, 0x2e, 0x46, 0xa1, + 0x4f, 0xa0, 0x10, 0x67, 0x5b, 0xae, 0xcf, 0xb7, 0xcc, 0xa1, 0xde, 0xc7, 0x28, 0x31, 0xef, 0xc2, + 0x52, 0xc4, 0xe2, 0xfd, 0xf2, 0x2c, 0xae, 0x56, 0xcf, 0x42, 0x01, 0xce, 0x1e, 0x8b, 0xf7, 0xbd, + 0x82, 0x69, 0x6f, 0x42, 0x5d, 0xc9, 0xb3, 0xf6, 0x64, 0xce, 0xde, 0x5c, 0x83, 0x5a, 0x26, 0xca, + 0xff, 0x4d, 0x0d, 0x6d, 0x17, 0xd6, 0xf6, 0x78, 0x40, 0x23, 0xf6, 0x1e, 0xc3, 0xc7, 0x98, 0xa6, + 0x74, 0x8c, 0xea, 0xc7, 0x8c, 0x54, 0xad, 0xec, 0x5f, 0x2b, 0x75, 0xed, 0x26, 0x05, 0x52, 0x5e, + 0x3b, 0x2d, 0x7b, 0x1f, 0x8e, 0x8e, 0xad, 0x85, 0x1f, 0xc7, 0xd6, 0xc2, 0xc7, 0xa9, 0x45, 0x8e, + 0xa6, 0x16, 0xf9, 0x3e, 0xb5, 0xc8, 0xaf, 0xa9, 0x45, 0x60, 0x35, 0xe0, 0x93, 0x4a, 0xf8, 0xde, + 0xa5, 0x2d, 0xf5, 0x60, 0xb9, 0xc5, 0x7b, 0x35, 0x50, 0x2f, 0xca, 0x80, 0xbc, 0x78, 0xf0, 0x3f, + 0x4f, 0xdf, 0x43, 0x91, 0x04, 0x5f, 0x16, 0x6b, 0xde, 0xe0, 0xd1, 0x70, 0x39, 0x9f, 0xbe, 0xff, + 0x3b, 0x00, 0x00, 0xff, 0xff, 0xfa, 0xbf, 0x78, 0x96, 0x43, 0x05, 0x00, 0x00, +} diff --git a/vendor/github.com/containerd/containerd/protobuf/google/rpc/error_details.proto b/vendor/github.com/containerd/containerd/protobuf/google/rpc/error_details.proto new file mode 100644 index 0000000000000..f1b90625c2e33 --- /dev/null +++ b/vendor/github.com/containerd/containerd/protobuf/google/rpc/error_details.proto @@ -0,0 +1,200 @@ +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.rpc; + +import "google/protobuf/duration.proto"; + +option go_package = "github.com/containerd/containerd/protobuf/google/rpc;rpc"; +option java_multiple_files = true; +option java_outer_classname = "ErrorDetailsProto"; +option java_package = "com.google.rpc"; +option objc_class_prefix = "RPC"; + + +// Describes when the clients can retry a failed request. Clients could ignore +// the recommendation here or retry when this information is missing from error +// responses. +// +// It's always recommended that clients should use exponential backoff when +// retrying. +// +// Clients should wait until `retry_delay` amount of time has passed since +// receiving the error response before retrying. If retrying requests also +// fail, clients should use an exponential backoff scheme to gradually increase +// the delay between retries based on `retry_delay`, until either a maximum +// number of retires have been reached or a maximum retry delay cap has been +// reached. +message RetryInfo { + // Clients should wait at least this long between retrying the same request. + google.protobuf.Duration retry_delay = 1; +} + +// Describes additional debugging info. +message DebugInfo { + // The stack trace entries indicating where the error occurred. + repeated string stack_entries = 1; + + // Additional debugging information provided by the server. + string detail = 2; +} + +// Describes how a quota check failed. +// +// For example if a daily limit was exceeded for the calling project, +// a service could respond with a QuotaFailure detail containing the project +// id and the description of the quota limit that was exceeded. If the +// calling project hasn't enabled the service in the developer console, then +// a service could respond with the project id and set `service_disabled` +// to true. +// +// Also see RetryDetail and Help types for other details about handling a +// quota failure. +message QuotaFailure { + // A message type used to describe a single quota violation. For example, a + // daily quota or a custom quota that was exceeded. + message Violation { + // The subject on which the quota check failed. + // For example, "clientip:" or "project:". + string subject = 1; + + // A description of how the quota check failed. Clients can use this + // description to find more about the quota configuration in the service's + // public documentation, or find the relevant quota limit to adjust through + // developer console. + // + // For example: "Service disabled" or "Daily Limit for read operations + // exceeded". + string description = 2; + } + + // Describes all quota violations. + repeated Violation violations = 1; +} + +// Describes what preconditions have failed. +// +// For example, if an RPC failed because it required the Terms of Service to be +// acknowledged, it could list the terms of service violation in the +// PreconditionFailure message. +message PreconditionFailure { + // A message type used to describe a single precondition failure. + message Violation { + // The type of PreconditionFailure. We recommend using a service-specific + // enum type to define the supported precondition violation types. For + // example, "TOS" for "Terms of Service violation". + string type = 1; + + // The subject, relative to the type, that failed. + // For example, "google.com/cloud" relative to the "TOS" type would + // indicate which terms of service is being referenced. + string subject = 2; + + // A description of how the precondition failed. Developers can use this + // description to understand how to fix the failure. + // + // For example: "Terms of service not accepted". + string description = 3; + } + + // Describes all precondition violations. + repeated Violation violations = 1; +} + +// Describes violations in a client request. This error type focuses on the +// syntactic aspects of the request. +message BadRequest { + // A message type used to describe a single bad request field. + message FieldViolation { + // A path leading to a field in the request body. The value will be a + // sequence of dot-separated identifiers that identify a protocol buffer + // field. E.g., "field_violations.field" would identify this field. + string field = 1; + + // A description of why the request element is bad. + string description = 2; + } + + // Describes all violations in a client request. + repeated FieldViolation field_violations = 1; +} + +// Contains metadata about the request that clients can attach when filing a bug +// or providing other forms of feedback. +message RequestInfo { + // An opaque string that should only be interpreted by the service generating + // it. For example, it can be used to identify requests in the service's logs. + string request_id = 1; + + // Any data that was used to serve this request. For example, an encrypted + // stack trace that can be sent back to the service provider for debugging. + string serving_data = 2; +} + +// Describes the resource that is being accessed. +message ResourceInfo { + // A name for the type of resource being accessed, e.g. "sql table", + // "cloud storage bucket", "file", "Google calendar"; or the type URL + // of the resource: e.g. "type.googleapis.com/google.pubsub.v1.Topic". + string resource_type = 1; + + // The name of the resource being accessed. For example, a shared calendar + // name: "example.com_4fghdhgsrgh@group.calendar.google.com", if the current + // error is [google.rpc.Code.PERMISSION_DENIED][google.rpc.Code.PERMISSION_DENIED]. + string resource_name = 2; + + // The owner of the resource (optional). + // For example, "user:" or "project:". + string owner = 3; + + // Describes what error is encountered when accessing this resource. + // For example, updating a cloud project may require the `writer` permission + // on the developer console project. + string description = 4; +} + +// Provides links to documentation or for performing an out of band action. +// +// For example, if a quota check failed with an error indicating the calling +// project hasn't enabled the accessed service, this can contain a URL pointing +// directly to the right place in the developer console to flip the bit. +message Help { + // Describes a URL link. + message Link { + // Describes what the link offers. + string description = 1; + + // The URL of the link. + string url = 2; + } + + // URL(s) pointing to additional information on handling the current error. + repeated Link links = 1; +} + +// Provides a localized error message that is safe to return to the user +// which can be attached to an RPC error. +message LocalizedMessage { + // The locale used following the specification defined at + // http://www.rfc-editor.org/rfc/bcp/bcp47.txt. + // Examples are: "en-US", "fr-CH", "es-MX" + string locale = 1; + + // The localized error message in the above locale. + string message = 2; +} diff --git a/vendor/github.com/containerd/containerd/protobuf/google/rpc/status.pb.go b/vendor/github.com/containerd/containerd/protobuf/google/rpc/status.pb.go new file mode 100644 index 0000000000000..80927bf65525c --- /dev/null +++ b/vendor/github.com/containerd/containerd/protobuf/google/rpc/status.pb.go @@ -0,0 +1,468 @@ +// Code generated by protoc-gen-gogo. +// source: github.com/containerd/containerd/protobuf/google/rpc/status.proto +// DO NOT EDIT! + +package rpc + +import proto "github.com/gogo/protobuf/proto" +import fmt "fmt" +import math "math" +import google_protobuf1 "github.com/gogo/protobuf/types" + +import strings "strings" +import reflect "reflect" + +import io "io" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// The `Status` type defines a logical error model that is suitable for different +// programming environments, including REST APIs and RPC APIs. It is used by +// [gRPC](https://github.com/grpc). The error model is designed to be: +// +// - Simple to use and understand for most users +// - Flexible enough to meet unexpected needs +// +// # Overview +// +// The `Status` message contains three pieces of data: error code, error message, +// and error details. The error code should be an enum value of +// [google.rpc.Code][google.rpc.Code], but it may accept additional error codes if needed. The +// error message should be a developer-facing English message that helps +// developers *understand* and *resolve* the error. If a localized user-facing +// error message is needed, put the localized message in the error details or +// localize it in the client. The optional error details may contain arbitrary +// information about the error. There is a predefined set of error detail types +// in the package `google.rpc` that can be used for common error conditions. +// +// # Language mapping +// +// The `Status` message is the logical representation of the error model, but it +// is not necessarily the actual wire format. When the `Status` message is +// exposed in different client libraries and different wire protocols, it can be +// mapped differently. For example, it will likely be mapped to some exceptions +// in Java, but more likely mapped to some error codes in C. +// +// # Other uses +// +// The error model and the `Status` message can be used in a variety of +// environments, either with or without APIs, to provide a +// consistent developer experience across different environments. +// +// Example uses of this error model include: +// +// - Partial errors. If a service needs to return partial errors to the client, +// it may embed the `Status` in the normal response to indicate the partial +// errors. +// +// - Workflow errors. A typical workflow has multiple steps. Each step may +// have a `Status` message for error reporting. +// +// - Batch operations. If a client uses batch request and batch response, the +// `Status` message should be used directly inside batch response, one for +// each error sub-response. +// +// - Asynchronous operations. If an API call embeds asynchronous operation +// results in its response, the status of those operations should be +// represented directly using the `Status` message. +// +// - Logging. If some API errors are stored in logs, the message `Status` could +// be used directly after any stripping needed for security/privacy reasons. +type Status struct { + // The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. + Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + // A developer-facing error message, which should be in English. Any + // user-facing error message should be localized and sent in the + // [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client. + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + // A list of messages that carry the error details. There is a common set of + // message types for APIs to use. + Details []*google_protobuf1.Any `protobuf:"bytes,3,rep,name=details" json:"details,omitempty"` +} + +func (m *Status) Reset() { *m = Status{} } +func (*Status) ProtoMessage() {} +func (*Status) Descriptor() ([]byte, []int) { return fileDescriptorStatus, []int{0} } + +func init() { + proto.RegisterType((*Status)(nil), "google.rpc.Status") +} +func (m *Status) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Status) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Code != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintStatus(dAtA, i, uint64(m.Code)) + } + if len(m.Message) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintStatus(dAtA, i, uint64(len(m.Message))) + i += copy(dAtA[i:], m.Message) + } + if len(m.Details) > 0 { + for _, msg := range m.Details { + dAtA[i] = 0x1a + i++ + i = encodeVarintStatus(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func encodeFixed64Status(dAtA []byte, offset int, v uint64) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) + dAtA[offset+4] = uint8(v >> 32) + dAtA[offset+5] = uint8(v >> 40) + dAtA[offset+6] = uint8(v >> 48) + dAtA[offset+7] = uint8(v >> 56) + return offset + 8 +} +func encodeFixed32Status(dAtA []byte, offset int, v uint32) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) + return offset + 4 +} +func encodeVarintStatus(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *Status) Size() (n int) { + var l int + _ = l + if m.Code != 0 { + n += 1 + sovStatus(uint64(m.Code)) + } + l = len(m.Message) + if l > 0 { + n += 1 + l + sovStatus(uint64(l)) + } + if len(m.Details) > 0 { + for _, e := range m.Details { + l = e.Size() + n += 1 + l + sovStatus(uint64(l)) + } + } + return n +} + +func sovStatus(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozStatus(x uint64) (n int) { + return sovStatus(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *Status) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&Status{`, + `Code:` + fmt.Sprintf("%v", this.Code) + `,`, + `Message:` + fmt.Sprintf("%v", this.Message) + `,`, + `Details:` + strings.Replace(fmt.Sprintf("%v", this.Details), "Any", "google_protobuf1.Any", 1) + `,`, + `}`, + }, "") + return s +} +func valueToStringStatus(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *Status) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStatus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Status: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Status: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType) + } + m.Code = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStatus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Code |= (int32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStatus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthStatus + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Message = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Details", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStatus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthStatus + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Details = append(m.Details, &google_protobuf1.Any{}) + if err := m.Details[len(m.Details)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipStatus(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthStatus + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipStatus(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowStatus + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowStatus + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowStatus + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthStatus + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowStatus + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipStatus(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthStatus = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowStatus = fmt.Errorf("proto: integer overflow") +) + +func init() { + proto.RegisterFile("github.com/containerd/containerd/protobuf/google/rpc/status.proto", fileDescriptorStatus) +} + +var fileDescriptorStatus = []byte{ + // 236 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x72, 0x4c, 0xcf, 0x2c, 0xc9, + 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0xcf, 0x2b, 0x49, 0xcc, 0xcc, 0x4b, 0x2d, + 0x4a, 0x41, 0x66, 0x16, 0x14, 0xe5, 0x97, 0xe4, 0x27, 0x95, 0xa6, 0xe9, 0xa7, 0xe7, 0xe7, 0xa7, + 0xe7, 0xa4, 0xea, 0x17, 0x15, 0x24, 0xeb, 0x17, 0x97, 0x24, 0x96, 0x94, 0x16, 0xeb, 0x81, 0xa5, + 0x84, 0xb8, 0x20, 0x12, 0x7a, 0x45, 0x05, 0xc9, 0x52, 0x92, 0x50, 0x45, 0x70, 0x4d, 0x89, 0x79, + 0x95, 0x10, 0x65, 0x4a, 0x69, 0x5c, 0x6c, 0xc1, 0x60, 0x6d, 0x42, 0x42, 0x5c, 0x2c, 0xc9, 0xf9, + 0x29, 0xa9, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0xac, 0x41, 0x60, 0xb6, 0x90, 0x04, 0x17, 0x7b, 0x6e, + 0x6a, 0x71, 0x71, 0x62, 0x7a, 0xaa, 0x04, 0x93, 0x02, 0xa3, 0x06, 0x67, 0x10, 0x8c, 0x2b, 0xa4, + 0xc7, 0xc5, 0x9e, 0x92, 0x5a, 0x92, 0x98, 0x99, 0x53, 0x2c, 0xc1, 0xac, 0xc0, 0xac, 0xc1, 0x6d, + 0x24, 0xa2, 0x07, 0xb5, 0x10, 0x66, 0x89, 0x9e, 0x63, 0x5e, 0x65, 0x10, 0x4c, 0x91, 0x53, 0xf9, + 0x89, 0x87, 0x72, 0x0c, 0x37, 0x1e, 0xca, 0x31, 0x34, 0x3c, 0x92, 0x63, 0x3c, 0xf1, 0x48, 0x8e, + 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0xb9, 0xf8, 0x92, 0xf3, 0x73, 0xf5, 0x10, + 0x8e, 0x75, 0xe2, 0x86, 0xb8, 0x27, 0x00, 0x64, 0x4c, 0x00, 0x63, 0x94, 0x05, 0x39, 0x41, 0x61, + 0x5d, 0x54, 0x90, 0xbc, 0x88, 0x89, 0x39, 0x28, 0xc0, 0x39, 0x89, 0x0d, 0x2c, 0x6d, 0x0c, 0x08, + 0x00, 0x00, 0xff, 0xff, 0x7d, 0xb3, 0x06, 0x51, 0x53, 0x01, 0x00, 0x00, +} diff --git a/vendor/github.com/containerd/containerd/protobuf/google/rpc/status.proto b/vendor/github.com/containerd/containerd/protobuf/google/rpc/status.proto new file mode 100644 index 0000000000000..55f4ea03b4958 --- /dev/null +++ b/vendor/github.com/containerd/containerd/protobuf/google/rpc/status.proto @@ -0,0 +1,92 @@ +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.rpc; + +import "google/protobuf/any.proto"; + +option go_package = "github.com/containerd/containerd/protobuf/google/rpc;rpc"; +option java_multiple_files = true; +option java_outer_classname = "StatusProto"; +option java_package = "com.google.rpc"; +option objc_class_prefix = "RPC"; + + +// The `Status` type defines a logical error model that is suitable for different +// programming environments, including REST APIs and RPC APIs. It is used by +// [gRPC](https://github.com/grpc). The error model is designed to be: +// +// - Simple to use and understand for most users +// - Flexible enough to meet unexpected needs +// +// # Overview +// +// The `Status` message contains three pieces of data: error code, error message, +// and error details. The error code should be an enum value of +// [google.rpc.Code][google.rpc.Code], but it may accept additional error codes if needed. The +// error message should be a developer-facing English message that helps +// developers *understand* and *resolve* the error. If a localized user-facing +// error message is needed, put the localized message in the error details or +// localize it in the client. The optional error details may contain arbitrary +// information about the error. There is a predefined set of error detail types +// in the package `google.rpc` that can be used for common error conditions. +// +// # Language mapping +// +// The `Status` message is the logical representation of the error model, but it +// is not necessarily the actual wire format. When the `Status` message is +// exposed in different client libraries and different wire protocols, it can be +// mapped differently. For example, it will likely be mapped to some exceptions +// in Java, but more likely mapped to some error codes in C. +// +// # Other uses +// +// The error model and the `Status` message can be used in a variety of +// environments, either with or without APIs, to provide a +// consistent developer experience across different environments. +// +// Example uses of this error model include: +// +// - Partial errors. If a service needs to return partial errors to the client, +// it may embed the `Status` in the normal response to indicate the partial +// errors. +// +// - Workflow errors. A typical workflow has multiple steps. Each step may +// have a `Status` message for error reporting. +// +// - Batch operations. If a client uses batch request and batch response, the +// `Status` message should be used directly inside batch response, one for +// each error sub-response. +// +// - Asynchronous operations. If an API call embeds asynchronous operation +// results in its response, the status of those operations should be +// represented directly using the `Status` message. +// +// - Logging. If some API errors are stored in logs, the message `Status` could +// be used directly after any stripping needed for security/privacy reasons. +message Status { + // The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. + int32 code = 1; + + // A developer-facing error message, which should be in English. Any + // user-facing error message should be localized and sent in the + // [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client. + string message = 2; + + // A list of messages that carry the error details. There is a common set of + // message types for APIs to use. + repeated google.protobuf.Any details = 3; +} diff --git a/vendor/github.com/containerd/containerd/protobuf/plugin/helpers.go b/vendor/github.com/containerd/containerd/protobuf/plugin/helpers.go index 9026aeee3fcf2..7a2af56fbfb81 100644 --- a/vendor/github.com/containerd/containerd/protobuf/plugin/helpers.go +++ b/vendor/github.com/containerd/containerd/protobuf/plugin/helpers.go @@ -5,6 +5,7 @@ import ( "github.com/gogo/protobuf/protoc-gen-gogo/descriptor" ) +// FieldpathEnabled returns true if E_Fieldpath is enabled func FieldpathEnabled(file *descriptor.FileDescriptorProto, message *descriptor.DescriptorProto) bool { return proto.GetBoolExtension(message.Options, E_Fieldpath, proto.GetBoolExtension(file.Options, E_FieldpathAll, false)) } diff --git a/vendor/github.com/containerd/containerd/reference/reference.go b/vendor/github.com/containerd/containerd/reference/reference.go index d31dff5231225..55c43b881cd61 100644 --- a/vendor/github.com/containerd/containerd/reference/reference.go +++ b/vendor/github.com/containerd/containerd/reference/reference.go @@ -12,8 +12,11 @@ import ( ) var ( - ErrInvalid = errors.New("invalid reference") - ErrObjectRequired = errors.New("object required") + // ErrInvalid is returned when there is an invalid reference + ErrInvalid = errors.New("invalid reference") + // ErrObjectRequired is returned when the object is required + ErrObjectRequired = errors.New("object required") + // ErrHostnameRequired is returned when the hostname is required ErrHostnameRequired = errors.New("hostname required") ) @@ -138,7 +141,6 @@ func SplitObject(obj string) (tag string, dgst digest.Digest) { parts := strings.SplitAfterN(obj, "@", 2) if len(parts) < 2 { return parts[0], "" - } else { - return parts[0], digest.Digest(parts[1]) } + return parts[0], digest.Digest(parts[1]) } diff --git a/vendor/github.com/containerd/containerd/remotes/docker/fetcher.go b/vendor/github.com/containerd/containerd/remotes/docker/fetcher.go index e4a70ac85edab..46677e491445e 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/fetcher.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/fetcher.go @@ -7,6 +7,7 @@ import ( "path" "strings" + "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" "github.com/containerd/containerd/log" ocispec "github.com/opencontainers/image-spec/specs-go/v1" @@ -26,7 +27,7 @@ func (r dockerFetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.R }, )) - paths, err := getV2URLPaths(desc) + urls, err := r.getV2URLPaths(ctx, desc) if err != nil { return nil, err } @@ -36,9 +37,7 @@ func (r dockerFetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.R return nil, err } - for _, path := range paths { - u := r.url(path) - + for _, u := range urls { req, err := http.NewRequest(http.MethodGet, u, nil) if err != nil { return nil, err @@ -51,34 +50,44 @@ func (r dockerFetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.R } if resp.StatusCode > 299 { + resp.Body.Close() if resp.StatusCode == http.StatusNotFound { continue // try one of the other urls. } - resp.Body.Close() return nil, errors.Errorf("unexpected status code %v: %v", u, resp.Status) } return resp.Body, nil } - return nil, errors.New("not found") + return nil, errors.Wrapf(errdefs.ErrNotFound, + "could not fetch content descriptor %v (%v) from remote", + desc.Digest, desc.MediaType) } // getV2URLPaths generates the candidate urls paths for the object based on the // set of hints and the provided object id. URLs are returned in the order of // most to least likely succeed. -func getV2URLPaths(desc ocispec.Descriptor) ([]string, error) { +func (r *dockerFetcher) getV2URLPaths(ctx context.Context, desc ocispec.Descriptor) ([]string, error) { var urls []string + if len(desc.URLs) > 0 { + // handle fetch via external urls. + for _, u := range desc.URLs { + log.G(ctx).WithField("url", u).Debug("adding alternative url") + urls = append(urls, u) + } + } + switch desc.MediaType { case images.MediaTypeDockerSchema2Manifest, images.MediaTypeDockerSchema2ManifestList, images.MediaTypeDockerSchema1Manifest, ocispec.MediaTypeImageManifest, ocispec.MediaTypeImageIndex: - urls = append(urls, path.Join("manifests", desc.Digest.String())) + urls = append(urls, r.url(path.Join("manifests", desc.Digest.String()))) } // always fallback to attempting to get the object out of the blobs store. - urls = append(urls, path.Join("blobs", desc.Digest.String())) + urls = append(urls, r.url(path.Join("blobs", desc.Digest.String()))) return urls, nil } diff --git a/vendor/github.com/containerd/containerd/remotes/docker/resolver.go b/vendor/github.com/containerd/containerd/remotes/docker/resolver.go index e331f3ba56b42..7a1150495667d 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/resolver.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/resolver.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "io" "io/ioutil" "net/http" "net/textproto" @@ -498,7 +499,7 @@ func (r *dockerBase) fetchTokenWithOAuth(ctx context.Context, to tokenOptions) ( if (resp.StatusCode == 405 && r.username != "") || resp.StatusCode == 404 { return r.getToken(ctx, to) } else if resp.StatusCode < 200 || resp.StatusCode >= 400 { - b, _ := ioutil.ReadAll(resp.Body) + b, _ := ioutil.ReadAll(io.LimitReader(resp.Body, 64000)) // 64KB log.G(ctx).WithFields(logrus.Fields{ "status": resp.Status, "body": string(b), diff --git a/vendor/github.com/containerd/containerd/remotes/docker/schema1/converter.go b/vendor/github.com/containerd/containerd/remotes/docker/schema1/converter.go index 8e451a21443e2..6e0dcb4e2af12 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/schema1/converter.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/schema1/converter.go @@ -9,6 +9,7 @@ import ( "fmt" "io" "io/ioutil" + "math/rand" "strings" "sync" "time" @@ -26,6 +27,8 @@ import ( "github.com/pkg/errors" ) +const manifestSizeLimit = 8e6 // 8MB + var ( mediaTypeManifest = "application/vnd.docker.distribution.manifest.v1+json" ) @@ -47,6 +50,7 @@ type Converter struct { layerBlobs map[digest.Digest]ocispec.Descriptor } +// NewConverter returns a new converter func NewConverter(contentStore content.Store, fetcher remotes.Fetcher) *Converter { return &Converter{ contentStore: contentStore, @@ -56,6 +60,7 @@ func NewConverter(contentStore content.Store, fetcher remotes.Fetcher) *Converte } } +// Handle fetching descriptors for a docker media type func (c *Converter) Handle(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { switch desc.MediaType { case images.MediaTypeDockerSchema1Manifest: @@ -101,6 +106,7 @@ func (c *Converter) Handle(ctx context.Context, desc ocispec.Descriptor) ([]ocis } } +// Convert a docker manifest to an OCI descriptor func (c *Converter) Convert(ctx context.Context) (ocispec.Descriptor, error) { history, diffIDs, err := c.schema1ManifestHistory() if err != nil { @@ -129,11 +135,6 @@ func (c *Converter) Convert(ctx context.Context) (ocispec.Descriptor, error) { Size: int64(len(b)), } - ref := remotes.MakeRefKey(ctx, config) - if err := content.WriteBlob(ctx, c.contentStore, ref, bytes.NewReader(b), config.Size, config.Digest); err != nil { - return ocispec.Descriptor{}, errors.Wrap(err, "failed to write config") - } - layers := make([]ocispec.Descriptor, len(diffIDs)) for i, diffID := range diffIDs { layers[i] = c.layerBlobs[diffID] @@ -147,22 +148,40 @@ func (c *Converter) Convert(ctx context.Context) (ocispec.Descriptor, error) { Layers: layers, } - b, err = json.Marshal(manifest) + mb, err := json.Marshal(manifest) if err != nil { return ocispec.Descriptor{}, errors.Wrap(err, "failed to marshal image") } desc := ocispec.Descriptor{ MediaType: ocispec.MediaTypeImageManifest, - Digest: digest.Canonical.FromBytes(b), - Size: int64(len(b)), + Digest: digest.Canonical.FromBytes(mb), + Size: int64(len(mb)), + } + + labels := map[string]string{} + labels["containerd.io/gc.root"] = time.Now().UTC().Format(time.RFC3339) + labels["containerd.io/gc.ref.content.0"] = manifest.Config.Digest.String() + for i, ch := range manifest.Layers { + labels[fmt.Sprintf("containerd.io/gc.ref.content.%d", i+1)] = ch.Digest.String() } - ref = remotes.MakeRefKey(ctx, desc) - if err := content.WriteBlob(ctx, c.contentStore, ref, bytes.NewReader(b), desc.Size, desc.Digest); err != nil { + ref := remotes.MakeRefKey(ctx, desc) + if err := content.WriteBlob(ctx, c.contentStore, ref, bytes.NewReader(mb), desc.Size, desc.Digest, content.WithLabels(labels)); err != nil { return ocispec.Descriptor{}, errors.Wrap(err, "failed to write config") } + ref = remotes.MakeRefKey(ctx, config) + if err := content.WriteBlob(ctx, c.contentStore, ref, bytes.NewReader(b), config.Size, config.Digest); err != nil { + return ocispec.Descriptor{}, errors.Wrap(err, "failed to write config") + } + + for _, ch := range manifest.Layers { + if _, err := c.contentStore.Update(ctx, content.Info{Digest: ch.Digest}, "labels.containerd.io/gc.root"); err != nil { + return ocispec.Descriptor{}, errors.Wrap(err, "failed to remove blob root tag") + } + } + return desc, nil } @@ -174,7 +193,7 @@ func (c *Converter) fetchManifest(ctx context.Context, desc ocispec.Descriptor) return err } - b, err := ioutil.ReadAll(rc) + b, err := ioutil.ReadAll(io.LimitReader(rc, manifestSizeLimit)) // limit to 8MB rc.Close() if err != nil { return err @@ -197,13 +216,26 @@ func (c *Converter) fetchManifest(ctx context.Context, desc ocispec.Descriptor) func (c *Converter) fetchBlob(ctx context.Context, desc ocispec.Descriptor) error { log.G(ctx).Debug("fetch blob") - ref := remotes.MakeRefKey(ctx, desc) - - calc := newBlobStateCalculator() + var ( + ref = remotes.MakeRefKey(ctx, desc) + calc = newBlobStateCalculator() + retry = 16 + ) +tryit: cw, err := c.contentStore.Writer(ctx, ref, desc.Size, desc.Digest) if err != nil { - if !errdefs.IsAlreadyExists(err) { + if errdefs.IsUnavailable(err) { + select { + case <-time.After(time.Millisecond * time.Duration(rand.Intn(retry))): + if retry < 2048 { + retry = retry << 1 + } + goto tryit + case <-ctx.Done(): + return err + } + } else if !errdefs.IsAlreadyExists(err) { return err } @@ -252,14 +284,15 @@ func (c *Converter) fetchBlob(ctx context.Context, desc ocispec.Descriptor) erro eg.Go(func() error { defer pw.Close() - return content.Copy(ctx, cw, io.TeeReader(rc, pw), desc.Size, desc.Digest) + opt := content.WithLabels(map[string]string{ + "containerd.io/gc.root": time.Now().UTC().Format(time.RFC3339), + }) + return content.Copy(ctx, cw, io.TeeReader(rc, pw), desc.Size, desc.Digest, opt) }) if err := eg.Wait(); err != nil { return err } - - // TODO: Label blob } if desc.Size == 0 { diff --git a/vendor/github.com/containerd/containerd/remotes/docker/status.go b/vendor/github.com/containerd/containerd/remotes/docker/status.go index 442f9ae0d48a3..4b8dbbc5c4462 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/status.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/status.go @@ -8,6 +8,7 @@ import ( "github.com/pkg/errors" ) +// Status of a content operation type Status struct { content.Status @@ -15,6 +16,7 @@ type Status struct { UploadUUID string } +// StatusTracker to track status of operations type StatusTracker interface { GetStatus(string) (Status, error) SetStatus(string, Status) @@ -25,6 +27,7 @@ type memoryStatusTracker struct { m sync.Mutex } +// NewInMemoryTracker returns a StatusTracker that tracks content status in-memory func NewInMemoryTracker() StatusTracker { return &memoryStatusTracker{ statuses: map[string]Status{}, diff --git a/vendor/github.com/containerd/containerd/remotes/handlers.go b/vendor/github.com/containerd/containerd/remotes/handlers.go index 3c756ecd3ce0e..7b1dad99ed101 100644 --- a/vendor/github.com/containerd/containerd/remotes/handlers.go +++ b/vendor/github.com/containerd/containerd/remotes/handlers.go @@ -2,8 +2,10 @@ package remotes import ( "context" + "encoding/json" "fmt" "io" + "math/rand" "time" "github.com/containerd/containerd/content" @@ -11,10 +13,11 @@ import ( "github.com/containerd/containerd/images" "github.com/containerd/containerd/log" ocispec "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/pkg/errors" "github.com/sirupsen/logrus" ) -// MakeRef returns a unique reference for the descriptor. This reference can be +// MakeRefKey returns a unique reference for the descriptor. This reference can be // used to lookup ongoing processes related to the descriptor. This function // may look to the context to namespace the reference appropriately. func MakeRefKey(ctx context.Context, desc ocispec.Descriptor) string { @@ -27,6 +30,7 @@ func MakeRefKey(ctx context.Context, desc ocispec.Descriptor) string { case images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex: return "index-" + desc.Digest.String() case images.MediaTypeDockerSchema2Layer, images.MediaTypeDockerSchema2LayerGzip, + images.MediaTypeDockerSchema2LayerForeign, images.MediaTypeDockerSchema2LayerForeignGzip, ocispec.MediaTypeImageLayer, ocispec.MediaTypeImageLayerGzip, ocispec.MediaTypeImageLayerNonDistributable, ocispec.MediaTypeImageLayerNonDistributableGzip: return "layer-" + desc.Digest.String() @@ -41,7 +45,7 @@ func MakeRefKey(ctx context.Context, desc ocispec.Descriptor) string { // FetchHandler returns a handler that will fetch all content into the ingester // discovered in a call to Dispatch. Use with ChildrenHandler to do a full // recursive fetch. -func FetchHandler(ingester content.Ingester, fetcher Fetcher) images.HandlerFunc { +func FetchHandler(ingester content.Ingester, fetcher Fetcher, root ocispec.Descriptor) images.HandlerFunc { return func(ctx context.Context, desc ocispec.Descriptor) (subdescs []ocispec.Descriptor, err error) { ctx = log.WithLogger(ctx, log.G(ctx).WithFields(logrus.Fields{ "digest": desc.Digest, @@ -53,13 +57,13 @@ func FetchHandler(ingester content.Ingester, fetcher Fetcher) images.HandlerFunc case images.MediaTypeDockerSchema1Manifest: return nil, fmt.Errorf("%v not supported", desc.MediaType) default: - err := fetch(ctx, ingester, fetcher, desc) + err := fetch(ctx, ingester, fetcher, desc, desc.Digest == root.Digest) return nil, err } } } -func fetch(ctx context.Context, ingester content.Ingester, fetcher Fetcher, desc ocispec.Descriptor) error { +func fetch(ctx context.Context, ingester content.Ingester, fetcher Fetcher, desc ocispec.Descriptor, root bool) error { log.G(ctx).Debug("fetch") var ( @@ -81,7 +85,7 @@ func fetch(ctx context.Context, ingester content.Ingester, fetcher Fetcher, desc // of writer and abort if not updated recently. select { - case <-time.After(time.Millisecond * time.Duration(retry)): + case <-time.After(time.Millisecond * time.Duration(rand.Intn(retry))): if retry < 2048 { retry = retry << 1 } @@ -101,7 +105,79 @@ func fetch(ctx context.Context, ingester content.Ingester, fetcher Fetcher, desc } defer rc.Close() - return content.Copy(ctx, cw, rc, desc.Size, desc.Digest) + r, opts := commitOpts(desc, rc, root) + return content.Copy(ctx, cw, r, desc.Size, desc.Digest, opts...) +} + +// commitOpts gets the appropriate content options to alter +// the content info on commit based on media type. +func commitOpts(desc ocispec.Descriptor, r io.Reader, root bool) (io.Reader, []content.Opt) { + var childrenF func(r io.Reader) ([]ocispec.Descriptor, error) + + switch desc.MediaType { + case images.MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest: + childrenF = func(r io.Reader) ([]ocispec.Descriptor, error) { + var ( + manifest ocispec.Manifest + decoder = json.NewDecoder(r) + ) + if err := decoder.Decode(&manifest); err != nil { + return nil, err + } + + return append([]ocispec.Descriptor{manifest.Config}, manifest.Layers...), nil + } + case images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex: + childrenF = func(r io.Reader) ([]ocispec.Descriptor, error) { + var ( + index ocispec.Index + decoder = json.NewDecoder(r) + ) + if err := decoder.Decode(&index); err != nil { + return nil, err + } + + return index.Manifests, nil + } + default: + return r, nil + } + + pr, pw := io.Pipe() + + var children []ocispec.Descriptor + errC := make(chan error) + + go func() { + defer close(errC) + ch, err := childrenF(pr) + if err != nil { + errC <- err + } + children = ch + }() + + opt := func(info *content.Info) error { + err := <-errC + if err != nil { + return errors.Wrap(err, "unable to get commit labels") + } + + if len(children) > 0 || root { + if info.Labels == nil { + info.Labels = map[string]string{} + } + if root { + info.Labels["containerd.io/gc.root"] = time.Now().UTC().Format(time.RFC3339) + } + for i, ch := range children { + info.Labels[fmt.Sprintf("containerd.io/gc.ref.content.%d", i)] = ch.Digest.String() + } + } + return nil + } + + return io.TeeReader(r, pw), []content.Opt{opt} } // PushHandler returns a handler that will push all content from the provider diff --git a/vendor/github.com/containerd/containerd/remotes/resolver.go b/vendor/github.com/containerd/containerd/remotes/resolver.go index d5fa60fc6b84e..caf4c97ce156d 100644 --- a/vendor/github.com/containerd/containerd/remotes/resolver.go +++ b/vendor/github.com/containerd/containerd/remotes/resolver.go @@ -32,11 +32,13 @@ type Resolver interface { Pusher(ctx context.Context, ref string) (Pusher, error) } +// Fetcher fetches content type Fetcher interface { // Fetch the resource identified by the descriptor. Fetch(ctx context.Context, desc ocispec.Descriptor) (io.ReadCloser, error) } +// Pusher pushes content type Pusher interface { // Push returns a content writer for the given resource identified // by the descriptor. @@ -47,6 +49,7 @@ type Pusher interface { // function. type FetcherFunc func(ctx context.Context, desc ocispec.Descriptor) (io.ReadCloser, error) +// Fetch content func (fn FetcherFunc) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.ReadCloser, error) { return fn(ctx, desc) } @@ -55,6 +58,7 @@ func (fn FetcherFunc) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.Re // function. type PusherFunc func(ctx context.Context, desc ocispec.Descriptor, r io.Reader) error -func (fn PusherFunc) Pusher(ctx context.Context, desc ocispec.Descriptor, r io.Reader) error { +// Push content +func (fn PusherFunc) Push(ctx context.Context, desc ocispec.Descriptor, r io.Reader) error { return fn(ctx, desc, r) } diff --git a/vendor/github.com/containerd/containerd/rootfs/apply.go b/vendor/github.com/containerd/containerd/rootfs/apply.go index b398228d4b021..a198c99f94b61 100644 --- a/vendor/github.com/containerd/containerd/rootfs/apply.go +++ b/vendor/github.com/containerd/containerd/rootfs/apply.go @@ -6,9 +6,9 @@ import ( "fmt" "time" + "github.com/containerd/containerd/diff" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/log" - "github.com/containerd/containerd/mount" "github.com/containerd/containerd/snapshot" "github.com/opencontainers/go-digest" "github.com/opencontainers/image-spec/identity" @@ -17,11 +17,6 @@ import ( "golang.org/x/net/context" ) -// Applier is used to apply a descriptor of a layer diff on top of mounts. -type Applier interface { - Apply(context.Context, ocispec.Descriptor, []mount.Mount) (ocispec.Descriptor, error) -} - // Layer represents the descriptors for a layer diff. These descriptions // include the descriptor for the uncompressed tar diff as well as a blob // used to transport that tar. The blob descriptor may or may not describe @@ -35,7 +30,7 @@ type Layer struct { // The returned result is a chain id digest representing all the applied layers. // Layers are applied in order they are given, making the first layer the // bottom-most layer in the layer chain. -func ApplyLayers(ctx context.Context, layers []Layer, sn snapshot.Snapshotter, a Applier) (digest.Digest, error) { +func ApplyLayers(ctx context.Context, layers []Layer, sn snapshot.Snapshotter, a diff.Differ) (digest.Digest, error) { var chain []digest.Digest for _, layer := range layers { if _, err := ApplyLayer(ctx, layer, chain, sn, a); err != nil { @@ -51,7 +46,7 @@ func ApplyLayers(ctx context.Context, layers []Layer, sn snapshot.Snapshotter, a // ApplyLayer applies a single layer on top of the given provided layer chain, // using the provided snapshotter and applier. If the layer was unpacked true // is returned, if the layer already exists false is returned. -func ApplyLayer(ctx context.Context, layer Layer, chain []digest.Digest, sn snapshot.Snapshotter, a Applier) (bool, error) { +func ApplyLayer(ctx context.Context, layer Layer, chain []digest.Digest, sn snapshot.Snapshotter, a diff.Differ, opts ...snapshot.Opt) (bool, error) { var ( parent = identity.ChainID(chain) chainID = identity.ChainID(append(chain, layer.Diff.Digest)) @@ -68,8 +63,8 @@ func ApplyLayer(ctx context.Context, layer Layer, chain []digest.Digest, sn snap key := fmt.Sprintf("extract-%s %s", uniquePart(), chainID) - // Prepare snapshot with from parent - mounts, err := sn.Prepare(ctx, key, parent.String()) + // Prepare snapshot with from parent, label as root + mounts, err := sn.Prepare(ctx, key, parent.String(), opts...) if err != nil { //TODO: If is snapshot exists error, retry return false, errors.Wrap(err, "failed to prepare extraction layer") @@ -92,7 +87,7 @@ func ApplyLayer(ctx context.Context, layer Layer, chain []digest.Digest, sn snap return false, err } - if err = sn.Commit(ctx, chainID.String(), key); err != nil { + if err = sn.Commit(ctx, chainID.String(), key, opts...); err != nil { if !errdefs.IsAlreadyExists(err) { return false, errors.Wrapf(err, "failed to commit snapshot %s", parent) } diff --git a/vendor/github.com/containerd/containerd/rootfs/diff.go b/vendor/github.com/containerd/containerd/rootfs/diff.go index 1a16fb9d9c8bb..035eb3026111d 100644 --- a/vendor/github.com/containerd/containerd/rootfs/diff.go +++ b/vendor/github.com/containerd/containerd/rootfs/diff.go @@ -3,25 +3,18 @@ package rootfs import ( "fmt" + "github.com/containerd/containerd/diff" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/snapshot" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "golang.org/x/net/context" ) -// MountDiffer computes the difference between two mounts and returns a -// descriptor for the computed diff. The provided ref can be used to track -// the content creation of the diff and media type is used to determine the -// format of the created content. -type MountDiffer interface { - DiffMounts(ctx context.Context, lower, upper []mount.Mount, media, ref string) (ocispec.Descriptor, error) -} - // Diff creates a layer diff for the given snapshot identifier from the parent // of the snapshot. A content ref is provided to track the progress of the // content creation and the provided snapshotter and mount differ are used // for calculating the diff. The descriptor for the layer diff is returned. -func Diff(ctx context.Context, snapshotID, contentRef string, sn snapshot.Snapshotter, md MountDiffer) (ocispec.Descriptor, error) { +func Diff(ctx context.Context, snapshotID string, sn snapshot.Snapshotter, d diff.Differ, opts ...diff.Opt) (ocispec.Descriptor, error) { info, err := sn.Stat(ctx, snapshotID) if err != nil { return ocispec.Descriptor{}, err @@ -49,5 +42,5 @@ func Diff(ctx context.Context, snapshotID, contentRef string, sn snapshot.Snapsh defer sn.Remove(ctx, lowerKey) } - return md.DiffMounts(ctx, lower, upper, ocispec.MediaTypeImageLayerGzip, contentRef) + return d.DiffMounts(ctx, lower, upper, opts...) } diff --git a/vendor/github.com/containerd/containerd/rootfs/init.go b/vendor/github.com/containerd/containerd/rootfs/init.go index ae3870efed87c..271e6cee51875 100644 --- a/vendor/github.com/containerd/containerd/rootfs/init.go +++ b/vendor/github.com/containerd/containerd/rootfs/init.go @@ -19,11 +19,13 @@ var ( type initializerFunc func(string) error +// Mounter handles mount and unmount type Mounter interface { Mount(target string, mounts ...mount.Mount) error Unmount(target string) error } +// InitRootFS initializes the snapshot for use as a rootfs func InitRootFS(ctx context.Context, name string, parent digest.Digest, readonly bool, snapshotter snapshot.Snapshotter, mounter Mounter) ([]mount.Mount, error) { _, err := snapshotter.Stat(ctx, name) if err == nil { diff --git a/vendor/github.com/containerd/containerd/runtime/events.go b/vendor/github.com/containerd/containerd/runtime/events.go deleted file mode 100644 index fd69c03126b29..0000000000000 --- a/vendor/github.com/containerd/containerd/runtime/events.go +++ /dev/null @@ -1,15 +0,0 @@ -package runtime - -const ( - TaskCreateEventTopic = "/tasks/create" - TaskStartEventTopic = "/tasks/start" - TaskOOMEventTopic = "/tasks/oom" - TaskExitEventTopic = "/tasks/exit" - TaskDeleteEventTopic = "/tasks/delete" - TaskExecAddedEventTopic = "/tasks/exec-added" - TaskExecStartedEventTopic = "/tasks/exec-started" - TaskPausedEventTopic = "/tasks/paused" - TaskResumedEventTopic = "/tasks/resumed" - TaskCheckpointedEventTopic = "/tasks/checkpointed" - TaskUnknownTopic = "/tasks/?" -) diff --git a/vendor/github.com/containerd/containerd/runtime/monitor.go b/vendor/github.com/containerd/containerd/runtime/monitor.go deleted file mode 100644 index 4c61858ba5271..0000000000000 --- a/vendor/github.com/containerd/containerd/runtime/monitor.go +++ /dev/null @@ -1,52 +0,0 @@ -package runtime - -// TaskMonitor provides an interface for monitoring of containers within containerd -type TaskMonitor interface { - // Monitor adds the provided container to the monitor - Monitor(Task) error - // Stop stops and removes the provided container from the monitor - Stop(Task) error -} - -func NewMultiTaskMonitor(monitors ...TaskMonitor) TaskMonitor { - return &multiTaskMonitor{ - monitors: monitors, - } -} - -func NewNoopMonitor() TaskMonitor { - return &noopTaskMonitor{} -} - -type noopTaskMonitor struct { -} - -func (mm *noopTaskMonitor) Monitor(c Task) error { - return nil -} - -func (mm *noopTaskMonitor) Stop(c Task) error { - return nil -} - -type multiTaskMonitor struct { - monitors []TaskMonitor -} - -func (mm *multiTaskMonitor) Monitor(c Task) error { - for _, m := range mm.monitors { - if err := m.Monitor(c); err != nil { - return err - } - } - return nil -} - -func (mm *multiTaskMonitor) Stop(c Task) error { - for _, m := range mm.monitors { - if err := m.Stop(c); err != nil { - return err - } - } - return nil -} diff --git a/vendor/github.com/containerd/containerd/runtime/runtime.go b/vendor/github.com/containerd/containerd/runtime/runtime.go deleted file mode 100644 index 09642a45423e6..0000000000000 --- a/vendor/github.com/containerd/containerd/runtime/runtime.go +++ /dev/null @@ -1,51 +0,0 @@ -package runtime - -import ( - "context" - "time" - - "github.com/containerd/containerd/mount" - "github.com/gogo/protobuf/types" -) - -type IO struct { - Stdin string - Stdout string - Stderr string - Terminal bool -} - -type CreateOpts struct { - // Spec is the OCI runtime spec - Spec *types.Any - // Rootfs mounts to perform to gain access to the container's filesystem - Rootfs []mount.Mount - // IO for the container's main process - IO IO - // Checkpoint digest to restore container state - Checkpoint string - // Options for the runtime and container - Options *types.Any -} - -type Exit struct { - Pid uint32 - Status uint32 - Timestamp time.Time -} - -// Runtime is responsible for the creation of containers for a certain platform, -// arch, or custom usage. -type Runtime interface { - // ID of the runtime - ID() string - // Create creates a task with the provided id and options. - Create(ctx context.Context, id string, opts CreateOpts) (Task, error) - // Get returns a task. - Get(context.Context, string) (Task, error) - // Tasks returns all the current tasks for the runtime. - // Any container runs at most one task at a time. - Tasks(context.Context) ([]Task, error) - // Delete removes the task in the runtime. - Delete(context.Context, Task) (*Exit, error) -} diff --git a/vendor/github.com/containerd/containerd/runtime/task.go b/vendor/github.com/containerd/containerd/runtime/task.go deleted file mode 100644 index 4f5032237e223..0000000000000 --- a/vendor/github.com/containerd/containerd/runtime/task.go +++ /dev/null @@ -1,92 +0,0 @@ -package runtime - -import ( - "context" - "time" - - "github.com/gogo/protobuf/types" -) - -type TaskInfo struct { - ID string - Runtime string - Spec []byte - Namespace string -} - -type Process interface { - ID() string - // State returns the process state - State(context.Context) (State, error) - // Kill signals a container - Kill(context.Context, uint32, bool) error - // Pty resizes the processes pty/console - ResizePty(context.Context, ConsoleSize) error - // CloseStdin closes the processes stdin - CloseIO(context.Context) error - // Start the container's user defined process - Start(context.Context) error -} - -type Task interface { - Process - - // Information of the container - Info() TaskInfo - // Pause pauses the container process - Pause(context.Context) error - // Resume unpauses the container process - Resume(context.Context) error - // Exec adds a process into the container - Exec(context.Context, string, ExecOpts) (Process, error) - // Pids returns all pids - Pids(context.Context) ([]uint32, error) - // Checkpoint checkpoints a container to an image with live system data - Checkpoint(context.Context, string, *types.Any) error - // DeleteProcess deletes a specific exec process via its id - DeleteProcess(context.Context, string) (*Exit, error) - // Update sets the provided resources to a running task - Update(context.Context, *types.Any) error - // Process returns a process within the task for the provided id - Process(context.Context, string) (Process, error) - // Metrics returns runtime specific metrics for a task - Metrics(context.Context) (interface{}, error) -} - -type ExecOpts struct { - Spec *types.Any - IO IO -} - -type ConsoleSize struct { - Width uint32 - Height uint32 -} - -type Status int - -const ( - CreatedStatus Status = iota + 1 - RunningStatus - StoppedStatus - DeletedStatus - PausedStatus - PausingStatus -) - -type State struct { - // Status is the current status of the container - Status Status - // Pid is the main process id for the container - Pid uint32 - // ExitStatus of the process - // Only valid if the Status is Stopped - ExitStatus uint32 - // ExitedAt is the time at which the process exited - // Only valid if the Status is Stopped - ExitedAt time.Time - Stdin string - Stdout string - Stderr string - Terminal bool -} diff --git a/vendor/github.com/containerd/containerd/runtime/task_list.go b/vendor/github.com/containerd/containerd/runtime/task_list.go deleted file mode 100644 index 12062cef59d09..0000000000000 --- a/vendor/github.com/containerd/containerd/runtime/task_list.go +++ /dev/null @@ -1,95 +0,0 @@ -package runtime - -import ( - "context" - "sync" - - "github.com/containerd/containerd/namespaces" - "github.com/pkg/errors" -) - -var ( - ErrTaskNotExists = errors.New("task does not exist") - ErrTaskAlreadyExists = errors.New("task already exists") -) - -func NewTaskList() *TaskList { - return &TaskList{ - tasks: make(map[string]map[string]Task), - } -} - -type TaskList struct { - mu sync.Mutex - tasks map[string]map[string]Task -} - -func (l *TaskList) Get(ctx context.Context, id string) (Task, error) { - l.mu.Lock() - defer l.mu.Unlock() - namespace, err := namespaces.NamespaceRequired(ctx) - if err != nil { - return nil, err - } - tasks, ok := l.tasks[namespace] - if !ok { - return nil, ErrTaskNotExists - } - t, ok := tasks[id] - if !ok { - return nil, ErrTaskNotExists - } - return t, nil -} - -func (l *TaskList) GetAll(ctx context.Context) ([]Task, error) { - namespace, err := namespaces.NamespaceRequired(ctx) - if err != nil { - return nil, err - } - var o []Task - tasks, ok := l.tasks[namespace] - if !ok { - return o, nil - } - for _, t := range tasks { - o = append(o, t) - } - return o, nil -} - -func (l *TaskList) Add(ctx context.Context, t Task) error { - namespace, err := namespaces.NamespaceRequired(ctx) - if err != nil { - return err - } - return l.AddWithNamespace(namespace, t) -} - -func (l *TaskList) AddWithNamespace(namespace string, t Task) error { - l.mu.Lock() - defer l.mu.Unlock() - - id := t.ID() - if _, ok := l.tasks[namespace]; !ok { - l.tasks[namespace] = make(map[string]Task) - } - if _, ok := l.tasks[namespace][id]; ok { - return errors.Wrap(ErrTaskAlreadyExists, id) - } - l.tasks[namespace][id] = t - return nil -} - -func (l *TaskList) Delete(ctx context.Context, t Task) { - l.mu.Lock() - defer l.mu.Unlock() - namespace, err := namespaces.NamespaceRequired(ctx) - if err != nil { - return - } - tasks, ok := l.tasks[namespace] - if ok { - delete(tasks, t.ID()) - } -} diff --git a/vendor/github.com/containerd/containerd/runtime/typeurl.go b/vendor/github.com/containerd/containerd/runtime/typeurl.go deleted file mode 100644 index 46b186d28b339..0000000000000 --- a/vendor/github.com/containerd/containerd/runtime/typeurl.go +++ /dev/null @@ -1,17 +0,0 @@ -package runtime - -import ( - "strconv" - - "github.com/containerd/containerd/typeurl" - specs "github.com/opencontainers/runtime-spec/specs-go" -) - -func init() { - // register TypeUrls for commonly marshaled external types - major := strconv.Itoa(specs.VersionMajor) - typeurl.Register(&specs.Spec{}, "opencontainers/runtime-spec", major, "Spec") - typeurl.Register(&specs.Process{}, "opencontainers/runtime-spec", major, "Process") - typeurl.Register(&specs.LinuxResources{}, "opencontainers/runtime-spec", major, "LinuxResources") - typeurl.Register(&specs.WindowsResources{}, "opencontainers/runtime-spec", major, "WindowsResources") -} diff --git a/vendor/github.com/containerd/containerd/services/content/reader.go b/vendor/github.com/containerd/containerd/services/content/reader.go index a8cc55430efe6..024251c6d60e2 100644 --- a/vendor/github.com/containerd/containerd/services/content/reader.go +++ b/vendor/github.com/containerd/containerd/services/content/reader.go @@ -44,6 +44,6 @@ func (ra *remoteReaderAt) ReadAt(p []byte, off int64) (n int, err error) { return n, nil } -func (rr *remoteReaderAt) Close() error { +func (ra *remoteReaderAt) Close() error { return nil } diff --git a/vendor/github.com/containerd/containerd/services/content/service.go b/vendor/github.com/containerd/containerd/services/content/service.go index 7a5e6d6d0a5d0..3784579d56bd8 100644 --- a/vendor/github.com/containerd/containerd/services/content/service.go +++ b/vendor/github.com/containerd/containerd/services/content/service.go @@ -4,7 +4,6 @@ import ( "io" "sync" - "github.com/boltdb/bolt" api "github.com/containerd/containerd/api/services/content/v1" eventsapi "github.com/containerd/containerd/api/services/events/v1" "github.com/containerd/containerd/content" @@ -22,7 +21,7 @@ import ( "google.golang.org/grpc/codes" ) -type Service struct { +type service struct { store content.Store publisher events.Publisher } @@ -33,42 +32,41 @@ var bufPool = sync.Pool{ }, } -var _ api.ContentServer = &Service{} +var _ api.ContentServer = &service{} func init() { plugin.Register(&plugin.Registration{ Type: plugin.GRPCPlugin, ID: "content", - Requires: []plugin.PluginType{ - plugin.ContentPlugin, + Requires: []plugin.Type{ plugin.MetadataPlugin, }, - Init: NewService, + InitFn: func(ic *plugin.InitContext) (interface{}, error) { + m, err := ic.Get(plugin.MetadataPlugin) + if err != nil { + return nil, err + } + + s, err := NewService(m.(*metadata.DB).ContentStore(), ic.Events) + return s, err + }, }) } -func NewService(ic *plugin.InitContext) (interface{}, error) { - c, err := ic.Get(plugin.ContentPlugin) - if err != nil { - return nil, err - } - m, err := ic.Get(plugin.MetadataPlugin) - if err != nil { - return nil, err - } - cs := metadata.NewContentStore(m.(*bolt.DB), c.(content.Store)) - return &Service{ +// NewService returns the content GRPC server +func NewService(cs content.Store, publisher events.Publisher) (api.ContentServer, error) { + return &service{ store: cs, - publisher: ic.Events, + publisher: publisher, }, nil } -func (s *Service) Register(server *grpc.Server) error { +func (s *service) Register(server *grpc.Server) error { api.RegisterContentServer(server, s) return nil } -func (s *Service) Info(ctx context.Context, req *api.InfoRequest) (*api.InfoResponse, error) { +func (s *service) Info(ctx context.Context, req *api.InfoRequest) (*api.InfoResponse, error) { if err := req.Digest.Validate(); err != nil { return nil, grpc.Errorf(codes.InvalidArgument, "%q failed validation", req.Digest) } @@ -83,7 +81,7 @@ func (s *Service) Info(ctx context.Context, req *api.InfoRequest) (*api.InfoResp }, nil } -func (s *Service) Update(ctx context.Context, req *api.UpdateRequest) (*api.UpdateResponse, error) { +func (s *service) Update(ctx context.Context, req *api.UpdateRequest) (*api.UpdateResponse, error) { if err := req.Info.Digest.Validate(); err != nil { return nil, grpc.Errorf(codes.InvalidArgument, "%q failed validation", req.Info.Digest) } @@ -98,7 +96,7 @@ func (s *Service) Update(ctx context.Context, req *api.UpdateRequest) (*api.Upda }, nil } -func (s *Service) List(req *api.ListContentRequest, session api.Content_ListServer) error { +func (s *service) List(req *api.ListContentRequest, session api.Content_ListServer) error { var ( buffer []api.Info sendBlock = func(block []api.Info) error { @@ -140,7 +138,7 @@ func (s *Service) List(req *api.ListContentRequest, session api.Content_ListServ return nil } -func (s *Service) Delete(ctx context.Context, req *api.DeleteContentRequest) (*empty.Empty, error) { +func (s *service) Delete(ctx context.Context, req *api.DeleteContentRequest) (*empty.Empty, error) { if err := req.Digest.Validate(); err != nil { return nil, grpc.Errorf(codes.InvalidArgument, err.Error()) } @@ -158,7 +156,7 @@ func (s *Service) Delete(ctx context.Context, req *api.DeleteContentRequest) (*e return &empty.Empty{}, nil } -func (s *Service) Read(req *api.ReadContentRequest, session api.Content_ReadServer) error { +func (s *service) Read(req *api.ReadContentRequest, session api.Content_ReadServer) error { if err := req.Digest.Validate(); err != nil { return grpc.Errorf(codes.InvalidArgument, "%v: %v", req.Digest, err) } @@ -226,7 +224,7 @@ func (rw *readResponseWriter) Write(p []byte) (n int, err error) { return len(p), nil } -func (s *Service) Status(ctx context.Context, req *api.StatusRequest) (*api.StatusResponse, error) { +func (s *service) Status(ctx context.Context, req *api.StatusRequest) (*api.StatusResponse, error) { status, err := s.store.Status(ctx, req.Ref) if err != nil { return nil, errdefs.ToGRPCf(err, "could not get status for ref %q", req.Ref) @@ -245,7 +243,7 @@ func (s *Service) Status(ctx context.Context, req *api.StatusRequest) (*api.Stat return &resp, nil } -func (s *Service) ListStatuses(ctx context.Context, req *api.ListStatusesRequest) (*api.ListStatusesResponse, error) { +func (s *service) ListStatuses(ctx context.Context, req *api.ListStatusesRequest) (*api.ListStatusesResponse, error) { statuses, err := s.store.ListStatuses(ctx, req.Filters...) if err != nil { return nil, errdefs.ToGRPC(err) @@ -266,7 +264,7 @@ func (s *Service) ListStatuses(ctx context.Context, req *api.ListStatusesRequest return &resp, nil } -func (s *Service) Write(session api.Content_WriteServer) (err error) { +func (s *service) Write(session api.Content_WriteServer) (err error) { var ( ctx = session.Context() msg api.WriteContentResponse @@ -286,7 +284,7 @@ func (s *Service) Write(session api.Content_WriteServer) (err error) { // identically across all GRPC methods. // // This is pretty noisy, so we can remove it but leave it for now. - log.G(ctx).WithError(err).Error("(*Service).Write failed") + log.G(ctx).WithError(err).Error("(*service).Write failed") } return @@ -322,7 +320,7 @@ func (s *Service) Write(session api.Content_WriteServer) (err error) { ctx = log.WithLogger(ctx, log.G(ctx).WithFields(fields)) - log.G(ctx).Debug("(*Service).Write started") + log.G(ctx).Debug("(*service).Write started") // this action locks the writer for the session. wr, err := s.store.Writer(ctx, ref, total, expected) if err != nil { @@ -354,7 +352,7 @@ func (s *Service) Write(session api.Content_WriteServer) (err error) { // 2. Compress inline. // 3. Validate digest and size (maybe). // - // Supporting these two paths is quite awkward but it let's both API + // Supporting these two paths is quite awkward but it lets both API // users use the same writer style for each with a minimum of overhead. if req.Expected != "" { if expected != "" && expected != req.Expected { @@ -447,7 +445,7 @@ func (s *Service) Write(session api.Content_WriteServer) (err error) { } } -func (s *Service) Abort(ctx context.Context, req *api.AbortRequest) (*empty.Empty, error) { +func (s *service) Abort(ctx context.Context, req *api.AbortRequest) (*empty.Empty, error) { if err := s.store.Abort(ctx, req.Ref); err != nil { return nil, errdefs.ToGRPC(err) } diff --git a/vendor/github.com/containerd/containerd/services/content/store.go b/vendor/github.com/containerd/containerd/services/content/store.go index 11fcc036517ea..b5aaa8577ce33 100644 --- a/vendor/github.com/containerd/containerd/services/content/store.go +++ b/vendor/github.com/containerd/containerd/services/content/store.go @@ -15,6 +15,7 @@ type remoteStore struct { client contentapi.ContentClient } +// NewStoreFromClient returns a new content store func NewStoreFromClient(client contentapi.ContentClient) content.Store { return &remoteStore{ client: client, diff --git a/vendor/github.com/containerd/containerd/services/diff/client.go b/vendor/github.com/containerd/containerd/services/diff/client.go index 81b9bf34a07b0..d34848be20efa 100644 --- a/vendor/github.com/containerd/containerd/services/diff/client.go +++ b/vendor/github.com/containerd/containerd/services/diff/client.go @@ -3,20 +3,15 @@ package diff import ( diffapi "github.com/containerd/containerd/api/services/diff/v1" "github.com/containerd/containerd/api/types" + "github.com/containerd/containerd/diff" "github.com/containerd/containerd/mount" - "github.com/containerd/containerd/rootfs" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "golang.org/x/net/context" ) -type DiffService interface { - rootfs.Applier - rootfs.MountDiffer -} - -// NewApplierFromClient returns a new Applier which communicates +// NewDiffServiceFromClient returns a new diff service which communicates // over a GRPC connection. -func NewDiffServiceFromClient(client diffapi.DiffClient) DiffService { +func NewDiffServiceFromClient(client diffapi.DiffClient) diff.Differ { return &remote{ client: client, } @@ -38,12 +33,19 @@ func (r *remote) Apply(ctx context.Context, diff ocispec.Descriptor, mounts []mo return toDescriptor(resp.Applied), nil } -func (r *remote) DiffMounts(ctx context.Context, a, b []mount.Mount, media, ref string) (ocispec.Descriptor, error) { +func (r *remote) DiffMounts(ctx context.Context, a, b []mount.Mount, opts ...diff.Opt) (ocispec.Descriptor, error) { + var config diff.Config + for _, opt := range opts { + if err := opt(&config); err != nil { + return ocispec.Descriptor{}, err + } + } req := &diffapi.DiffRequest{ Left: fromMounts(a), Right: fromMounts(b), - MediaType: media, - Ref: ref, + MediaType: config.MediaType, + Ref: config.Reference, + Labels: config.Labels, } resp, err := r.client.Diff(ctx, req) if err != nil { diff --git a/vendor/github.com/containerd/containerd/services/diff/service.go b/vendor/github.com/containerd/containerd/services/diff/service.go index af6326b605a1a..81e44dcf6ff52 100644 --- a/vendor/github.com/containerd/containerd/services/diff/service.go +++ b/vendor/github.com/containerd/containerd/services/diff/service.go @@ -3,6 +3,7 @@ package diff import ( diffapi "github.com/containerd/containerd/api/services/diff/v1" "github.com/containerd/containerd/api/types" + "github.com/containerd/containerd/diff" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/plugin" @@ -19,33 +20,38 @@ type config struct { // respected for which is choosen. Each differ should return the same // correct output, allowing any ordering to be used to prefer // more optimimal implementations. - Order []string `toml:"default,omitempty"` + Order []string `toml:"default"` } func init() { plugin.Register(&plugin.Registration{ Type: plugin.GRPCPlugin, ID: "diff", - Requires: []plugin.PluginType{ + Requires: []plugin.Type{ plugin.DiffPlugin, }, Config: &config{ Order: []string{"walking"}, }, - Init: func(ic *plugin.InitContext) (interface{}, error) { - differs, err := ic.GetAll(plugin.DiffPlugin) + InitFn: func(ic *plugin.InitContext) (interface{}, error) { + differs, err := ic.GetByType(plugin.DiffPlugin) if err != nil { return nil, err } orderedNames := ic.Config.(*config).Order - ordered := make([]plugin.Differ, len(orderedNames)) + ordered := make([]diff.Differ, len(orderedNames)) for i, n := range orderedNames { - differ, ok := differs[n] + differp, ok := differs[n] if !ok { return nil, errors.Errorf("needed differ not loaded: %s", n) } - ordered[i] = differ.(plugin.Differ) + differ, err := differp.Instance() + if err != nil { + return nil, errors.Wrapf(err, "could not load required differ due plugin init error: %s", n) + } + + ordered[i] = differ.(diff.Differ) } return &service{ @@ -56,7 +62,7 @@ func init() { } type service struct { - differs []plugin.Differ + differs []diff.Differ } func (s *service) Register(gs *grpc.Server) error { @@ -97,8 +103,19 @@ func (s *service) Diff(ctx context.Context, dr *diffapi.DiffRequest) (*diffapi.D bMounts = toMounts(dr.Right) ) + var opts []diff.Opt + if dr.MediaType != "" { + opts = append(opts, diff.WithMediaType(dr.MediaType)) + } + if dr.Ref != "" { + opts = append(opts, diff.WithReference(dr.Ref)) + } + if dr.Labels != nil { + opts = append(opts, diff.WithLabels(dr.Labels)) + } + for _, differ := range s.differs { - ocidesc, err = differ.DiffMounts(ctx, aMounts, bMounts, dr.MediaType, dr.Ref) + ocidesc, err = differ.DiffMounts(ctx, aMounts, bMounts, opts...) if !errdefs.IsNotImplemented(err) { break } diff --git a/vendor/github.com/containerd/containerd/services/images/client.go b/vendor/github.com/containerd/containerd/services/images/client.go index eebe776fac1fe..f746ddce8b696 100644 --- a/vendor/github.com/containerd/containerd/services/images/client.go +++ b/vendor/github.com/containerd/containerd/services/images/client.go @@ -13,6 +13,7 @@ type remoteStore struct { client imagesapi.ImagesClient } +// NewStoreFromClient returns a new image store client func NewStoreFromClient(client imagesapi.ImagesClient) images.Store { return &remoteStore{ client: client, diff --git a/vendor/github.com/containerd/containerd/services/images/service.go b/vendor/github.com/containerd/containerd/services/images/service.go index d8499aa43cbd2..3843df554c706 100644 --- a/vendor/github.com/containerd/containerd/services/images/service.go +++ b/vendor/github.com/containerd/containerd/services/images/service.go @@ -10,6 +10,7 @@ import ( "github.com/containerd/containerd/metadata" "github.com/containerd/containerd/plugin" "github.com/golang/protobuf/ptypes/empty" + "github.com/pkg/errors" "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -20,37 +21,38 @@ func init() { plugin.Register(&plugin.Registration{ Type: plugin.GRPCPlugin, ID: "images", - Requires: []plugin.PluginType{ + Requires: []plugin.Type{ plugin.MetadataPlugin, }, - Init: func(ic *plugin.InitContext) (interface{}, error) { + InitFn: func(ic *plugin.InitContext) (interface{}, error) { m, err := ic.Get(plugin.MetadataPlugin) if err != nil { return nil, err } - return NewService(m.(*bolt.DB), ic.Events), nil + return NewService(m.(*metadata.DB), ic.Events), nil }, }) } -type Service struct { - db *bolt.DB +type service struct { + db *metadata.DB publisher events.Publisher } -func NewService(db *bolt.DB, publisher events.Publisher) imagesapi.ImagesServer { - return &Service{ +// NewService returns the GRPC image server +func NewService(db *metadata.DB, publisher events.Publisher) imagesapi.ImagesServer { + return &service{ db: db, publisher: publisher, } } -func (s *Service) Register(server *grpc.Server) error { +func (s *service) Register(server *grpc.Server) error { imagesapi.RegisterImagesServer(server, s) return nil } -func (s *Service) Get(ctx context.Context, req *imagesapi.GetImageRequest) (*imagesapi.GetImageResponse, error) { +func (s *service) Get(ctx context.Context, req *imagesapi.GetImageRequest) (*imagesapi.GetImageResponse, error) { var resp imagesapi.GetImageResponse return &resp, errdefs.ToGRPC(s.withStoreView(ctx, func(ctx context.Context, store images.Store) error { @@ -64,7 +66,7 @@ func (s *Service) Get(ctx context.Context, req *imagesapi.GetImageRequest) (*ima })) } -func (s *Service) List(ctx context.Context, req *imagesapi.ListImagesRequest) (*imagesapi.ListImagesResponse, error) { +func (s *service) List(ctx context.Context, req *imagesapi.ListImagesRequest) (*imagesapi.ListImagesResponse, error) { var resp imagesapi.ListImagesResponse return &resp, errdefs.ToGRPC(s.withStoreView(ctx, func(ctx context.Context, store images.Store) error { @@ -78,7 +80,7 @@ func (s *Service) List(ctx context.Context, req *imagesapi.ListImagesRequest) (* })) } -func (s *Service) Create(ctx context.Context, req *imagesapi.CreateImageRequest) (*imagesapi.CreateImageResponse, error) { +func (s *service) Create(ctx context.Context, req *imagesapi.CreateImageRequest) (*imagesapi.CreateImageResponse, error) { if req.Image.Name == "" { return nil, status.Errorf(codes.InvalidArgument, "Image.Name required") } @@ -110,7 +112,7 @@ func (s *Service) Create(ctx context.Context, req *imagesapi.CreateImageRequest) } -func (s *Service) Update(ctx context.Context, req *imagesapi.UpdateImageRequest) (*imagesapi.UpdateImageResponse, error) { +func (s *service) Update(ctx context.Context, req *imagesapi.UpdateImageRequest) (*imagesapi.UpdateImageResponse, error) { if req.Image.Name == "" { return nil, status.Errorf(codes.InvalidArgument, "Image.Name required") } @@ -148,7 +150,7 @@ func (s *Service) Update(ctx context.Context, req *imagesapi.UpdateImageRequest) return &resp, nil } -func (s *Service) Delete(ctx context.Context, req *imagesapi.DeleteImageRequest) (*empty.Empty, error) { +func (s *service) Delete(ctx context.Context, req *imagesapi.DeleteImageRequest) (*empty.Empty, error) { if err := s.withStoreUpdate(ctx, func(ctx context.Context, store images.Store) error { return errdefs.ToGRPC(store.Delete(ctx, req.Name)) }); err != nil { @@ -161,17 +163,21 @@ func (s *Service) Delete(ctx context.Context, req *imagesapi.DeleteImageRequest) return nil, err } + if err := s.db.GarbageCollect(ctx); err != nil { + return nil, errdefs.ToGRPC(errors.Wrap(err, "garbage collection failed")) + } + return &empty.Empty{}, nil } -func (s *Service) withStore(ctx context.Context, fn func(ctx context.Context, store images.Store) error) func(tx *bolt.Tx) error { +func (s *service) withStore(ctx context.Context, fn func(ctx context.Context, store images.Store) error) func(tx *bolt.Tx) error { return func(tx *bolt.Tx) error { return fn(ctx, metadata.NewImageStore(tx)) } } -func (s *Service) withStoreView(ctx context.Context, fn func(ctx context.Context, store images.Store) error) error { +func (s *service) withStoreView(ctx context.Context, fn func(ctx context.Context, store images.Store) error) error { return s.db.View(s.withStore(ctx, fn)) } -func (s *Service) withStoreUpdate(ctx context.Context, fn func(ctx context.Context, store images.Store) error) error { +func (s *service) withStoreUpdate(ctx context.Context, fn func(ctx context.Context, store images.Store) error) error { return s.db.Update(s.withStore(ctx, fn)) } diff --git a/vendor/github.com/containerd/containerd/services/namespaces/client.go b/vendor/github.com/containerd/containerd/services/namespaces/client.go new file mode 100644 index 0000000000000..fd59ec619db26 --- /dev/null +++ b/vendor/github.com/containerd/containerd/services/namespaces/client.go @@ -0,0 +1,97 @@ +package namespaces + +import ( + "context" + "strings" + + api "github.com/containerd/containerd/api/services/namespaces/v1" + "github.com/containerd/containerd/errdefs" + "github.com/containerd/containerd/namespaces" + "github.com/gogo/protobuf/types" +) + +// NewStoreFromClient returns a new namespace store +func NewStoreFromClient(client api.NamespacesClient) namespaces.Store { + return &remote{client: client} +} + +type remote struct { + client api.NamespacesClient +} + +func (r *remote) Create(ctx context.Context, namespace string, labels map[string]string) error { + var req api.CreateNamespaceRequest + + req.Namespace = api.Namespace{ + Name: namespace, + Labels: labels, + } + + _, err := r.client.Create(ctx, &req) + if err != nil { + return errdefs.FromGRPC(err) + } + + return nil +} + +func (r *remote) Labels(ctx context.Context, namespace string) (map[string]string, error) { + var req api.GetNamespaceRequest + req.Name = namespace + + resp, err := r.client.Get(ctx, &req) + if err != nil { + return nil, errdefs.FromGRPC(err) + } + + return resp.Namespace.Labels, nil +} + +func (r *remote) SetLabel(ctx context.Context, namespace, key, value string) error { + var req api.UpdateNamespaceRequest + + req.Namespace = api.Namespace{ + Name: namespace, + Labels: map[string]string{key: value}, + } + + req.UpdateMask = &types.FieldMask{ + Paths: []string{strings.Join([]string{"labels", key}, ".")}, + } + + _, err := r.client.Update(ctx, &req) + if err != nil { + return errdefs.FromGRPC(err) + } + + return nil +} + +func (r *remote) List(ctx context.Context) ([]string, error) { + var req api.ListNamespacesRequest + + resp, err := r.client.List(ctx, &req) + if err != nil { + return nil, errdefs.FromGRPC(err) + } + + var namespaces []string + + for _, ns := range resp.Namespaces { + namespaces = append(namespaces, ns.Name) + } + + return namespaces, nil +} + +func (r *remote) Delete(ctx context.Context, namespace string) error { + var req api.DeleteNamespaceRequest + + req.Name = namespace + _, err := r.client.Delete(ctx, &req) + if err != nil { + return errdefs.FromGRPC(err) + } + + return nil +} diff --git a/vendor/github.com/containerd/containerd/services/namespaces/service.go b/vendor/github.com/containerd/containerd/services/namespaces/service.go new file mode 100644 index 0000000000000..b795ab52f7c7a --- /dev/null +++ b/vendor/github.com/containerd/containerd/services/namespaces/service.go @@ -0,0 +1,212 @@ +package namespaces + +import ( + "strings" + + "github.com/boltdb/bolt" + eventsapi "github.com/containerd/containerd/api/services/events/v1" + api "github.com/containerd/containerd/api/services/namespaces/v1" + "github.com/containerd/containerd/errdefs" + "github.com/containerd/containerd/events" + "github.com/containerd/containerd/metadata" + "github.com/containerd/containerd/namespaces" + "github.com/containerd/containerd/plugin" + "github.com/golang/protobuf/ptypes/empty" + "golang.org/x/net/context" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" +) + +func init() { + plugin.Register(&plugin.Registration{ + Type: plugin.GRPCPlugin, + ID: "namespaces", + Requires: []plugin.Type{ + plugin.MetadataPlugin, + }, + InitFn: func(ic *plugin.InitContext) (interface{}, error) { + m, err := ic.Get(plugin.MetadataPlugin) + if err != nil { + return nil, err + } + return NewService(m.(*metadata.DB), ic.Events), nil + }, + }) +} + +type service struct { + db *metadata.DB + publisher events.Publisher +} + +var _ api.NamespacesServer = &service{} + +// NewService returns the GRPC namespaces server +func NewService(db *metadata.DB, publisher events.Publisher) api.NamespacesServer { + return &service{ + db: db, + publisher: publisher, + } +} + +func (s *service) Register(server *grpc.Server) error { + api.RegisterNamespacesServer(server, s) + return nil +} + +func (s *service) Get(ctx context.Context, req *api.GetNamespaceRequest) (*api.GetNamespaceResponse, error) { + var resp api.GetNamespaceResponse + + return &resp, s.withStoreView(ctx, func(ctx context.Context, store namespaces.Store) error { + labels, err := store.Labels(ctx, req.Name) + if err != nil { + return errdefs.ToGRPC(err) + } + + resp.Namespace = api.Namespace{ + Name: req.Name, + Labels: labels, + } + + return nil + }) +} + +func (s *service) List(ctx context.Context, req *api.ListNamespacesRequest) (*api.ListNamespacesResponse, error) { + var resp api.ListNamespacesResponse + + return &resp, s.withStoreView(ctx, func(ctx context.Context, store namespaces.Store) error { + namespaces, err := store.List(ctx) + if err != nil { + return err + } + + for _, namespace := range namespaces { + labels, err := store.Labels(ctx, namespace) + if err != nil { + // In general, this should be unlikely, since we are holding a + // transaction to service this request. + return errdefs.ToGRPC(err) + } + + resp.Namespaces = append(resp.Namespaces, api.Namespace{ + Name: namespace, + Labels: labels, + }) + } + + return nil + }) +} + +func (s *service) Create(ctx context.Context, req *api.CreateNamespaceRequest) (*api.CreateNamespaceResponse, error) { + var resp api.CreateNamespaceResponse + + if err := s.withStoreUpdate(ctx, func(ctx context.Context, store namespaces.Store) error { + if err := store.Create(ctx, req.Namespace.Name, req.Namespace.Labels); err != nil { + return errdefs.ToGRPC(err) + } + + for k, v := range req.Namespace.Labels { + if err := store.SetLabel(ctx, req.Namespace.Name, k, v); err != nil { + return err + } + } + + resp.Namespace = req.Namespace + return nil + }); err != nil { + return &resp, err + } + + if err := s.publisher.Publish(ctx, "/namespaces/create", &eventsapi.NamespaceCreate{ + Name: req.Namespace.Name, + Labels: req.Namespace.Labels, + }); err != nil { + return &resp, err + } + + return &resp, nil + +} + +func (s *service) Update(ctx context.Context, req *api.UpdateNamespaceRequest) (*api.UpdateNamespaceResponse, error) { + var resp api.UpdateNamespaceResponse + if err := s.withStoreUpdate(ctx, func(ctx context.Context, store namespaces.Store) error { + if req.UpdateMask != nil && len(req.UpdateMask.Paths) > 0 { + for _, path := range req.UpdateMask.Paths { + switch { + case strings.HasPrefix(path, "labels."): + key := strings.TrimPrefix(path, "labels.") + if err := store.SetLabel(ctx, req.Namespace.Name, key, req.Namespace.Labels[key]); err != nil { + return err + } + default: + return grpc.Errorf(codes.InvalidArgument, "cannot update %q field", path) + } + } + } else { + // clear out the existing labels and then set them to the incoming request. + // get current set of labels + labels, err := store.Labels(ctx, req.Namespace.Name) + if err != nil { + return errdefs.ToGRPC(err) + } + + for k := range labels { + if err := store.SetLabel(ctx, req.Namespace.Name, k, ""); err != nil { + return err + } + } + + for k, v := range req.Namespace.Labels { + if err := store.SetLabel(ctx, req.Namespace.Name, k, v); err != nil { + return err + } + + } + } + + return nil + }); err != nil { + return &resp, err + } + + if err := s.publisher.Publish(ctx, "/namespaces/update", &eventsapi.NamespaceUpdate{ + Name: req.Namespace.Name, + Labels: req.Namespace.Labels, + }); err != nil { + return &resp, err + } + + return &resp, nil +} + +func (s *service) Delete(ctx context.Context, req *api.DeleteNamespaceRequest) (*empty.Empty, error) { + if err := s.withStoreUpdate(ctx, func(ctx context.Context, store namespaces.Store) error { + return errdefs.ToGRPC(store.Delete(ctx, req.Name)) + }); err != nil { + return &empty.Empty{}, err + } + // set the namespace in the context before publishing the event + ctx = namespaces.WithNamespace(ctx, req.Name) + if err := s.publisher.Publish(ctx, "/namespaces/delete", &eventsapi.NamespaceDelete{ + Name: req.Name, + }); err != nil { + return &empty.Empty{}, err + } + + return &empty.Empty{}, nil +} + +func (s *service) withStore(ctx context.Context, fn func(ctx context.Context, store namespaces.Store) error) func(tx *bolt.Tx) error { + return func(tx *bolt.Tx) error { return fn(ctx, metadata.NewNamespaceStore(tx)) } +} + +func (s *service) withStoreView(ctx context.Context, fn func(ctx context.Context, store namespaces.Store) error) error { + return s.db.View(s.withStore(ctx, fn)) +} + +func (s *service) withStoreUpdate(ctx context.Context, fn func(ctx context.Context, store namespaces.Store) error) error { + return s.db.Update(s.withStore(ctx, fn)) +} diff --git a/vendor/github.com/containerd/containerd/services/snapshot/service.go b/vendor/github.com/containerd/containerd/services/snapshot/service.go index 293a643e3ec7a..716b4c42c5a78 100644 --- a/vendor/github.com/containerd/containerd/services/snapshot/service.go +++ b/vendor/github.com/containerd/containerd/services/snapshot/service.go @@ -3,7 +3,6 @@ package snapshot import ( gocontext "context" - "github.com/boltdb/bolt" eventsapi "github.com/containerd/containerd/api/services/events/v1" snapshotapi "github.com/containerd/containerd/api/services/snapshot/v1" "github.com/containerd/containerd/api/types" @@ -15,7 +14,6 @@ import ( "github.com/containerd/containerd/plugin" "github.com/containerd/containerd/snapshot" protoempty "github.com/golang/protobuf/ptypes/empty" - "github.com/pkg/errors" "golang.org/x/net/context" "google.golang.org/grpc" ) @@ -24,42 +22,29 @@ func init() { plugin.Register(&plugin.Registration{ Type: plugin.GRPCPlugin, ID: "snapshots", - Requires: []plugin.PluginType{ - plugin.SnapshotPlugin, + Requires: []plugin.Type{ plugin.MetadataPlugin, }, - Init: newService, + InitFn: newService, }) } var empty = &protoempty.Empty{} type service struct { - snapshotters map[string]snapshot.Snapshotter - publisher events.Publisher + db *metadata.DB + publisher events.Publisher } func newService(ic *plugin.InitContext) (interface{}, error) { - rawSnapshotters, err := ic.GetAll(plugin.SnapshotPlugin) - if err != nil { - return nil, err - } md, err := ic.Get(plugin.MetadataPlugin) if err != nil { return nil, err } - snapshotters := make(map[string]snapshot.Snapshotter) - for name, sn := range rawSnapshotters { - snapshotters[name] = metadata.NewSnapshotter(md.(*bolt.DB), name, sn.(snapshot.Snapshotter)) - } - - if len(snapshotters) == 0 { - return nil, errors.Errorf("failed to create snapshotter service: no snapshotters loaded") - } return &service{ - snapshotters: snapshotters, - publisher: ic.Events, + db: md.(*metadata.DB), + publisher: ic.Events, }, nil } @@ -68,8 +53,8 @@ func (s *service) getSnapshotter(name string) (snapshot.Snapshotter, error) { return nil, errdefs.ToGRPCf(errdefs.ErrInvalidArgument, "snapshotter argument missing") } - sn, ok := s.snapshotters[name] - if !ok { + sn := s.db.Snapshotter(name) + if sn == nil { return nil, errdefs.ToGRPCf(errdefs.ErrInvalidArgument, "snapshotter not loaded: %s", name) } return sn, nil diff --git a/vendor/github.com/containerd/containerd/snapshot/naive/naive.go b/vendor/github.com/containerd/containerd/snapshot/naive/naive.go index f2f849cc12d11..006afd5768563 100644 --- a/vendor/github.com/containerd/containerd/snapshot/naive/naive.go +++ b/vendor/github.com/containerd/containerd/snapshot/naive/naive.go @@ -9,6 +9,7 @@ import ( "github.com/containerd/containerd/fs" "github.com/containerd/containerd/log" "github.com/containerd/containerd/mount" + "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/plugin" "github.com/containerd/containerd/snapshot" "github.com/containerd/containerd/snapshot/storage" @@ -19,7 +20,8 @@ func init() { plugin.Register(&plugin.Registration{ Type: plugin.SnapshotPlugin, ID: "naive", - Init: func(ic *plugin.InitContext) (interface{}, error) { + InitFn: func(ic *plugin.InitContext) (interface{}, error) { + ic.Meta.Platforms = append(ic.Meta.Platforms, platforms.DefaultSpec()) return NewSnapshotter(ic.Root) }, }) diff --git a/vendor/github.com/containerd/containerd/snapshot/overlay/overlay.go b/vendor/github.com/containerd/containerd/snapshot/overlay/overlay.go index d682339204b08..8f0e0d09e90ff 100644 --- a/vendor/github.com/containerd/containerd/snapshot/overlay/overlay.go +++ b/vendor/github.com/containerd/containerd/snapshot/overlay/overlay.go @@ -14,6 +14,7 @@ import ( "github.com/containerd/containerd/fs" "github.com/containerd/containerd/log" "github.com/containerd/containerd/mount" + "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/plugin" "github.com/containerd/containerd/snapshot" "github.com/containerd/containerd/snapshot/storage" @@ -24,7 +25,9 @@ func init() { plugin.Register(&plugin.Registration{ Type: plugin.SnapshotPlugin, ID: "overlayfs", - Init: func(ic *plugin.InitContext) (interface{}, error) { + InitFn: func(ic *plugin.InitContext) (interface{}, error) { + ic.Meta.Platforms = append(ic.Meta.Platforms, platforms.DefaultSpec()) + ic.Meta.Exports["root"] = ic.Root return NewSnapshotter(ic.Root) }, }) @@ -54,7 +57,7 @@ func NewSnapshotter(root string) (snapshot.Snapshotter, error) { return nil, err } if !supportsDType { - return nil, fmt.Errorf("%s does not support d_type. If the backing filesystem is xfs, please reformat with ftype=1 to enable d_type support.", root) + return nil, fmt.Errorf("%s does not support d_type. If the backing filesystem is xfs, please reformat with ftype=1 to enable d_type support", root) } ms, err := storage.NewMetaStore(filepath.Join(root, "metadata.db")) if err != nil { diff --git a/vendor/github.com/containerd/containerd/snapshot/snapshotter.go b/vendor/github.com/containerd/containerd/snapshot/snapshotter.go index 29d15b393a2db..2b3fe627554f6 100644 --- a/vendor/github.com/containerd/containerd/snapshot/snapshotter.go +++ b/vendor/github.com/containerd/containerd/snapshot/snapshotter.go @@ -20,6 +20,9 @@ const ( KindCommitted ) +// ParseKind parses the provided string into a Kind +// +// If the string cannot be parsed KindUnknown is returned func ParseKind(s string) Kind { s = strings.ToLower(s) switch s { @@ -34,6 +37,7 @@ func ParseKind(s string) Kind { return KindUnknown } +// String returns the string representation of the Kind func (k Kind) String() string { switch k { case KindView: @@ -47,10 +51,12 @@ func (k Kind) String() string { return "Unknown" } +// MarshalJSON the Kind to JSON func (k Kind) MarshalJSON() ([]byte, error) { return json.Marshal(k.String()) } +// UnmarshalJSON the Kind from JSON func (k *Kind) UnmarshalJSON(b []byte) error { var s string if err := json.Unmarshal(b, &s); err != nil { @@ -81,6 +87,7 @@ type Usage struct { Size int64 // provides usage, in bytes, of snapshot } +// Add the provided usage to the current usage func (u *Usage) Add(other Usage) { u.Size += other.Size @@ -146,7 +153,7 @@ func (u *Usage) Add(other Usage) { // the active snapshot. Mount this to the temporary location with the // following: // -// if err := containerd.MountAll(mounts, tmpDir); err != nil { ... } +// if err := mount.All(mounts, tmpDir); err != nil { ... } // // Once the mounts are performed, our temporary location is ready to capture // a diff. In practice, this works similar to a filesystem transaction. The @@ -213,7 +220,7 @@ type Snapshotter interface { // the kind of snapshot. Stat(ctx context.Context, key string) (Info, error) - // Update updates the infor for a snapshot. + // Update updates the info for a snapshot. // // Only mutable properties of a snapshot may be updated. Update(ctx context.Context, info Info, fieldpaths ...string) (Info, error) diff --git a/vendor/github.com/containerd/containerd/snapshot/storage/bolt.go b/vendor/github.com/containerd/containerd/snapshot/storage/bolt.go index 4f0c677ce28d5..26c394c06aceb 100644 --- a/vendor/github.com/containerd/containerd/snapshot/storage/bolt.go +++ b/vendor/github.com/containerd/containerd/snapshot/storage/bolt.go @@ -30,21 +30,6 @@ var ( ErrNoTransaction = errors.New("no transaction in context") ) -type boltFileTransactor struct { - db *bolt.DB - tx *bolt.Tx -} - -func (bft *boltFileTransactor) Rollback() error { - defer bft.db.Close() - return bft.tx.Rollback() -} - -func (bft *boltFileTransactor) Commit() error { - defer bft.db.Close() - return bft.tx.Commit() -} - // parentKey returns a composite key of the parent and child identifiers. The // parts of the key are separated by a zero byte. func parentKey(parent, child uint64) []byte { @@ -90,6 +75,7 @@ func GetInfo(ctx context.Context, key string) (string, snapshot.Info, snapshot.U return fmt.Sprintf("%d", id), si, su, nil } +// UpdateInfo updates an existing snapshot info's data func UpdateInfo(ctx context.Context, info snapshot.Info, fieldpaths ...string) (snapshot.Info, error) { updated := snapshot.Info{ Name: info.Name, @@ -131,11 +117,7 @@ func UpdateInfo(ctx context.Context, info snapshot.Info, fieldpaths ...string) ( return err } - if err := boltutil.WriteLabels(sbkt, updated.Labels); err != nil { - return err - } - - return nil + return boltutil.WriteLabels(sbkt, updated.Labels) }) if err != nil { return snapshot.Info{}, err @@ -305,7 +287,7 @@ func Remove(ctx context.Context, key string) (string, snapshot.Kind, error) { if pbkt != nil { k, _ := pbkt.Cursor().Seek(parentPrefixKey(id)) if getParentPrefix(k) == id { - return errors.Errorf("cannot remove snapshot with child") + return errors.Wrap(errdefs.ErrFailedPrecondition, "cannot remove snapshot with child") } if si.Parent != "" { @@ -408,11 +390,11 @@ func CommitActive(ctx context.Context, key, name string, usage snapshot.Usage, o } func withSnapshotBucket(ctx context.Context, key string, fn func(context.Context, *bolt.Bucket, *bolt.Bucket) error) error { - t, ok := ctx.Value(transactionKey{}).(*boltFileTransactor) + tx, ok := ctx.Value(transactionKey{}).(*bolt.Tx) if !ok { return ErrNoTransaction } - bkt := t.tx.Bucket(bucketKeyStorageVersion) + bkt := tx.Bucket(bucketKeyStorageVersion) if bkt == nil { return errors.Wrap(errdefs.ErrNotFound, "bucket does not exist") } @@ -429,11 +411,11 @@ func withSnapshotBucket(ctx context.Context, key string, fn func(context.Context } func withBucket(ctx context.Context, fn func(context.Context, *bolt.Bucket, *bolt.Bucket) error) error { - t, ok := ctx.Value(transactionKey{}).(*boltFileTransactor) + tx, ok := ctx.Value(transactionKey{}).(*bolt.Tx) if !ok { return ErrNoTransaction } - bkt := t.tx.Bucket(bucketKeyStorageVersion) + bkt := tx.Bucket(bucketKeyStorageVersion) if bkt == nil { return errors.Wrap(errdefs.ErrNotFound, "bucket does not exist") } @@ -441,12 +423,12 @@ func withBucket(ctx context.Context, fn func(context.Context, *bolt.Bucket, *bol } func createBucketIfNotExists(ctx context.Context, fn func(context.Context, *bolt.Bucket, *bolt.Bucket) error) error { - t, ok := ctx.Value(transactionKey{}).(*boltFileTransactor) + tx, ok := ctx.Value(transactionKey{}).(*bolt.Tx) if !ok { return ErrNoTransaction } - bkt, err := t.tx.CreateBucketIfNotExists(bucketKeyStorageVersion) + bkt, err := tx.CreateBucketIfNotExists(bucketKeyStorageVersion) if err != nil { return errors.Wrap(err, "failed to create version bucket") } @@ -534,12 +516,7 @@ func putSnapshot(bkt *bolt.Bucket, id uint64, si snapshot.Info) error { if err := boltutil.WriteTimestamps(bkt, si.Created, si.Updated); err != nil { return err } - - if err := boltutil.WriteLabels(bkt, si.Labels); err != nil { - return err - } - - return nil + return boltutil.WriteLabels(bkt, si.Labels) } func getUsage(bkt *bolt.Bucket, usage *snapshot.Usage) { @@ -569,7 +546,7 @@ func putUsage(bkt *bolt.Bucket, usage snapshot.Usage) error { func encodeSize(size int64) ([]byte, error) { var ( buf [binary.MaxVarintLen64]byte - sizeEncoded []byte = buf[:] + sizeEncoded = buf[:] ) sizeEncoded = sizeEncoded[:binary.PutVarint(sizeEncoded, size)] @@ -582,7 +559,7 @@ func encodeSize(size int64) ([]byte, error) { func encodeID(id uint64) ([]byte, error) { var ( buf [binary.MaxVarintLen64]byte - idEncoded []byte = buf[:] + idEncoded = buf[:] ) idEncoded = idEncoded[:binary.PutUvarint(idEncoded, id)] diff --git a/vendor/github.com/containerd/containerd/snapshot/storage/metastore.go b/vendor/github.com/containerd/containerd/snapshot/storage/metastore.go index 692931a3c098b..a8d18868ce55b 100644 --- a/vendor/github.com/containerd/containerd/snapshot/storage/metastore.go +++ b/vendor/github.com/containerd/containerd/snapshot/storage/metastore.go @@ -7,6 +7,7 @@ package storage import ( "context" + "sync" "github.com/boltdb/bolt" "github.com/containerd/containerd/snapshot" @@ -46,6 +47,9 @@ type Snapshot struct { // complexities of a driver implementation. type MetaStore struct { dbfile string + + dbL sync.Mutex + db *bolt.DB } // NewMetaStore returns a snapshot MetaStore for storage of metadata related to @@ -63,22 +67,33 @@ type transactionKey struct{} // TransactionContext creates a new transaction context. The writable value // should be set to true for transactions which are expected to mutate data. func (ms *MetaStore) TransactionContext(ctx context.Context, writable bool) (context.Context, Transactor, error) { - db, err := bolt.Open(ms.dbfile, 0600, nil) - if err != nil { - return ctx, nil, errors.Wrap(err, "failed to open database file") + ms.dbL.Lock() + if ms.db == nil { + db, err := bolt.Open(ms.dbfile, 0600, nil) + if err != nil { + ms.dbL.Unlock() + return ctx, nil, errors.Wrap(err, "failed to open database file") + } + ms.db = db } + ms.dbL.Unlock() - tx, err := db.Begin(writable) + tx, err := ms.db.Begin(writable) if err != nil { return ctx, nil, errors.Wrap(err, "failed to start transaction") } - t := &boltFileTransactor{ - db: db, - tx: tx, - } + ctx = context.WithValue(ctx, transactionKey{}, tx) - ctx = context.WithValue(ctx, transactionKey{}, t) + return ctx, tx, nil +} - return ctx, t, nil +// Close closes the metastore and any underlying database connections +func (ms *MetaStore) Close() error { + ms.dbL.Lock() + defer ms.dbL.Unlock() + if ms.db == nil { + return nil + } + return ms.db.Close() } diff --git a/vendor/github.com/containerd/containerd/spec.go b/vendor/github.com/containerd/containerd/spec.go index fc1201467a212..850f470a0987b 100644 --- a/vendor/github.com/containerd/containerd/spec.go +++ b/vendor/github.com/containerd/containerd/spec.go @@ -10,7 +10,7 @@ import ( // GenerateSpec will generate a default spec from the provided image // for use as a containerd container func GenerateSpec(ctx context.Context, client *Client, c *containers.Container, opts ...SpecOpts) (*specs.Spec, error) { - s, err := createDefaultSpec() + s, err := createDefaultSpec(ctx, c.ID) if err != nil { return nil, err } diff --git a/vendor/github.com/containerd/containerd/spec_opts.go b/vendor/github.com/containerd/containerd/spec_opts.go index 811e1eebad08a..2dbf8214ab130 100644 --- a/vendor/github.com/containerd/containerd/spec_opts.go +++ b/vendor/github.com/containerd/containerd/spec_opts.go @@ -4,7 +4,7 @@ import ( "context" "github.com/containerd/containerd/containers" - "github.com/containerd/containerd/typeurl" + "github.com/containerd/typeurl" specs "github.com/opencontainers/runtime-spec/specs-go" ) @@ -19,6 +19,14 @@ func WithProcessArgs(args ...string) SpecOpts { } } +// WithProcessCwd replaces the current working directory on the generated spec +func WithProcessCwd(cwd string) SpecOpts { + return func(_ context.Context, _ *Client, _ *containers.Container, s *specs.Spec) error { + s.Process.Cwd = cwd + return nil + } +} + // WithHostname sets the container's hostname func WithHostname(name string) SpecOpts { return func(_ context.Context, _ *Client, _ *containers.Container, s *specs.Spec) error { @@ -30,7 +38,7 @@ func WithHostname(name string) SpecOpts { // WithNewSpec generates a new spec for a new container func WithNewSpec(opts ...SpecOpts) NewContainerOpts { return func(ctx context.Context, client *Client, c *containers.Container) error { - s, err := createDefaultSpec() + s, err := createDefaultSpec(ctx, c.ID) if err != nil { return err } diff --git a/vendor/github.com/containerd/containerd/spec_opts_unix.go b/vendor/github.com/containerd/containerd/spec_opts_unix.go index b529cfb878123..7009522d2224b 100644 --- a/vendor/github.com/containerd/containerd/spec_opts_unix.go +++ b/vendor/github.com/containerd/containerd/spec_opts_unix.go @@ -11,6 +11,7 @@ import ( "path/filepath" "strconv" "strings" + "time" "golang.org/x/sys/unix" @@ -20,6 +21,7 @@ import ( "github.com/containerd/containerd/images" "github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/platforms" + "github.com/containerd/containerd/snapshot" "github.com/opencontainers/image-spec/identity" "github.com/opencontainers/image-spec/specs-go/v1" "github.com/opencontainers/runc/libcontainer/user" @@ -73,7 +75,7 @@ func WithImageConfig(i Image) SpecOpts { image = i.(*image) store = client.ContentStore() ) - ic, err := image.i.Config(ctx, store, platforms.Format(platforms.Default())) + ic, err := image.i.Config(ctx, store, platforms.Default()) if err != nil { return err } @@ -138,17 +140,28 @@ func WithImageConfig(i Image) SpecOpts { } // WithRootFSPath specifies unmanaged rootfs path. -func WithRootFSPath(path string, readonly bool) SpecOpts { +func WithRootFSPath(path string) SpecOpts { return func(_ context.Context, _ *Client, _ *containers.Container, s *specs.Spec) error { - s.Root = &specs.Root{ - Path: path, - Readonly: readonly, + if s.Root == nil { + s.Root = &specs.Root{} } + s.Root.Path = path // Entrypoint is not set here (it's up to caller) return nil } } +// WithRootFSReadonly sets specs.Root.Readonly to true +func WithRootFSReadonly() SpecOpts { + return func(_ context.Context, _ *Client, _ *containers.Container, s *specs.Spec) error { + if s.Root == nil { + s.Root = &specs.Root{} + } + s.Root.Readonly = true + return nil + } +} + // WithResources sets the provided resources on the spec for task updates func WithResources(resources *specs.LinuxResources) UpdateTaskOpts { return func(ctx context.Context, client *Client, r *UpdateTaskInfo) error { @@ -236,7 +249,7 @@ func WithRemappedSnapshotView(id string, i Image, uid, gid uint32) NewContainerO func withRemappedSnapshotBase(id string, i Image, uid, gid uint32, readonly bool) NewContainerOpts { return func(ctx context.Context, client *Client, c *containers.Container) error { - diffIDs, err := i.(*image).i.RootFS(ctx, client.ContentStore(), platforms.Format(platforms.Default())) + diffIDs, err := i.(*image).i.RootFS(ctx, client.ContentStore(), platforms.Default()) if err != nil { return err } @@ -247,16 +260,19 @@ func withRemappedSnapshotBase(id string, i Image, uid, gid uint32, readonly bool snapshotter = client.SnapshotService(c.Snapshotter) parent = identity.ChainID(diffIDs).String() usernsID = fmt.Sprintf("%s-%d-%d", parent, uid, gid) + opt = snapshot.WithLabels(map[string]string{ + "containerd.io/gc.root": time.Now().UTC().Format(time.RFC3339), + }) ) if _, err := snapshotter.Stat(ctx, usernsID); err == nil { - if _, err := snapshotter.Prepare(ctx, id, usernsID); err != nil { + if _, err := snapshotter.Prepare(ctx, id, usernsID, opt); err != nil { return err } c.SnapshotKey = id c.Image = i.Name() return nil } - mounts, err := snapshotter.Prepare(ctx, usernsID+"-remap", parent) + mounts, err := snapshotter.Prepare(ctx, usernsID+"-remap", parent, opt) if err != nil { return err } @@ -264,13 +280,13 @@ func withRemappedSnapshotBase(id string, i Image, uid, gid uint32, readonly bool snapshotter.Remove(ctx, usernsID) return err } - if err := snapshotter.Commit(ctx, usernsID, usernsID+"-remap"); err != nil { + if err := snapshotter.Commit(ctx, usernsID, usernsID+"-remap", opt); err != nil { return err } if readonly { - _, err = snapshotter.View(ctx, id, usernsID) + _, err = snapshotter.View(ctx, id, usernsID, opt) } else { - _, err = snapshotter.Prepare(ctx, id, usernsID) + _, err = snapshotter.Prepare(ctx, id, usernsID, opt) } if err != nil { return err @@ -302,8 +318,8 @@ func WithNamespacedCgroup() SpecOpts { } } -// WithUidGid allows the UID and GID for the Process to be set -func WithUidGid(uid, gid uint32) SpecOpts { +// WithUIDGID allows the UID and GID for the Process to be set +func WithUIDGID(uid, gid uint32) SpecOpts { return func(_ context.Context, _ *Client, _ *containers.Container, s *specs.Spec) error { s.Process.User.UID = uid s.Process.User.GID = gid diff --git a/vendor/github.com/containerd/containerd/spec_opts_windows.go b/vendor/github.com/containerd/containerd/spec_opts_windows.go index 33aba1a9cf55d..1fc5d5e37d8df 100644 --- a/vendor/github.com/containerd/containerd/spec_opts_windows.go +++ b/vendor/github.com/containerd/containerd/spec_opts_windows.go @@ -15,13 +15,14 @@ import ( specs "github.com/opencontainers/runtime-spec/specs-go" ) +// WithImageConfig configures the spec to from the configuration of an Image func WithImageConfig(i Image) SpecOpts { return func(ctx context.Context, client *Client, _ *containers.Container, s *specs.Spec) error { var ( image = i.(*image) store = client.ContentStore() ) - ic, err := image.i.Config(ctx, store, platforms.Format(platforms.Default())) + ic, err := image.i.Config(ctx, store, platforms.Default()) if err != nil { return err } @@ -51,6 +52,8 @@ func WithImageConfig(i Image) SpecOpts { } } +// WithTTY sets the information on the spec as well as the environment variables for +// using a TTY func WithTTY(width, height int) SpecOpts { return func(_ context.Context, _ *Client, _ *containers.Container, s *specs.Spec) error { s.Process.Terminal = true @@ -63,6 +66,7 @@ func WithTTY(width, height int) SpecOpts { } } +// WithResources sets the provided resources on the spec for task updates func WithResources(resources *specs.WindowsResources) UpdateTaskOpts { return func(ctx context.Context, client *Client, r *UpdateTaskInfo) error { r.Resources = resources diff --git a/vendor/github.com/containerd/containerd/spec_unix.go b/vendor/github.com/containerd/containerd/spec_unix.go index 4d431f4201a14..9a0b537dc5fbc 100644 --- a/vendor/github.com/containerd/containerd/spec_unix.go +++ b/vendor/github.com/containerd/containerd/spec_unix.go @@ -3,6 +3,7 @@ package containerd import ( + "context" "io/ioutil" "os" "path/filepath" @@ -11,6 +12,7 @@ import ( "golang.org/x/sys/unix" "github.com/containerd/containerd/mount" + "github.com/containerd/containerd/namespaces" specs "github.com/opencontainers/runtime-spec/specs-go" ) @@ -64,7 +66,11 @@ func defaultNamespaces() []specs.LinuxNamespace { } } -func createDefaultSpec() (*specs.Spec, error) { +func createDefaultSpec(ctx context.Context, id string) (*specs.Spec, error) { + ns, err := namespaces.NamespaceRequired(ctx) + if err != nil { + return nil, err + } s := &specs.Spec{ Version: specs.Version, Root: &specs.Root{ @@ -136,7 +142,25 @@ func createDefaultSpec() (*specs.Spec, error) { }, }, Linux: &specs.Linux{ - // TODO (@crosbymichael) make sure we don't have have two containers in the same cgroup + // TODO (AkihiroSuda): unmask /sys/firmware on Windows daemon for LCOW support? + // https://github.com/moby/moby/pull/33241/files#diff-a1f5051ce84e711a2ee688ab9ded5e74R215 + MaskedPaths: []string{ + "/proc/kcore", + "/proc/latency_stats", + "/proc/timer_list", + "/proc/timer_stats", + "/proc/sched_debug", + "/sys/firmware", + }, + ReadonlyPaths: []string{ + "/proc/asound", + "/proc/bus", + "/proc/fs", + "/proc/irq", + "/proc/sys", + "/proc/sysrq-trigger", + }, + CgroupsPath: filepath.Join("/", ns, id), Resources: &specs.LinuxResources{ Devices: []specs.LinuxDeviceCgroup{ { diff --git a/vendor/github.com/containerd/containerd/spec_windows.go b/vendor/github.com/containerd/containerd/spec_windows.go index 8fa1305c92578..16a58b4468f7f 100644 --- a/vendor/github.com/containerd/containerd/spec_windows.go +++ b/vendor/github.com/containerd/containerd/spec_windows.go @@ -1,8 +1,12 @@ package containerd -import specs "github.com/opencontainers/runtime-spec/specs-go" +import ( + "context" -func createDefaultSpec() (*specs.Spec, error) { + specs "github.com/opencontainers/runtime-spec/specs-go" +) + +func createDefaultSpec(ctx context.Context, id string) (*specs.Spec, error) { return &specs.Spec{ Version: specs.Version, Root: &specs.Root{}, diff --git a/vendor/github.com/containerd/containerd/sys/oom_windows.go b/vendor/github.com/containerd/containerd/sys/oom_windows.go index a72568b279d69..6e42ddce8e4a7 100644 --- a/vendor/github.com/containerd/containerd/sys/oom_windows.go +++ b/vendor/github.com/containerd/containerd/sys/oom_windows.go @@ -1,5 +1,8 @@ package sys +// SetOOMScore sets the oom score for the process +// +// Not implemented on Windows func SetOOMScore(pid, score int) error { return nil } diff --git a/vendor/github.com/containerd/containerd/sys/prctl_solaris.go b/vendor/github.com/containerd/containerd/sys/prctl_solaris.go deleted file mode 100644 index 9443f14dbd59a..0000000000000 --- a/vendor/github.com/containerd/containerd/sys/prctl_solaris.go +++ /dev/null @@ -1,19 +0,0 @@ -// +build solaris - -package sys - -import ( - "errors" -) - -//Solaris TODO - -// GetSubreaper returns the subreaper setting for the calling process -func GetSubreaper() (int, error) { - return 0, errors.New("osutils GetSubreaper not implemented on Solaris") -} - -// SetSubreaper sets the value i as the subreaper setting for the calling process -func SetSubreaper(i int) error { - return errors.New("osutils SetSubreaper not implemented on Solaris") -} diff --git a/vendor/github.com/containerd/containerd/sys/stat_unix.go b/vendor/github.com/containerd/containerd/sys/stat_unix.go index da13ed26e260f..1f983a98dbb3f 100644 --- a/vendor/github.com/containerd/containerd/sys/stat_unix.go +++ b/vendor/github.com/containerd/containerd/sys/stat_unix.go @@ -6,14 +6,17 @@ import ( "syscall" ) +// StatAtime returns the Atim func StatAtime(st *syscall.Stat_t) syscall.Timespec { return st.Atim } +// StatCtime returns the Ctim func StatCtime(st *syscall.Stat_t) syscall.Timespec { return st.Ctim } +// StatMtime returns the Mtim func StatMtime(st *syscall.Stat_t) syscall.Timespec { return st.Mtim } diff --git a/vendor/github.com/containerd/containerd/task.go b/vendor/github.com/containerd/containerd/task.go index 6da88d374cc5b..b5f8450b362d0 100644 --- a/vendor/github.com/containerd/containerd/task.go +++ b/vendor/github.com/containerd/containerd/task.go @@ -12,18 +12,21 @@ import ( "syscall" "time" - eventsapi "github.com/containerd/containerd/api/services/events/v1" "github.com/containerd/containerd/api/services/tasks/v1" "github.com/containerd/containerd/api/types" "github.com/containerd/containerd/content" + "github.com/containerd/containerd/diff" "github.com/containerd/containerd/errdefs" + "github.com/containerd/containerd/images" + "github.com/containerd/containerd/log" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/plugin" "github.com/containerd/containerd/rootfs" - "github.com/containerd/containerd/runtime" - "github.com/containerd/containerd/typeurl" + "github.com/containerd/typeurl" + google_protobuf "github.com/gogo/protobuf/types" digest "github.com/opencontainers/go-digest" "github.com/opencontainers/image-spec/specs-go/v1" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" ) @@ -33,6 +36,11 @@ import ( // or if an error was encountered when obtaining the exit status, it is set to 255. const UnknownExitStatus = 255 +const ( + checkpointDateFormat = "01-02-2006-15:04:05" + checkpointNameFormat = "containerd.io/checkpoint/%s:%s" +) + // Status returns process status and exit information type Status struct { // Status of the process @@ -43,6 +51,16 @@ type Status struct { ExitTime time.Time } +// ProcessInfo provides platform specific process information +type ProcessInfo struct { + // Pid is the process ID + Pid uint32 + // Info includes additional process information + // Info varies by platform + Info *google_protobuf.Any +} + +// ProcessStatus returns a human readable status for the Process representing its current status type ProcessStatus string const ( @@ -77,6 +95,7 @@ func WithStdinCloser(r *IOCloseInfo) { // CheckpointTaskInfo allows specific checkpoint information to be set for the task type CheckpointTaskInfo struct { + Name string // ParentCheckpoint is the digest of a parent checkpoint ParentCheckpoint digest.Digest // Options hold runtime specific settings for checkpointing a task @@ -108,12 +127,12 @@ type Task interface { // Exec creates a new process inside the task Exec(context.Context, string, *specs.Process, IOCreation) (Process, error) // Pids returns a list of system specific process ids inside the task - Pids(context.Context) ([]uint32, error) + Pids(context.Context) ([]ProcessInfo, error) // Checkpoint serializes the runtime and memory information of a task into an // OCI Index that can be push and pulled from a remote resource. // // Additional software like CRIU maybe required to checkpoint and restore tasks - Checkpoint(context.Context, ...CheckpointTaskOpts) (v1.Descriptor, error) + Checkpoint(context.Context, ...CheckpointTaskOpts) (Image, error) // Update modifies executing tasks with updated settings Update(context.Context, ...UpdateTaskOpts) error // LoadProcess loads a previously created exec'd process @@ -135,8 +154,7 @@ type task struct { id string pid uint32 - mu sync.Mutex - deferred *tasks.CreateTaskRequest + mu sync.Mutex } // Pid returns the pid or process id for the task @@ -145,28 +163,15 @@ func (t *task) Pid() uint32 { } func (t *task) Start(ctx context.Context) error { - t.mu.Lock() - deferred := t.deferred - t.mu.Unlock() - if deferred != nil { - response, err := t.client.TaskService().Create(ctx, deferred) - t.mu.Lock() - t.deferred = nil - t.mu.Unlock() - if err != nil { - t.io.Close() - return errdefs.FromGRPC(err) - } - t.pid = response.Pid - return nil - } - _, err := t.client.TaskService().Start(ctx, &tasks.StartRequest{ + r, err := t.client.TaskService().Start(ctx, &tasks.StartRequest{ ContainerID: t.id, }) if err != nil { t.io.Close() + return errdefs.FromGRPC(err) } - return errdefs.FromGRPC(err) + t.pid = r.Pid + return nil } func (t *task) Kill(ctx context.Context, s syscall.Signal, opts ...KillOpts) error { @@ -216,60 +221,25 @@ func (t *task) Status(ctx context.Context) (Status, error) { } func (t *task) Wait(ctx context.Context) (<-chan ExitStatus, error) { - cancellable, cancel := context.WithCancel(ctx) - eventstream, err := t.client.EventService().Subscribe(cancellable, &eventsapi.SubscribeRequest{ - Filters: []string{"topic==" + runtime.TaskExitEventTopic}, - }) - if err != nil { - cancel() - return nil, errdefs.FromGRPC(err) - } - - chStatus := make(chan ExitStatus, 1) - - t.mu.Lock() - checkpoint := t.deferred != nil - t.mu.Unlock() - if !checkpoint { - // first check if the task has exited - status, err := t.Status(ctx) - if err != nil { - cancel() - return nil, errdefs.FromGRPC(err) - } - if status.Status == Stopped { - cancel() - chStatus <- ExitStatus{code: status.ExitStatus, exitedAt: status.ExitTime} - return chStatus, nil - } - } - + c := make(chan ExitStatus, 1) go func() { - defer cancel() - chStatus <- ExitStatus{} // signal that goroutine is running - for { - evt, err := eventstream.Recv() - if err != nil { - chStatus <- ExitStatus{code: UnknownExitStatus, err: errdefs.FromGRPC(err)} - return - } - if typeurl.Is(evt.Event, &eventsapi.TaskExit{}) { - v, err := typeurl.UnmarshalAny(evt.Event) - if err != nil { - chStatus <- ExitStatus{code: UnknownExitStatus, err: err} - return - } - e := v.(*eventsapi.TaskExit) - if e.ContainerID == t.id && e.Pid == t.pid { - chStatus <- ExitStatus{code: e.ExitStatus, exitedAt: e.ExitedAt} - return - } + defer close(c) + r, err := t.client.TaskService().Wait(ctx, &tasks.WaitRequest{ + ContainerID: t.id, + }) + if err != nil { + c <- ExitStatus{ + code: UnknownExitStatus, + err: err, } + return + } + c <- ExitStatus{ + code: r.ExitStatus, + exitedAt: r.ExitedAt, } }() - - <-chStatus // wait for the goroutine to be running - return chStatus, nil + return c, nil } // Delete deletes the task and its runtime state @@ -345,14 +315,21 @@ func (t *task) Exec(ctx context.Context, id string, spec *specs.Process, ioCreat }, nil } -func (t *task) Pids(ctx context.Context) ([]uint32, error) { +func (t *task) Pids(ctx context.Context) ([]ProcessInfo, error) { response, err := t.client.TaskService().ListPids(ctx, &tasks.ListPidsRequest{ ContainerID: t.id, }) if err != nil { return nil, errdefs.FromGRPC(err) } - return response.Pids, nil + var processList []ProcessInfo + for _, p := range response.Processes { + processList = append(processList, ProcessInfo{ + Pid: p.Pid, + Info: p.Info, + }) + } + return processList, nil } func (t *task) CloseIO(ctx context.Context, opts ...IOCloserOpts) error { @@ -381,46 +358,82 @@ func (t *task) Resize(ctx context.Context, w, h uint32) error { return errdefs.FromGRPC(err) } -func (t *task) Checkpoint(ctx context.Context, opts ...CheckpointTaskOpts) (d v1.Descriptor, err error) { +func (t *task) Checkpoint(ctx context.Context, opts ...CheckpointTaskOpts) (Image, error) { request := &tasks.CheckpointTaskRequest{ ContainerID: t.id, } var i CheckpointTaskInfo for _, o := range opts { if err := o(&i); err != nil { - return d, err + return nil, err } } + // set a default name + if i.Name == "" { + i.Name = fmt.Sprintf(checkpointNameFormat, t.id, time.Now().Format(checkpointDateFormat)) + } request.ParentCheckpoint = i.ParentCheckpoint if i.Options != nil { any, err := typeurl.MarshalAny(i.Options) if err != nil { - return d, err + return nil, err } request.Options = any } // make sure we pause it and resume after all other filesystem operations are completed if err := t.Pause(ctx); err != nil { - return d, err + return nil, err } defer t.Resume(ctx) cr, err := t.client.ContainerService().Get(ctx, t.id) if err != nil { - return d, err + return nil, err } - var index v1.Index + index := v1.Index{ + Annotations: make(map[string]string), + } + // make sure we clear the gc root labels reguardless of success + var clearRoots []ocispec.Descriptor + defer func() { + for _, r := range append(index.Manifests, clearRoots...) { + if err := clearRootGCLabel(ctx, t.client, r); err != nil { + log.G(ctx).WithError(err).WithField("dgst", r.Digest).Warnf("failed to remove root marker") + } + } + }() if err := t.checkpointTask(ctx, &index, request); err != nil { - return d, err + return nil, err } - if err := t.checkpointImage(ctx, &index, cr.Image); err != nil { - return d, err + if cr.Image != "" { + if err := t.checkpointImage(ctx, &index, cr.Image); err != nil { + return nil, err + } + index.Annotations["image.name"] = cr.Image } - if err := t.checkpointRWSnapshot(ctx, &index, cr.Snapshotter, cr.SnapshotKey); err != nil { - return d, err + if cr.SnapshotKey != "" { + if err := t.checkpointRWSnapshot(ctx, &index, cr.Snapshotter, cr.SnapshotKey); err != nil { + return nil, err + } } - index.Annotations = make(map[string]string) - index.Annotations["image.name"] = cr.Image - return t.writeIndex(ctx, &index) + desc, err := t.writeIndex(ctx, &index) + if err != nil { + return nil, err + } + clearRoots = append(clearRoots, desc) + im := images.Image{ + Name: i.Name, + Target: desc, + Labels: map[string]string{ + "containerd.io/checkpoint": "true", + }, + } + if im, err = t.client.ImageService().Create(ctx, im); err != nil { + return nil, err + } + return &image{ + client: t.client, + i: im, + }, nil } // UpdateTaskInfo allows updated specific settings to be changed on a task @@ -487,6 +500,15 @@ func (t *task) Metrics(ctx context.Context) (*types.Metric, error) { if err != nil { return nil, errdefs.FromGRPC(err) } + + if response.Metrics == nil { + _, err := t.Status(ctx) + if err != nil && errdefs.IsNotFound(err) { + return nil, err + } + return nil, errors.New("no metrics received") + } + return response.Metrics[0], nil } @@ -511,7 +533,13 @@ func (t *task) checkpointTask(ctx context.Context, index *v1.Index, request *tas } func (t *task) checkpointRWSnapshot(ctx context.Context, index *v1.Index, snapshotterName string, id string) error { - rw, err := rootfs.Diff(ctx, id, fmt.Sprintf("checkpoint-rw-%s", id), t.client.SnapshotService(snapshotterName), t.client.DiffService()) + opts := []diff.Opt{ + diff.WithReference(fmt.Sprintf("checkpoint-rw-%s", id)), + diff.WithLabels(map[string]string{ + "containerd.io/gc.root": time.Now().UTC().Format(time.RFC3339), + }), + } + rw, err := rootfs.Diff(ctx, id, t.client.SnapshotService(snapshotterName), t.client.DiffService(), opts...) if err != nil { return err } @@ -535,15 +563,21 @@ func (t *task) checkpointImage(ctx context.Context, index *v1.Index, image strin return nil } -func (t *task) writeIndex(ctx context.Context, index *v1.Index) (v1.Descriptor, error) { +func (t *task) writeIndex(ctx context.Context, index *v1.Index) (d v1.Descriptor, err error) { + labels := map[string]string{ + "containerd.io/gc.root": time.Now().UTC().Format(time.RFC3339), + } + for i, m := range index.Manifests { + labels[fmt.Sprintf("containerd.io/gc.ref.content.%d", i)] = m.Digest.String() + } buf := bytes.NewBuffer(nil) if err := json.NewEncoder(buf).Encode(index); err != nil { return v1.Descriptor{}, err } - return writeContent(ctx, t.client.ContentStore(), v1.MediaTypeImageIndex, t.id, buf) + return writeContent(ctx, t.client.ContentStore(), v1.MediaTypeImageIndex, t.id, buf, content.WithLabels(labels)) } -func writeContent(ctx context.Context, store content.Store, mediaType, ref string, r io.Reader) (d v1.Descriptor, err error) { +func writeContent(ctx context.Context, store content.Store, mediaType, ref string, r io.Reader, opts ...content.Opt) (d v1.Descriptor, err error) { writer, err := store.Writer(ctx, ref, 0, "") if err != nil { return d, err @@ -553,7 +587,7 @@ func writeContent(ctx context.Context, store content.Store, mediaType, ref strin if err != nil { return d, err } - if err := writer.Commit(ctx, size, ""); err != nil { + if err := writer.Commit(ctx, size, "", opts...); err != nil { return d, err } return v1.Descriptor{ @@ -562,3 +596,9 @@ func writeContent(ctx context.Context, store content.Store, mediaType, ref strin Size: size, }, nil } + +func clearRootGCLabel(ctx context.Context, client *Client, desc ocispec.Descriptor) error { + info := content.Info{Digest: desc.Digest} + _, err := client.ContentStore().Update(ctx, info, "labels.containerd.io/gc.root") + return err +} diff --git a/vendor/github.com/containerd/containerd/task_opts.go b/vendor/github.com/containerd/containerd/task_opts.go index 36bbfab946a42..261ccba64b137 100644 --- a/vendor/github.com/containerd/containerd/task_opts.go +++ b/vendor/github.com/containerd/containerd/task_opts.go @@ -28,6 +28,14 @@ func WithExit(r *CheckpointTaskInfo) error { return nil } +// WithCheckpointName sets the image name for the checkpoint +func WithCheckpointName(name string) CheckpointTaskOpts { + return func(r *CheckpointTaskInfo) error { + r.Name = name + return nil + } +} + // ProcessDeleteOpts allows the caller to set options for the deletion of a task type ProcessDeleteOpts func(context.Context, Process) error @@ -52,12 +60,14 @@ func WithProcessKill(ctx context.Context, p Process) error { return nil } +// KillInfo contains information on how to process a Kill action type KillInfo struct { // All kills all processes inside the task // only valid on tasks, ignored on processes All bool } +// KillOpts allows options to be set for the killing of a process type KillOpts func(context.Context, Process, *KillInfo) error // WithKillAll kills all processes for a task diff --git a/vendor/github.com/containerd/containerd/vendor.conf b/vendor/github.com/containerd/containerd/vendor.conf index 1698fbe70b158..671346821c622 100644 --- a/vendor/github.com/containerd/containerd/vendor.conf +++ b/vendor/github.com/containerd/containerd/vendor.conf @@ -1,7 +1,8 @@ github.com/coreos/go-systemd 48702e0da86bd25e76cfef347e2adeb434a0d0a6 -github.com/containerd/go-runc b3c048c028ddd789c6f9510c597f8b9c62f25359 -github.com/containerd/console 76d18fd1d66972718ab2284449591db0b3cdb4de -github.com/containerd/cgroups 5933ab4dc4f7caa3a73a1dc141bd11f42b5c9163 +github.com/containerd/go-runc ed1cbe1fc31f5fb2359d3a54b6330d1a097858b7 +github.com/containerd/console 84eeaae905fa414d03e07bcd6c8d3f19e7cf180e +github.com/containerd/cgroups f7dd103d3e4e696aa67152f6b4ddd1779a3455a9 +github.com/containerd/typeurl f6943554a7e7e88b3c14aad190bf05932da84788 github.com/docker/go-metrics 8fd5772bf1584597834c6f7961a530f06cbfbb87 github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9 github.com/godbus/dbus c7fdd8b5cd55e87b4e1f4e372cdb1db61dd6c66f @@ -15,19 +16,19 @@ github.com/docker/go-units v0.3.1 github.com/gogo/protobuf d2e1ade2d719b78fe5b061b4c18a9f7111b5bdc8 github.com/golang/protobuf 5a0f697c9ed9d68fef0116532c6e05cfeae00e55 github.com/opencontainers/runtime-spec v1.0.0 -github.com/opencontainers/runc 593914b8bd5448a93f7c3e4902a03408b6d5c0ce +github.com/opencontainers/runc 74a17296470088de3805e138d3d87c62e613dfc4 github.com/sirupsen/logrus v1.0.0 github.com/containerd/btrfs cc52c4dea2ce11a44e6639e561bb5c2af9ada9e3 github.com/stretchr/testify v1.1.4 github.com/davecgh/go-spew v1.1.0 github.com/pmezard/go-difflib v1.0.0 github.com/containerd/fifo fbfb6a11ec671efbe94ad1c12c2e98773f19e1e6 -github.com/urfave/cli 8ba6f23b6e36d03666a14bd9421f5e3efcb59aca +github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c golang.org/x/net 7dcfb8076726a3fdd9353b6b8a1f1b6be6811bd6 google.golang.org/grpc v1.3.0 github.com/pkg/errors v0.8.0 github.com/opencontainers/go-digest 21dfd564fd89c944783d00d069f33e3e7123c448 -golang.org/x/sys 7ddbeae9ae08c6a06a59597f0c9edbc5ff2444ce https://github.com/golang/sys +golang.org/x/sys 314a259e304ff91bd6985da2a7149bbf91237993 https://github.com/golang/sys github.com/opencontainers/image-spec v1.0.0 github.com/containerd/continuity cf279e6ac893682272b4479d4c67fd3abf878b4e golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c @@ -37,7 +38,6 @@ github.com/Microsoft/go-winio v0.4.4 github.com/Microsoft/hcsshim v0.6.3 github.com/Microsoft/opengcs v0.3.2 github.com/boltdb/bolt e9cf4fae01b5a8ff89d0ec6b32f0d9c9f79aefdd -github.com/Azure/go-ansiterm 19f72df4d05d31cbe1c56bfc8045c96babff6c7e google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944 golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4 github.com/dmcgowan/go-tar 2e2c51242e8993c50445dab7c03c8e7febddd0cf diff --git a/vendor/github.com/containerd/typeurl/LICENSE b/vendor/github.com/containerd/typeurl/LICENSE new file mode 100644 index 0000000000000..261eeb9e9f8b2 --- /dev/null +++ b/vendor/github.com/containerd/typeurl/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/containerd/typeurl/README.md b/vendor/github.com/containerd/typeurl/README.md new file mode 100644 index 0000000000000..e0787743c5dad --- /dev/null +++ b/vendor/github.com/containerd/typeurl/README.md @@ -0,0 +1,9 @@ +# typeurl + +[![Build Status](https://travis-ci.org/containerd/typeurl.svg?branch=master)](https://travis-ci.org/containerd/typeurl) + +[![codecov](https://codecov.io/gh/containerd/typeurl/branch/master/graph/badge.svg)](https://codecov.io/gh/containerd/typeurl) + +A Go package for managing the registration, marshaling, and unmarshaling of encoded types. + +This package helps when types are sent over a GRPC API and marshaled as a [protobuf.Any](). diff --git a/vendor/github.com/containerd/containerd/typeurl/types.go b/vendor/github.com/containerd/typeurl/types.go similarity index 86% rename from vendor/github.com/containerd/containerd/typeurl/types.go rename to vendor/github.com/containerd/typeurl/types.go index 63b214b5e2438..10a78228ba358 100644 --- a/vendor/github.com/containerd/containerd/typeurl/types.go +++ b/vendor/github.com/containerd/typeurl/types.go @@ -4,27 +4,25 @@ import ( "encoding/json" "path" "reflect" - "strings" "sync" - "github.com/containerd/containerd/errdefs" "github.com/gogo/protobuf/proto" "github.com/gogo/protobuf/types" "github.com/pkg/errors" ) -const Prefix = "types.containerd.io" - var ( mu sync.Mutex registry = make(map[reflect.Type]string) ) +var ErrNotFound = errors.New("not found") + // Register a type with the base url of the type func Register(v interface{}, args ...string) { var ( t = tryDereference(v) - p = path.Join(append([]string{Prefix}, args...)...) + p = path.Join(args...) ) mu.Lock() defer mu.Unlock() @@ -46,9 +44,9 @@ func TypeURL(v interface{}) (string, error) { // fallback to the proto registry if it is a proto message pb, ok := v.(proto.Message) if !ok { - return "", errors.Wrapf(errdefs.ErrNotFound, "type %s", reflect.TypeOf(v)) + return "", errors.Wrapf(ErrNotFound, "type %s", reflect.TypeOf(v)) } - return path.Join(Prefix, proto.MessageName(pb)), nil + return proto.MessageName(pb), nil } return u, nil } @@ -123,7 +121,7 @@ func getTypeByUrl(url string) (urlType, error) { } } // fallback to proto registry - t := proto.MessageType(strings.TrimPrefix(url, Prefix+"/")) + t := proto.MessageType(url) if t != nil { return urlType{ // get the underlying Elem because proto returns a pointer to the type @@ -131,7 +129,7 @@ func getTypeByUrl(url string) (urlType, error) { isProto: true, }, nil } - return urlType{}, errors.Wrapf(errdefs.ErrNotFound, "type with url %s", url) + return urlType{}, errors.Wrapf(ErrNotFound, "type with url %s", url) } func tryDereference(v interface{}) reflect.Type { diff --git a/worker/containerdworker/worker.go b/worker/containerdworker/worker.go index 76cbe4c903b2e..ffb24242a7e57 100644 --- a/worker/containerdworker/worker.go +++ b/worker/containerdworker/worker.go @@ -25,7 +25,7 @@ func New(client *containerd.Client) worker.Worker { func (w containerdWorker) Exec(ctx context.Context, meta worker.Meta, root cache.Mountable, mounts []worker.Mount, stdin io.ReadCloser, stdout, stderr io.WriteCloser) error { id := identity.NewID() - spec, cleanup, err := oci.GenerateSpec(ctx, meta, mounts) + spec, cleanup, err := oci.GenerateSpec(ctx, meta, mounts, id) if err != nil { return err } diff --git a/worker/oci/spec_unix.go b/worker/oci/spec_unix.go index 00ddb6a567c9f..9b7316ec2ac12 100644 --- a/worker/oci/spec_unix.go +++ b/worker/oci/spec_unix.go @@ -8,7 +8,9 @@ import ( "sync" "github.com/containerd/containerd" + "github.com/containerd/containerd/containers" "github.com/containerd/containerd/mount" + "github.com/containerd/containerd/namespaces" "github.com/mitchellh/hashstructure" "github.com/moby/buildkit/snapshot" "github.com/moby/buildkit/worker" @@ -18,8 +20,17 @@ import ( // Ideally we don't have to import whole containerd just for the default spec -func GenerateSpec(ctx context.Context, meta worker.Meta, mounts []worker.Mount) (*specs.Spec, func(), error) { - s, err := containerd.GenerateSpec(ctx, nil, nil, +// GenerateSpec generates spec using containerd functionality. +func GenerateSpec(ctx context.Context, meta worker.Meta, mounts []worker.Mount, id string) (*specs.Spec, func(), error) { + c := &containers.Container{ + ID: id, + } + _, ok := namespaces.Namespace(ctx) + if !ok { + ctx = namespaces.WithNamespace(ctx, "buildkit") + } + // Note that containerd.GenerateSpec is namespaced + s, err := containerd.GenerateSpec(ctx, nil, c, containerd.WithHostNamespace(specs.NetworkNamespace), containerd.WithHostResolvconf, containerd.WithHostHostsFile, diff --git a/worker/runcworker/worker.go b/worker/runcworker/worker.go index 7db889b966a95..962fb8f0fa3be 100644 --- a/worker/runcworker/worker.go +++ b/worker/runcworker/worker.go @@ -77,13 +77,13 @@ func (w *runcworker) Exec(ctx context.Context, meta worker.Meta, root cache.Moun return err } defer f.Close() - spec, cleanup, err := oci.GenerateSpec(ctx, meta, mounts) + spec, cleanup, err := oci.GenerateSpec(ctx, meta, mounts, id) if err != nil { return err } defer cleanup() - if err := mount.MountAll(rootMount, rootFSPath); err != nil { + if err := mount.All(rootMount, rootFSPath); err != nil { return err } defer mount.Unmount(rootFSPath, 0)