bump up containerd (v1.0.0-beta.3)
Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>docker-18.09
parent
2898b24cab
commit
c71a1ca768
|
@ -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/v1.0.0-beta.3/RUNC.md) for more information.
|
||||
|
||||
|
||||
#### Contributing
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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.RFC3339Nano),
|
||||
"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
|
||||
|
|
|
@ -33,7 +33,9 @@ func TestChecksumBasicFile(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
cm := setupCacheManager(t, tmpdir)
|
||||
snapshotter, err := naive.NewSnapshotter(filepath.Join(tmpdir, "snapshots"))
|
||||
require.NoError(t, err)
|
||||
cm := setupCacheManager(t, tmpdir, snapshotter)
|
||||
defer cm.Close()
|
||||
|
||||
ch := []string{
|
||||
|
@ -180,7 +182,9 @@ func TestHandleChange(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
cm := setupCacheManager(t, tmpdir)
|
||||
snapshotter, err := naive.NewSnapshotter(filepath.Join(tmpdir, "snapshots"))
|
||||
require.NoError(t, err)
|
||||
cm := setupCacheManager(t, tmpdir, snapshotter)
|
||||
defer cm.Close()
|
||||
|
||||
ch := []string{
|
||||
|
@ -255,7 +259,9 @@ func TestPersistence(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
cm := setupCacheManager(t, tmpdir)
|
||||
snapshotter, err := naive.NewSnapshotter(filepath.Join(tmpdir, "snapshots"))
|
||||
require.NoError(t, err)
|
||||
cm := setupCacheManager(t, tmpdir, snapshotter)
|
||||
defer cm.Close()
|
||||
|
||||
ch := []string{
|
||||
|
@ -289,9 +295,10 @@ func TestPersistence(t *testing.T) {
|
|||
|
||||
time.Sleep(100 * time.Millisecond) // saving happens on the background
|
||||
|
||||
// we can't close snapshotter and open it twice (especially, its internal boltdb store)
|
||||
cm.Close()
|
||||
getDefaultManager().lru.Purge()
|
||||
cm = setupCacheManager(t, tmpdir)
|
||||
cm = setupCacheManager(t, tmpdir, snapshotter)
|
||||
defer cm.Close()
|
||||
|
||||
ref, err = cm.Get(context.TODO(), id)
|
||||
|
@ -324,10 +331,7 @@ func createRef(t *testing.T, cm cache.Manager, files []string) cache.ImmutableRe
|
|||
return ref
|
||||
}
|
||||
|
||||
func setupCacheManager(t *testing.T, tmpdir string) cache.Manager {
|
||||
snapshotter, err := naive.NewSnapshotter(filepath.Join(tmpdir, "snapshots"))
|
||||
require.NoError(t, err)
|
||||
|
||||
func setupCacheManager(t *testing.T, tmpdir string, snapshotter snapshot.Snapshotter) cache.Manager {
|
||||
md, err := metadata.NewStore(filepath.Join(tmpdir, "metadata.db"))
|
||||
require.NoError(t, err)
|
||||
|
||||
|
|
|
@ -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.RFC3339Nano),
|
||||
}
|
||||
if _, err := cm.Snapshotter.Prepare(ctx, id, parentID, cdsnapshot.WithLabels(labels)); err != nil {
|
||||
if parent != nil {
|
||||
parent.Release(context.TODO())
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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.RFC3339Nano),
|
||||
}
|
||||
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())
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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", "v1.0.0-beta.3", "containerd version")
|
||||
flag.StringVar(&opt.runc, "runc", "74a17296470088de3805e138d3d87c62e613dfc4", "runc version")
|
||||
flag.Parse()
|
||||
|
||||
bk := buildkit(opt)
|
||||
|
|
|
@ -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", "v1.0.0-beta.3", "containerd version")
|
||||
flag.StringVar(&opt.runc, "runc", "74a17296470088de3805e138d3d87c62e613dfc4", "runc version")
|
||||
flag.Parse()
|
||||
|
||||
bk := buildkit(opt)
|
||||
|
|
|
@ -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", "v1.0.0-beta.3", "containerd version")
|
||||
flag.StringVar(&opt.runc, "runc", "74a17296470088de3805e138d3d87c62e613dfc4", "runc version")
|
||||
flag.Parse()
|
||||
|
||||
bk := buildkit(opt)
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
ARG RUNC_VERSION=e775f0fba3ea329b8b766451c892c41a3d49594d
|
||||
ARG CONTAINERD_VERSION=d1e11f17ec7b325f89608dd46c128300b8727d50
|
||||
ARG RUNC_VERSION=74a17296470088de3805e138d3d87c62e613dfc4
|
||||
ARG CONTAINERD_VERSION=v1.0.0-beta.3
|
||||
ARG BUILDKIT_TARGET=standalone
|
||||
|
||||
FROM golang:1.9-alpine AS gobuild-base
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -195,7 +196,7 @@ func (p *puller) Snapshot(ctx context.Context) (cache.ImmutableRef, error) {
|
|||
return nil, nil
|
||||
}),
|
||||
remotes.FetchHandler(p.is.ContentStore, fetcher),
|
||||
images.ChildrenHandler(p.is.ContentStore),
|
||||
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.RFC3339Nano),
|
||||
"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")
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ func Config(ctx context.Context, str string, resolver remotes.Resolver, 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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 v1.0.0-beta.3
|
||||
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
|
||||
github.com/docker/docker-credential-helpers d68f9aeca33f5fd3f08eeae5e9d175edf4e731d1
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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/.
|
||||
|
|
304
vendor/github.com/containerd/containerd/api/services/containers/v1/containers.pb.go
generated
vendored
304
vendor/github.com/containerd/containerd/api/services/containers/v1/containers.pb.go
generated
vendored
|
@ -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,
|
||||
}
|
||||
|
|
13
vendor/github.com/containerd/containerd/api/services/containers/v1/containers.proto
generated
vendored
13
vendor/github.com/containerd/containerd/api/services/containers/v1/containers.proto
generated
vendored
|
@ -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<string, string> 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<string, google.protobuf.Any> extensions = 10 [(gogoproto.nullable) = false];
|
||||
}
|
||||
|
||||
message GetContainerRequest {
|
||||
|
|
|
@ -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"`
|
||||
}
|
||||
|
||||
|
|
|
@ -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<string, string> 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<string, string> labels = 7;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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<string, string> labels = 5;
|
||||
}
|
||||
|
||||
message DiffResponse {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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"`
|
||||
|
|
|
@ -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<string, string> labels = 2;
|
||||
|
||||
// Target describes the content entry point of the image.
|
||||
|
|
1
vendor/github.com/containerd/containerd/api/services/introspection/v1/doc.go
generated
vendored
Normal file
1
vendor/github.com/containerd/containerd/api/services/introspection/v1/doc.go
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
package introspection
|
1175
vendor/github.com/containerd/containerd/api/services/introspection/v1/introspection.pb.go
generated
vendored
Normal file
1175
vendor/github.com/containerd/containerd/api/services/introspection/v1/introspection.pb.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
81
vendor/github.com/containerd/containerd/api/services/introspection/v1/introspection.proto
generated
vendored
Normal file
81
vendor/github.com/containerd/containerd/api/services/introspection/v1/introspection.proto
generated
vendored
Normal file
|
@ -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<string, string> 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];
|
||||
}
|
1
vendor/github.com/containerd/containerd/api/services/leases/v1/doc.go
generated
vendored
Normal file
1
vendor/github.com/containerd/containerd/api/services/leases/v1/doc.go
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
package leases
|
1573
vendor/github.com/containerd/containerd/api/services/leases/v1/leases.pb.go
generated
vendored
Normal file
1573
vendor/github.com/containerd/containerd/api/services/leases/v1/leases.pb.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
58
vendor/github.com/containerd/containerd/api/services/leases/v1/leases.proto
generated
vendored
Normal file
58
vendor/github.com/containerd/containerd/api/services/leases/v1/leases.proto
generated
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package containerd.services.leases.v1;
|
||||
|
||||
import "gogoproto/gogo.proto";
|
||||
import "google/protobuf/empty.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
|
||||
option go_package = "github.com/containerd/containerd/api/services/leases/v1;leases";
|
||||
|
||||
// Leases service manages resources leases within the metadata store.
|
||||
service Leases {
|
||||
// Create creates a new lease for managing changes to metadata. A lease
|
||||
// can be used to protect objects from being removed.
|
||||
rpc Create(CreateRequest) returns (CreateResponse);
|
||||
|
||||
// Delete deletes the lease and makes any unreferenced objects created
|
||||
// during the lease eligible for garbage collection if not referenced
|
||||
// or retained by other resources during the lease.
|
||||
rpc Delete(DeleteRequest) returns (google.protobuf.Empty);
|
||||
|
||||
// ListTransactions lists all active leases, returning the full list of
|
||||
// leases and optionally including the referenced resources.
|
||||
rpc List(ListRequest) returns (ListResponse);
|
||||
}
|
||||
|
||||
// Lease is an object which retains resources while it exists.
|
||||
message Lease {
|
||||
string id = 1;
|
||||
|
||||
google.protobuf.Timestamp created_at = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
|
||||
|
||||
map<string, string> labels = 3;
|
||||
}
|
||||
|
||||
message CreateRequest {
|
||||
// ID is used to identity the lease, when the id is not set the service
|
||||
// generates a random identifier for the lease.
|
||||
string id = 1;
|
||||
|
||||
map<string, string> labels = 3;
|
||||
}
|
||||
|
||||
message CreateResponse {
|
||||
Lease lease = 1;
|
||||
}
|
||||
|
||||
message DeleteRequest {
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
message ListRequest {
|
||||
repeated string filters = 1;
|
||||
}
|
||||
|
||||
message ListResponse {
|
||||
repeated Lease leases = 1;
|
||||
}
|
2
vendor/github.com/containerd/containerd/api/services/namespaces/v1/namespace.pb.go
generated
vendored
2
vendor/github.com/containerd/containerd/api/services/namespaces/v1/namespace.pb.go
generated
vendored
|
@ -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"`
|
||||
|
|
2
vendor/github.com/containerd/containerd/api/services/namespaces/v1/namespace.proto
generated
vendored
2
vendor/github.com/containerd/containerd/api/services/namespaces/v1/namespace.proto
generated
vendored
|
@ -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<string, string> labels = 2;
|
||||
|
|
8
vendor/github.com/containerd/containerd/api/services/snapshot/v1/snapshots.pb.go
generated
vendored
8
vendor/github.com/containerd/containerd/api/services/snapshot/v1/snapshots.pb.go
generated
vendored
|
@ -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"`
|
||||
}
|
||||
|
||||
|
|
8
vendor/github.com/containerd/containerd/api/services/snapshot/v1/snapshots.proto
generated
vendored
8
vendor/github.com/containerd/containerd/api/services/snapshot/v1/snapshots.proto
generated
vendored
|
@ -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<string, string> 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<string, string> 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<string, string> 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<string, string> labels = 6;
|
||||
}
|
||||
|
||||
|
|
|
@ -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++
|
||||
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
|
||||
}
|
||||
dAtA7[j6] = uint8(num)
|
||||
j6++
|
||||
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
|
||||
}
|
||||
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
|
||||
}
|
||||
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
|
||||
}
|
||||
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,
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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,
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 nil
|
||||
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
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -15,26 +15,31 @@ 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/dialer"
|
||||
"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 +49,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
|
||||
|
@ -67,7 +73,7 @@ func New(address string, opts ...ClientOpt) (*Client, error) {
|
|||
grpc.WithTimeout(60 * time.Second),
|
||||
grpc.FailOnNonTempDialError(true),
|
||||
grpc.WithBackoffMaxDelay(3 * time.Second),
|
||||
grpc.WithDialer(Dialer),
|
||||
grpc.WithDialer(dialer.Dialer),
|
||||
}
|
||||
if len(copts.dialOptions) > 0 {
|
||||
gopts = copts.dialOptions
|
||||
|
@ -79,7 +85,7 @@ func New(address string, opts ...ClientOpt) (*Client, error) {
|
|||
grpc.WithStreamInterceptor(stream),
|
||||
)
|
||||
}
|
||||
conn, err := grpc.Dial(DialAddress(address), gopts...)
|
||||
conn, err := grpc.Dial(dialer.DialAddress(address), gopts...)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to dial %q", address)
|
||||
}
|
||||
|
@ -98,10 +104,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
|
||||
|
@ -134,6 +138,12 @@ func (c *Client) Containers(ctx context.Context, filters ...string) ([]Container
|
|||
// NewContainer will create a new container in container with the provided id
|
||||
// the id must be unique within the namespace
|
||||
func (c *Client) NewContainer(ctx context.Context, id string, opts ...NewContainerOpts) (Container, error) {
|
||||
ctx, done, err := c.withLease(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer done()
|
||||
|
||||
container := containers.Container{
|
||||
ID: id,
|
||||
Runtime: containers.RuntimeInfo{
|
||||
|
@ -176,6 +186,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 +210,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 {
|
||||
|
@ -206,6 +219,12 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpts) (Imag
|
|||
}
|
||||
store := c.ContentStore()
|
||||
|
||||
ctx, done, err := c.withLease(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer done()
|
||||
|
||||
name, desc, err := pullCtx.Resolver.Resolve(ctx, ref)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -225,7 +244,7 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpts) (Imag
|
|||
} else {
|
||||
handler = images.Handlers(append(pullCtx.BaseHandlers,
|
||||
remotes.FetchHandler(store, fetcher),
|
||||
images.ChildrenHandler(store))...,
|
||||
images.ChildrenHandler(store, platforms.Default()))...,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -242,22 +261,23 @@ 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
|
||||
}
|
||||
|
||||
img := &image{
|
||||
|
@ -273,7 +293,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 +316,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 +326,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 +358,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 +424,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 +508,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 {
|
||||
|
@ -529,6 +591,13 @@ func (c *Client) Import(ctx context.Context, ref string, reader io.Reader, opts
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx, done, err := c.withLease(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer done()
|
||||
|
||||
switch iopts.format {
|
||||
case ociImageFormat:
|
||||
return c.importFromOCITar(ctx, ref, reader, iopts)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
i, err := c.client.ImageService().Get(ctx, c.c.Image)
|
||||
r, err := c.get(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to get image for container")
|
||||
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, r.Image)
|
||||
if err != nil {
|
||||
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{
|
||||
|
|
|
@ -6,15 +6,21 @@ import (
|
|||
"github.com/containerd/containerd/containers"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/containerd/containerd/typeurl"
|
||||
"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 +86,13 @@ 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 {
|
||||
parent := identity.ChainID(diffIDs).String()
|
||||
if _, err := client.SnapshotService(c.Snapshotter).Prepare(ctx, id, parent); err != nil {
|
||||
return err
|
||||
}
|
||||
c.SnapshotKey = id
|
||||
|
@ -109,12 +116,13 @@ 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 {
|
||||
parent := identity.ChainID(diffIDs).String()
|
||||
if _, err := client.SnapshotService(c.Snapshotter).View(ctx, id, parent); err != nil {
|
||||
return err
|
||||
}
|
||||
c.SnapshotKey = id
|
||||
|
@ -128,3 +136,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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
package containerd
|
||||
package dialer
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
|
@ -1,15 +1,22 @@
|
|||
// +build !windows
|
||||
|
||||
package containerd
|
||||
package dialer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
// DialAddress returns the address with unix:// prepended to the
|
||||
// provided address
|
||||
func DialAddress(address string) string {
|
||||
return fmt.Sprintf("unix://%s", address)
|
||||
}
|
||||
|
||||
func isNoent(err error) bool {
|
||||
if err != nil {
|
||||
if nerr, ok := err.(*net.OpError); ok {
|
||||
|
@ -24,9 +31,6 @@ 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)
|
||||
}
|
||||
|
||||
func DialAddress(address string) string {
|
||||
return fmt.Sprintf("unix://%s", address)
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package containerd
|
||||
package dialer
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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[:]))
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -1,27 +1,30 @@
|
|||
package events
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
events "github.com/containerd/containerd/api/services/events/v1"
|
||||
v1 "github.com/containerd/containerd/api/services/events/v1"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/events"
|
||||
"github.com/containerd/containerd/filters"
|
||||
"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(),
|
||||
|
@ -32,7 +35,7 @@ func NewExchange() *Exchange {
|
|||
//
|
||||
// This is useful when an event is forwaded on behalf of another namespace or
|
||||
// when the event is propagated on behalf of another publisher.
|
||||
func (e *Exchange) Forward(ctx context.Context, envelope *events.Envelope) (err error) {
|
||||
func (e *Exchange) Forward(ctx context.Context, envelope *v1.Envelope) (err error) {
|
||||
if err := validateEnvelope(envelope); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -57,11 +60,11 @@ func (e *Exchange) Forward(ctx context.Context, envelope *events.Envelope) (err
|
|||
// Publish packages and sends an event. The caller will be considered the
|
||||
// initial publisher of the event. This means the timestamp will be calculated
|
||||
// at this point and this method may read from the calling context.
|
||||
func (e *Exchange) Publish(ctx context.Context, topic string, event Event) (err error) {
|
||||
func (e *Exchange) Publish(ctx context.Context, topic string, event events.Event) (err error) {
|
||||
var (
|
||||
namespace string
|
||||
encoded *types.Any
|
||||
envelope events.Envelope
|
||||
envelope v1.Envelope
|
||||
)
|
||||
|
||||
namespace, err = namespaces.NamespaceRequired(ctx)
|
||||
|
@ -106,9 +109,9 @@ func (e *Exchange) Publish(ctx context.Context, topic string, event Event) (err
|
|||
// Zero or more filters may be provided as strings. Only events that match
|
||||
// *any* of the provided filters will be sent on the channel. The filters use
|
||||
// the standard containerd filters package syntax.
|
||||
func (e *Exchange) Subscribe(ctx context.Context, fs ...string) (ch <-chan *events.Envelope, errs <-chan error) {
|
||||
func (e *Exchange) Subscribe(ctx context.Context, fs ...string) (ch <-chan *v1.Envelope, errs <-chan error) {
|
||||
var (
|
||||
evch = make(chan *events.Envelope)
|
||||
evch = make(chan *v1.Envelope)
|
||||
errq = make(chan error, 1)
|
||||
channel = goevents.NewChannel(0)
|
||||
queue = goevents.NewQueue(channel)
|
||||
|
@ -148,7 +151,7 @@ func (e *Exchange) Subscribe(ctx context.Context, fs ...string) (ch <-chan *even
|
|||
for {
|
||||
select {
|
||||
case ev := <-channel.C:
|
||||
env, ok := ev.(*events.Envelope)
|
||||
env, ok := ev.(*v1.Envelope)
|
||||
if !ok {
|
||||
// TODO(stevvooe): For the most part, we are well protected
|
||||
// from this condition. Both Forward and Publish protect
|
||||
|
@ -202,7 +205,7 @@ func validateTopic(topic string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func validateEnvelope(envelope *events.Envelope) error {
|
||||
func validateEnvelope(envelope *v1.Envelope) error {
|
||||
if err := namespaces.Validate(envelope.Namespace); err != nil {
|
||||
return errors.Wrapf(err, "event envelope has invalid namespace")
|
||||
}
|
|
@ -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),
|
||||
)
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package fs
|
||||
|
||||
// Usage of disk information
|
||||
type Usage struct {
|
||||
Inodes int64
|
||||
Size int64
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -2,11 +2,16 @@ package containerd
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"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 +30,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 +52,85 @@ 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)
|
||||
if err != nil {
|
||||
// TODO: possibly wait and retry if extraction of same chain id was in progress
|
||||
return err
|
||||
labels := map[string]string{
|
||||
"containerd.io/uncompressed": layer.Diff.Digest.String(),
|
||||
}
|
||||
if unpacked {
|
||||
info, err := cs.Info(ctx, layer.Blob.Digest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
unpacked, err = rootfs.ApplyLayer(ctx, layer, chain, sn, a, snapshot.WithLabels(labels))
|
||||
if 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
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
package containerd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
leasesapi "github.com/containerd/containerd/api/services/leases/v1"
|
||||
"github.com/containerd/containerd/leases"
|
||||
)
|
||||
|
||||
// Lease is used to hold a reference to active resources which have not been
|
||||
// referenced by a root resource. This is useful for preventing garbage
|
||||
// collection of resources while they are actively being updated.
|
||||
type Lease struct {
|
||||
id string
|
||||
createdAt time.Time
|
||||
|
||||
client *Client
|
||||
}
|
||||
|
||||
// CreateLease creates a new lease
|
||||
func (c *Client) CreateLease(ctx context.Context) (Lease, error) {
|
||||
lapi := leasesapi.NewLeasesClient(c.conn)
|
||||
resp, err := lapi.Create(ctx, &leasesapi.CreateRequest{})
|
||||
if err != nil {
|
||||
return Lease{}, err
|
||||
}
|
||||
|
||||
return Lease{
|
||||
id: resp.Lease.ID,
|
||||
client: c,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ListLeases lists active leases
|
||||
func (c *Client) ListLeases(ctx context.Context) ([]Lease, error) {
|
||||
lapi := leasesapi.NewLeasesClient(c.conn)
|
||||
resp, err := lapi.List(ctx, &leasesapi.ListRequest{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
leases := make([]Lease, len(resp.Leases))
|
||||
for i := range resp.Leases {
|
||||
leases[i] = Lease{
|
||||
id: resp.Leases[i].ID,
|
||||
createdAt: resp.Leases[i].CreatedAt,
|
||||
client: c,
|
||||
}
|
||||
}
|
||||
|
||||
return leases, nil
|
||||
}
|
||||
|
||||
func (c *Client) withLease(ctx context.Context) (context.Context, func() error, error) {
|
||||
_, ok := leases.Lease(ctx)
|
||||
if ok {
|
||||
return ctx, func() error {
|
||||
return nil
|
||||
}, nil
|
||||
}
|
||||
|
||||
l, err := c.CreateLease(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ctx = leases.WithLease(ctx, l.ID())
|
||||
return ctx, func() error {
|
||||
return l.Delete(ctx)
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ID returns the lease ID
|
||||
func (l Lease) ID() string {
|
||||
return l.id
|
||||
}
|
||||
|
||||
// CreatedAt returns the time at which the lease was created
|
||||
func (l Lease) CreatedAt() time.Time {
|
||||
return l.createdAt
|
||||
}
|
||||
|
||||
// Delete deletes the lease, removing the reference to all resources created
|
||||
// during the lease.
|
||||
func (l Lease) Delete(ctx context.Context) error {
|
||||
lapi := leasesapi.NewLeasesClient(l.client.conn)
|
||||
_, err := lapi.Delete(ctx, &leasesapi.DeleteRequest{
|
||||
ID: l.id,
|
||||
})
|
||||
return err
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package leases
|
||||
|
||||
import "context"
|
||||
|
||||
type leaseKey struct{}
|
||||
|
||||
// WithLease sets a given lease on the context
|
||||
func WithLease(ctx context.Context, lid string) context.Context {
|
||||
ctx = context.WithValue(ctx, leaseKey{}, lid)
|
||||
|
||||
// also store on the grpc headers so it gets picked up by any clients that
|
||||
// are using this.
|
||||
return withGRPCLeaseHeader(ctx, lid)
|
||||
}
|
||||
|
||||
// Lease returns the lease from the context.
|
||||
func Lease(ctx context.Context) (string, bool) {
|
||||
lid, ok := ctx.Value(leaseKey{}).(string)
|
||||
if !ok {
|
||||
return fromGRPCHeader(ctx)
|
||||
}
|
||||
|
||||
return lid, ok
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package leases
|
||||
|
||||
import (
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc/metadata"
|
||||
)
|
||||
|
||||
const (
|
||||
// GRPCHeader defines the header name for specifying a containerd lease.
|
||||
GRPCHeader = "containerd-lease"
|
||||
)
|
||||
|
||||
func withGRPCLeaseHeader(ctx context.Context, lid string) context.Context {
|
||||
// also store on the grpc headers so it gets picked up by any clients
|
||||
// that are using this.
|
||||
txheader := metadata.Pairs(GRPCHeader, lid)
|
||||
md, ok := metadata.FromOutgoingContext(ctx) // merge with outgoing context.
|
||||
if !ok {
|
||||
md = txheader
|
||||
} else {
|
||||
// order ensures the latest is first in this list.
|
||||
md = metadata.Join(txheader, md)
|
||||
}
|
||||
|
||||
return metadata.NewOutgoingContext(ctx, md)
|
||||
}
|
||||
|
||||
func fromGRPCHeader(ctx context.Context) (string, bool) {
|
||||
// try to extract for use in grpc servers.
|
||||
md, ok := metadata.FromIncomingContext(ctx)
|
||||
if !ok {
|
||||
return "", false
|
||||
}
|
||||
|
||||
values := md[GRPCHeader]
|
||||
if len(values) == 0 {
|
||||
return "", false
|
||||
}
|
||||
|
||||
return values[0], true
|
||||
}
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
@ -37,6 +38,7 @@ var (
|
|||
bucketKeyObjectContent = []byte("content") // stores content references
|
||||
bucketKeyObjectBlob = []byte("blob") // stores content links
|
||||
bucketKeyObjectIngest = []byte("ingest") // stores ingest links
|
||||
bucketKeyObjectLeases = []byte("leases") // stores leases
|
||||
|
||||
bucketKeyDigest = []byte("digest")
|
||||
bucketKeyMediaType = []byte("mediatype")
|
||||
|
@ -45,11 +47,14 @@ 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")
|
||||
bucketKeyCreatedAt = []byte("createdat")
|
||||
)
|
||||
|
||||
func getBucket(tx *bolt.Tx, keys ...[]byte) *bolt.Bucket {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
@ -360,23 +391,31 @@ func (nw *namespacedWriter) Commit(ctx context.Context, size int64, expected dig
|
|||
return err
|
||||
}
|
||||
}
|
||||
return nw.commit(ctx, tx, size, expected, opts...)
|
||||
dgst, err := nw.commit(ctx, tx, size, expected, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return addContentLease(ctx, tx, dgst)
|
||||
})
|
||||
}
|
||||
|
||||
func (nw *namespacedWriter) commit(ctx context.Context, tx *bolt.Tx, size int64, expected digest.Digest, opts ...content.Opt) error {
|
||||
func (nw *namespacedWriter) commit(ctx context.Context, tx *bolt.Tx, size int64, expected digest.Digest, opts ...content.Opt) (digest.Digest, error) {
|
||||
var base content.Info
|
||||
for _, opt := range opts {
|
||||
if err := opt(&base); err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
if err := validateInfo(&base); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
status, err := nw.Writer.Status()
|
||||
if err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
if size != 0 && size != status.Offset {
|
||||
return errors.Errorf("%q failed size validation: %v != %v", nw.ref, status.Offset, size)
|
||||
return "", errors.Errorf("%q failed size validation: %v != %v", nw.ref, status.Offset, size)
|
||||
}
|
||||
size = status.Offset
|
||||
|
||||
|
@ -384,36 +423,32 @@ func (nw *namespacedWriter) commit(ctx context.Context, tx *bolt.Tx, size int64,
|
|||
|
||||
if err := nw.Writer.Commit(ctx, size, expected); err != nil {
|
||||
if !errdefs.IsAlreadyExists(err) {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
if getBlobBucket(tx, nw.namespace, actual) != nil {
|
||||
return errors.Wrapf(errdefs.ErrAlreadyExists, "content %v", actual)
|
||||
return "", errors.Wrapf(errdefs.ErrAlreadyExists, "content %v", actual)
|
||||
}
|
||||
}
|
||||
|
||||
bkt, err := createBlobBucket(tx, nw.namespace, actual)
|
||||
if err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
|
||||
commitTime := time.Now().UTC()
|
||||
|
||||
sizeEncoded, err := encodeSize(size)
|
||||
sizeEncoded, err := encodeInt(size)
|
||||
if err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := boltutil.WriteTimestamps(bkt, commitTime, commitTime); err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
if err := boltutil.WriteLabels(bkt, base.Labels); err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
if err := bkt.Put(bucketKeySize, sizeEncoded); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return actual, bkt.Put(bucketKeySize, sizeEncoded)
|
||||
}
|
||||
|
||||
func (nw *namespacedWriter) Status() (content.Status, error) {
|
||||
|
@ -446,6 +481,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 +519,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
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue