From 9027a02e8e2730fea1b29bd162eb1dddd7255067 Mon Sep 17 00:00:00 2001 From: yanxuean Date: Wed, 1 Nov 2017 11:26:33 +0800 Subject: [PATCH] Use image.IsUnpacked fix #361 Signed-off-by: yanxuean --- pkg/containerd/opts/container.go | 14 +-- pkg/server/restart.go | 21 ++-- vendor.conf | 2 +- .../containerd/containerd/README.md | 2 +- .../containerd/containerd/dialer_windows.go | 1 + .../github.com/containerd/containerd/gc/gc.go | 6 +- .../github.com/containerd/containerd/image.go | 23 ++++ .../containerd/containerd/metadata/db.go | 104 ++++++++++-------- .../containerd/containerd/metadata/gc.go | 23 ++-- .../containerd/mount/mount_solaris.go | 83 -------------- .../containerd/mount/mount_windows.go | 4 + .../containerd/mount/mountinfo_solaris.go | 50 --------- .../containerd/containerd/plugin/context.go | 16 +-- .../containerd/containerd/plugin/plugin.go | 11 +- .../remotes/docker/schema1/converter.go | 22 +++- .../containerd/containerd/remotes/handlers.go | 3 +- .../containerd/services/content/reader.go | 2 +- .../containerd/services/content/store.go | 1 + .../containerd/services/diff/client.go | 2 +- .../containerd/services/images/client.go | 1 + .../containerd/services/namespaces/client.go | 1 + .../containerd/snapshot/snapshotter.go | 7 ++ .../containerd/spec_opts_windows.go | 4 + .../containerd/containerd/sys/oom_windows.go | 3 + .../containerd/sys/prctl_solaris.go | 19 ---- .../containerd/containerd/sys/stat_unix.go | 3 + .../containerd/containerd/vendor.conf | 2 +- 27 files changed, 174 insertions(+), 256 deletions(-) delete mode 100644 vendor/github.com/containerd/containerd/mount/mount_solaris.go delete mode 100644 vendor/github.com/containerd/containerd/mount/mountinfo_solaris.go delete mode 100644 vendor/github.com/containerd/containerd/sys/prctl_solaris.go diff --git a/pkg/containerd/opts/container.go b/pkg/containerd/opts/container.go index 3921a2245..ce3787d84 100644 --- a/pkg/containerd/opts/container.go +++ b/pkg/containerd/opts/container.go @@ -21,10 +21,8 @@ import ( "github.com/containerd/containerd" "github.com/containerd/containerd/containers" - "github.com/containerd/containerd/errdefs" "github.com/docker/docker/pkg/chrootarchive" "github.com/docker/docker/pkg/system" - "github.com/opencontainers/image-spec/identity" "github.com/pkg/errors" "golang.org/x/sys/unix" ) @@ -35,19 +33,13 @@ func WithImageUnpack(i containerd.Image) containerd.NewContainerOpts { if c.Snapshotter == "" { return errors.New("no snapshotter set for container") } - snapshotter := client.SnapshotService(c.Snapshotter) - diffIDs, err := i.RootFS(ctx) + unpacked, err := i.IsUnpacked(ctx, c.Snapshotter) if err != nil { - return errors.Wrap(err, "get image diff IDs") + return errors.Wrap(err, "fail to check if image is unpacked") } - chainID := identity.ChainID(diffIDs) - _, err = snapshotter.Stat(ctx, chainID.String()) - if err == nil { + if unpacked { return nil } - if !errdefs.IsNotFound(err) { - return errors.Wrap(err, "stat snapshot") - } // Unpack the snapshot. if err := i.Unpack(ctx, c.Snapshotter); err != nil { return errors.Wrap(err, "unpack snapshot") diff --git a/pkg/server/restart.go b/pkg/server/restart.go index bfa40f645..4102b753e 100644 --- a/pkg/server/restart.go +++ b/pkg/server/restart.go @@ -28,7 +28,6 @@ import ( "github.com/containerd/containerd/errdefs" containerdimages "github.com/containerd/containerd/images" "github.com/containerd/containerd/platforms" - "github.com/containerd/containerd/snapshot" "github.com/containerd/typeurl" "github.com/docker/distribution/reference" "github.com/docker/docker/pkg/system" @@ -99,7 +98,7 @@ func (c *criContainerdService) recover(ctx context.Context) error { if err != nil { return fmt.Errorf("failed to list images: %v", err) } - images, err := loadImages(ctx, cImages, c.client.ContentStore(), c.client.SnapshotService(c.config.ContainerdConfig.Snapshotter)) + images, err := loadImages(ctx, cImages, c.client.ContentStore(), c.config.ContainerdConfig.Snapshotter) if err != nil { return fmt.Errorf("failed to load images: %v", err) } @@ -329,7 +328,7 @@ func loadSandbox(ctx context.Context, cntr containerd.Container) (sandboxstore.S // TODO(random-liu): Check whether image is unpacked, because containerd put image reference // into store before image is unpacked. func loadImages(ctx context.Context, cImages []containerd.Image, provider content.Provider, - snapshotter snapshot.Snapshotter) ([]imagestore.Image, error) { + snapshotter string) ([]imagestore.Image, error) { // Group images by image id. imageMap := make(map[string][]containerd.Image) for _, i := range cImages { @@ -355,6 +354,16 @@ func loadImages(ctx context.Context, cImages []containerd.Image, provider conten glog.Warningf("The image content readiness for %q is not ok", i.Name()) continue } + // Checking existence of top-level snapshot for each image being recovered. + unpacked, err := i.IsUnpacked(ctx, snapshotter) + if err != nil { + glog.Warningf("Failed to Check whether image is unpacked for image %s: %v", i.Name(), err) + continue + } + if !unpacked { + glog.Warningf("The image %s is not unpacked.", i.Name()) + // TODO(random-liu): Consider whether we should try unpack here. + } info, err := getImageInfo(ctx, i, provider) if err != nil { @@ -387,12 +396,6 @@ func loadImages(ctx context.Context, cImages []containerd.Image, provider conten glog.Warningf("Invalid image reference %q", name) } } - - // Checking existence of top-level snapshot for each image being recovered. - if _, err := snapshotter.Stat(ctx, image.ChainID); err != nil { - glog.Warningf("Failed to stat the top-level snapshot for image %+v: %v", image, err) - // TODO(random-liu): Consider whether we should try unpack here. - } images = append(images, image) } return images, nil diff --git a/vendor.conf b/vendor.conf index 36a4f1698..caa28999a 100644 --- a/vendor.conf +++ b/vendor.conf @@ -2,7 +2,7 @@ github.com/blang/semver v3.1.0 github.com/boltdb/bolt e9cf4fae01b5a8ff89d0ec6b32f0d9c9f79aefdd github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895 github.com/containerd/cgroups f7dd103d3e4e696aa67152f6b4ddd1779a3455a9 -github.com/containerd/containerd 04659d94051126f4fe4fcddf068550db447ff5a0 +github.com/containerd/containerd fe3d9a70fabba8d73387db82585a2cbe07a5a68b github.com/containerd/continuity cf279e6ac893682272b4479d4c67fd3abf878b4e github.com/containerd/fifo fbfb6a11ec671efbe94ad1c12c2e98773f19e1e6 github.com/containerd/typeurl f6943554a7e7e88b3c14aad190bf05932da84788 diff --git a/vendor/github.com/containerd/containerd/README.md b/vendor/github.com/containerd/containerd/README.md index 28635dbf0..9b04d5a3b 100644 --- a/vendor/github.com/containerd/containerd/README.md +++ b/vendor/github.com/containerd/containerd/README.md @@ -205,4 +205,4 @@ 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/. +CC-BY-4.0, at http://creativecommons.org/licenses/by/4.0/. diff --git a/vendor/github.com/containerd/containerd/dialer_windows.go b/vendor/github.com/containerd/containerd/dialer_windows.go index c91a32617..43625ef1f 100644 --- a/vendor/github.com/containerd/containerd/dialer_windows.go +++ b/vendor/github.com/containerd/containerd/dialer_windows.go @@ -24,6 +24,7 @@ func dialer(address string, timeout time.Duration) (net.Conn, error) { return winio.DialPipe(address, &timeout) } +// DialAddress returns the dial address func DialAddress(address string) string { return address } diff --git a/vendor/github.com/containerd/containerd/gc/gc.go b/vendor/github.com/containerd/containerd/gc/gc.go index e892be155..70838a762 100644 --- a/vendor/github.com/containerd/containerd/gc/gc.go +++ b/vendor/github.com/containerd/containerd/gc/gc.go @@ -10,7 +10,7 @@ import ( "sync" ) -// Resourcetype represents type of resource at a node +// ResourceType represents type of resource at a node type ResourceType uint8 // Node presents a resource which has a type and key, @@ -145,10 +145,10 @@ func ConcurrentMark(ctx context.Context, root <-chan Node, refs func(context.Con // 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 <-chan Node, remove func(Node) error) error { +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 { + for _, node := range all { if _, ok := reachable[node]; !ok { if err := remove(node); err != nil { return err diff --git a/vendor/github.com/containerd/containerd/image.go b/vendor/github.com/containerd/containerd/image.go index b41037a16..426e15817 100644 --- a/vendor/github.com/containerd/containerd/image.go +++ b/vendor/github.com/containerd/containerd/image.go @@ -6,6 +6,7 @@ import ( "time" "github.com/containerd/containerd/content" + "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/rootfs" @@ -30,6 +31,8 @@ type Image interface { Size(ctx context.Context) (int64, error) // Config descriptor for the image. Config(ctx context.Context) (ocispec.Descriptor, error) + // IsUnpacked returns whether or not an image is unpacked. + IsUnpacked(context.Context, string) (bool, error) } var _ = (Image)(&image{}) @@ -63,6 +66,26 @@ func (i *image) Config(ctx context.Context) (ocispec.Descriptor, error) { 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.Default()) if err != nil { diff --git a/vendor/github.com/containerd/containerd/metadata/db.go b/vendor/github.com/containerd/containerd/metadata/db.go index 510d14a2a..7c366ebcc 100644 --- a/vendor/github.com/containerd/containerd/metadata/db.go +++ b/vendor/github.com/containerd/containerd/metadata/db.go @@ -190,6 +190,7 @@ func (m *DB) Update(fn func(*bolt.Tx) error) error { return m.db.Update(fn) } +// GarbageCollect starts garbage collection func (m *DB) GarbageCollect(ctx context.Context) error { lt1 := time.Now() m.wlock.Lock() @@ -198,39 +199,8 @@ func (m *DB) GarbageCollect(ctx context.Context) error { log.G(ctx).WithField("d", time.Now().Sub(lt1)).Debug("metadata garbage collected") }() - var marked map[gc.Node]struct{} - - if err := m.db.View(func(tx *bolt.Tx) error { - ctx, cancel := context.WithCancel(ctx) - defer cancel() - - roots := make(chan gc.Node) - errChan := make(chan error) - go func() { - defer close(errChan) - defer close(roots) - - // Call roots - if err := scanRoots(ctx, tx, roots); err != nil { - cancel() - errChan <- err - } - }() - - refs := func(ctx context.Context, n gc.Node, fn func(gc.Node)) error { - return references(ctx, tx, n, fn) - } - - reachable, err := gc.ConcurrentMark(ctx, roots, refs) - if rerr := <-errChan; rerr != nil { - return rerr - } - if err != nil { - return err - } - marked = reachable - return nil - }); err != nil { + marked, err := m.getMarked(ctx) + if err != nil { return err } @@ -241,15 +211,11 @@ func (m *DB) GarbageCollect(ctx context.Context) error { ctx, cancel := context.WithCancel(ctx) defer cancel() - nodeC := make(chan gc.Node) - var scanErr error + rm := func(ctx context.Context, n gc.Node) error { + if _, ok := marked[n]; ok { + return nil + } - go func() { - defer close(nodeC) - scanErr = scanAll(ctx, tx, nodeC) - }() - - rm := func(n gc.Node) error { if n.Type == ResourceSnapshot { if idx := strings.IndexRune(n.Key, '/'); idx > 0 { m.dirtySS[n.Key[:idx]] = struct{}{} @@ -260,12 +226,8 @@ func (m *DB) GarbageCollect(ctx context.Context) error { return remove(ctx, tx, n) } - if err := gc.Sweep(marked, nodeC, rm); err != nil { - return errors.Wrap(err, "failed to sweep") - } - - if scanErr != nil { - return errors.Wrap(scanErr, "failed to scan all") + if err := scanAll(ctx, tx, rm); err != nil { + return errors.Wrap(err, "failed to scan and remove") } return nil @@ -292,6 +254,54 @@ func (m *DB) GarbageCollect(ctx context.Context) error { 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] diff --git a/vendor/github.com/containerd/containerd/metadata/gc.go b/vendor/github.com/containerd/containerd/metadata/gc.go index 8434d694b..63d1852e0 100644 --- a/vendor/github.com/containerd/containerd/metadata/gc.go +++ b/vendor/github.com/containerd/containerd/metadata/gc.go @@ -12,10 +12,15 @@ import ( ) const ( + // ResourceUnknown specifies an unknown resource ResourceUnknown gc.ResourceType = iota + // ResourceContent specifies a content resource ResourceContent + // ResourceSnapshot specifies a snapshot resource ResourceSnapshot + // ResourceContainer specifies a container resource ResourceContainer + // ResourceTask specifies a task resource ResourceTask ) @@ -174,7 +179,7 @@ func references(ctx context.Context, tx *bolt.Tx, node gc.Node, fn func(gc.Node) return nil } -func scanAll(ctx context.Context, tx *bolt.Tx, nc chan<- gc.Node) error { +func scanAll(ctx context.Context, tx *bolt.Tx, fn func(ctx context.Context, n gc.Node) error) error { v1bkt := tx.Bucket(bucketKeyVersion) if v1bkt == nil { return nil @@ -201,12 +206,8 @@ func scanAll(ctx context.Context, tx *bolt.Tx, nc chan<- gc.Node) error { if v != nil { return nil } - select { - case nc <- gcnode(ResourceSnapshot, ns, fmt.Sprintf("%s/%s", sk, k)): - case <-ctx.Done(): - return ctx.Err() - } - return nil + node := gcnode(ResourceSnapshot, ns, fmt.Sprintf("%s/%s", sk, k)) + return fn(ctx, node) }) }); err != nil { return err @@ -222,12 +223,8 @@ func scanAll(ctx context.Context, tx *bolt.Tx, nc chan<- gc.Node) error { if v != nil { return nil } - select { - case nc <- gcnode(ResourceContent, ns, string(k)): - case <-ctx.Done(): - return ctx.Err() - } - return nil + node := gcnode(ResourceContent, ns, string(k)) + return fn(ctx, node) }); err != nil { return err } diff --git a/vendor/github.com/containerd/containerd/mount/mount_solaris.go b/vendor/github.com/containerd/containerd/mount/mount_solaris.go deleted file mode 100644 index 3b6c35d74..000000000 --- a/vendor/github.com/containerd/containerd/mount/mount_solaris.go +++ /dev/null @@ -1,83 +0,0 @@ -package mount - -// On Solaris we can't invoke the mount system call directly. First, -// the mount system call takes more than 6 arguments, and go doesn't -// support invoking system calls that take more than 6 arguments. Past -// that, the mount system call is a private interfaces. For example, -// the arguments and data structures passed to the kernel to create an -// nfs mount are private and can change at any time. The only public -// and stable interface for creating mounts on Solaris is the mount.8 -// command, so we'll invoke that here. - -import ( - "bytes" - "errors" - "fmt" - "os/exec" - "strings" - - "golang.org/x/sys/unix" -) - -const ( - mountCmd = "/usr/sbin/mount" -) - -func doMount(arg ...string) error { - cmd := exec.Command(mountCmd, arg...) - - /* Setup Stdin, Stdout, and Stderr */ - stderr := new(bytes.Buffer) - cmd.Stdin = nil - cmd.Stdout = nil - cmd.Stderr = stderr - - /* - * Run the command. If the command fails create a new error - * object to return that includes stderr output. - */ - err := cmd.Start() - if err != nil { - return err - } - err = cmd.Wait() - if err != nil { - return errors.New(fmt.Sprintf("%v: %s", err, stderr.String())) - } - return nil -} - -func (m *Mount) Mount(target string) error { - var err error - - if len(m.Options) == 0 { - err = doMount("-F", m.Type, m.Source, target) - } else { - err = doMount("-F", m.Type, "-o", strings.Join(m.Options, ","), - m.Source, target) - } - return err -} - -func Unmount(mount string, flags int) error { - return unix.Unmount(mount, flags) -} - -// UnmountAll repeatedly unmounts the given mount point until there -// are no mounts remaining (EINVAL is returned by mount), which is -// useful for undoing a stack of mounts on the same mount point. -func UnmountAll(mount string, flags int) error { - for { - if err := Unmount(mount, flags); err != nil { - // EINVAL is returned if the target is not a - // mount point, indicating that we are - // done. It can also indicate a few other - // things (such as invalid flags) which we - // unfortunately end up squelching here too. - if err == unix.EINVAL { - return nil - } - return err - } - } -} diff --git a/vendor/github.com/containerd/containerd/mount/mount_windows.go b/vendor/github.com/containerd/containerd/mount/mount_windows.go index 8eeca6817..8ad7eab12 100644 --- a/vendor/github.com/containerd/containerd/mount/mount_windows.go +++ b/vendor/github.com/containerd/containerd/mount/mount_windows.go @@ -3,17 +3,21 @@ package mount import "github.com/pkg/errors" var ( + // ErrNotImplementOnWindows is returned when an action is not implemented for windows ErrNotImplementOnWindows = errors.New("not implemented under windows") ) +// Mount to the provided target func (m *Mount) Mount(target string) error { return ErrNotImplementOnWindows } +// Unmount the mount at the provided path func Unmount(mount string, flags int) error { return ErrNotImplementOnWindows } +// UnmountAll mounts at the provided path func UnmountAll(mount string, flags int) error { return ErrNotImplementOnWindows } diff --git a/vendor/github.com/containerd/containerd/mount/mountinfo_solaris.go b/vendor/github.com/containerd/containerd/mount/mountinfo_solaris.go deleted file mode 100644 index aaafad36a..000000000 --- a/vendor/github.com/containerd/containerd/mount/mountinfo_solaris.go +++ /dev/null @@ -1,50 +0,0 @@ -// +build solaris,cgo - -package mount - -/* -#include -#include -#include -*/ -import "C" - -import ( - "fmt" - "unsafe" -) - -// Self retrieves a list of mounts for the current running process. -func Self() ([]Info, error) { - path := C.CString(C.MNTTAB) - defer C.free(unsafe.Pointer(path)) - mode := C.CString("r") - defer C.free(unsafe.Pointer(mode)) - - mnttab := C.fopen(path, mode) - if mnttab == nil { - return nil, fmt.Errorf("Failed to open %s", C.MNTTAB) - } - - var out []Info - var mp C.struct_mnttab - - ret := C.getmntent(mnttab, &mp) - for ret == 0 { - var mountinfo Info - mountinfo.Mountpoint = C.GoString(mp.mnt_mountp) - mountinfo.Source = C.GoString(mp.mnt_special) - mountinfo.FSType = C.GoString(mp.mnt_fstype) - mountinfo.Options = C.GoString(mp.mnt_mntopts) - out = append(out, mountinfo) - ret = C.getmntent(mnttab, &mp) - } - - C.fclose(mnttab) - return out, nil -} - -// PID collects the mounts for a specific process ID. -func PID(pid int) ([]Info, error) { - return nil, fmt.Errorf("mountinfo.PID is not implemented on solaris") -} diff --git a/vendor/github.com/containerd/containerd/plugin/context.go b/vendor/github.com/containerd/containerd/plugin/context.go index 849b1cb0f..67ad2aa44 100644 --- a/vendor/github.com/containerd/containerd/plugin/context.go +++ b/vendor/github.com/containerd/containerd/plugin/context.go @@ -22,11 +22,11 @@ type InitContext struct { Meta *Meta // plugins can fill in metadata at init. - plugins *PluginSet + plugins *Set } // NewContext returns a new plugin InitContext -func NewContext(ctx context.Context, r *Registration, plugins *PluginSet, root, state string) *InitContext { +func NewContext(ctx context.Context, r *Registration, plugins *Set, root, state string) *InitContext { return &InitContext{ Context: log.WithModule(ctx, r.URI()), Root: filepath.Join(root, r.URI()), @@ -72,26 +72,26 @@ func (p *Plugin) Instance() (interface{}, error) { return p.instance, p.err } -// PluginSet defines a plugin collection, used with InitContext. +// Set defines a plugin collection, used with InitContext. // // This maintains ordering and unique indexing over the set. // // After iteratively instantiating plugins, this set should represent, the // ordered, initialization set of plugins for a containerd instance. -type PluginSet struct { +type Set struct { ordered []*Plugin // order of initialization byTypeAndID map[Type]map[string]*Plugin } // NewPluginSet returns an initialized plugin set -func NewPluginSet() *PluginSet { - return &PluginSet{ +func NewPluginSet() *Set { + return &Set{ byTypeAndID: make(map[Type]map[string]*Plugin), } } // Add a plugin to the set -func (ps *PluginSet) Add(p *Plugin) error { +func (ps *Set) Add(p *Plugin) error { if byID, typeok := ps.byTypeAndID[p.Registration.Type]; !typeok { ps.byTypeAndID[p.Registration.Type] = map[string]*Plugin{ p.Registration.ID: p, @@ -107,7 +107,7 @@ func (ps *PluginSet) Add(p *Plugin) error { } // Get returns the first plugin by its type -func (ps *PluginSet) Get(t Type) (interface{}, error) { +func (ps *Set) Get(t Type) (interface{}, error) { for _, v := range ps.byTypeAndID[t] { return v.Instance() } diff --git a/vendor/github.com/containerd/containerd/plugin/plugin.go b/vendor/github.com/containerd/containerd/plugin/plugin.go index d7b1c0a61..9bda46cbf 100644 --- a/vendor/github.com/containerd/containerd/plugin/plugin.go +++ b/vendor/github.com/containerd/containerd/plugin/plugin.go @@ -58,9 +58,13 @@ const ( // Registration contains information for registering a plugin type Registration struct { - Type Type - ID string - Config interface{} + // Type of the plugin + Type Type + // ID of the plugin + ID string + // Config specific to the plugin + Config interface{} + // Requires is a list of plugins that the registered plugin requires to be available Requires []Type // InitFn is called when initializing a plugin. The registration and @@ -69,6 +73,7 @@ type Registration struct { InitFn func(*InitContext) (interface{}, error) } +// Init the registered plugin func (r *Registration) Init(ic *InitContext) *Plugin { p, err := r.InitFn(ic) return &Plugin{ diff --git a/vendor/github.com/containerd/containerd/remotes/docker/schema1/converter.go b/vendor/github.com/containerd/containerd/remotes/docker/schema1/converter.go index 99940c88a..6e0dcb4e2 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/schema1/converter.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/schema1/converter.go @@ -9,6 +9,7 @@ import ( "fmt" "io" "io/ioutil" + "math/rand" "strings" "sync" "time" @@ -215,13 +216,26 @@ func (c *Converter) fetchManifest(ctx context.Context, desc ocispec.Descriptor) func (c *Converter) fetchBlob(ctx context.Context, desc ocispec.Descriptor) error { log.G(ctx).Debug("fetch blob") - ref := remotes.MakeRefKey(ctx, desc) - - calc := newBlobStateCalculator() + var ( + ref = remotes.MakeRefKey(ctx, desc) + calc = newBlobStateCalculator() + retry = 16 + ) +tryit: cw, err := c.contentStore.Writer(ctx, ref, desc.Size, desc.Digest) if err != nil { - if !errdefs.IsAlreadyExists(err) { + if errdefs.IsUnavailable(err) { + select { + case <-time.After(time.Millisecond * time.Duration(rand.Intn(retry))): + if retry < 2048 { + retry = retry << 1 + } + goto tryit + case <-ctx.Done(): + return err + } + } else if !errdefs.IsAlreadyExists(err) { return err } diff --git a/vendor/github.com/containerd/containerd/remotes/handlers.go b/vendor/github.com/containerd/containerd/remotes/handlers.go index e6d213299..7b1dad99e 100644 --- a/vendor/github.com/containerd/containerd/remotes/handlers.go +++ b/vendor/github.com/containerd/containerd/remotes/handlers.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "io" + "math/rand" "time" "github.com/containerd/containerd/content" @@ -84,7 +85,7 @@ func fetch(ctx context.Context, ingester content.Ingester, fetcher Fetcher, desc // of writer and abort if not updated recently. select { - case <-time.After(time.Millisecond * time.Duration(retry)): + case <-time.After(time.Millisecond * time.Duration(rand.Intn(retry))): if retry < 2048 { retry = retry << 1 } diff --git a/vendor/github.com/containerd/containerd/services/content/reader.go b/vendor/github.com/containerd/containerd/services/content/reader.go index a8cc55430..024251c6d 100644 --- a/vendor/github.com/containerd/containerd/services/content/reader.go +++ b/vendor/github.com/containerd/containerd/services/content/reader.go @@ -44,6 +44,6 @@ func (ra *remoteReaderAt) ReadAt(p []byte, off int64) (n int, err error) { return n, nil } -func (rr *remoteReaderAt) Close() error { +func (ra *remoteReaderAt) Close() error { return nil } diff --git a/vendor/github.com/containerd/containerd/services/content/store.go b/vendor/github.com/containerd/containerd/services/content/store.go index 11fcc0365..b5aaa8577 100644 --- a/vendor/github.com/containerd/containerd/services/content/store.go +++ b/vendor/github.com/containerd/containerd/services/content/store.go @@ -15,6 +15,7 @@ type remoteStore struct { client contentapi.ContentClient } +// NewStoreFromClient returns a new content store func NewStoreFromClient(client contentapi.ContentClient) content.Store { return &remoteStore{ client: client, diff --git a/vendor/github.com/containerd/containerd/services/diff/client.go b/vendor/github.com/containerd/containerd/services/diff/client.go index 5267f9707..d34848be2 100644 --- a/vendor/github.com/containerd/containerd/services/diff/client.go +++ b/vendor/github.com/containerd/containerd/services/diff/client.go @@ -9,7 +9,7 @@ import ( "golang.org/x/net/context" ) -// NewApplierFromClient returns a new Applier which communicates +// NewDiffServiceFromClient returns a new diff service which communicates // over a GRPC connection. func NewDiffServiceFromClient(client diffapi.DiffClient) diff.Differ { return &remote{ diff --git a/vendor/github.com/containerd/containerd/services/images/client.go b/vendor/github.com/containerd/containerd/services/images/client.go index eebe776fa..f746ddce8 100644 --- a/vendor/github.com/containerd/containerd/services/images/client.go +++ b/vendor/github.com/containerd/containerd/services/images/client.go @@ -13,6 +13,7 @@ type remoteStore struct { client imagesapi.ImagesClient } +// NewStoreFromClient returns a new image store client func NewStoreFromClient(client imagesapi.ImagesClient) images.Store { return &remoteStore{ client: client, diff --git a/vendor/github.com/containerd/containerd/services/namespaces/client.go b/vendor/github.com/containerd/containerd/services/namespaces/client.go index 80709f905..fd59ec619 100644 --- a/vendor/github.com/containerd/containerd/services/namespaces/client.go +++ b/vendor/github.com/containerd/containerd/services/namespaces/client.go @@ -10,6 +10,7 @@ import ( "github.com/gogo/protobuf/types" ) +// NewStoreFromClient returns a new namespace store func NewStoreFromClient(client api.NamespacesClient) namespaces.Store { return &remote{client: client} } diff --git a/vendor/github.com/containerd/containerd/snapshot/snapshotter.go b/vendor/github.com/containerd/containerd/snapshot/snapshotter.go index 6beafd48a..2b3fe6275 100644 --- a/vendor/github.com/containerd/containerd/snapshot/snapshotter.go +++ b/vendor/github.com/containerd/containerd/snapshot/snapshotter.go @@ -20,6 +20,9 @@ const ( KindCommitted ) +// ParseKind parses the provided string into a Kind +// +// If the string cannot be parsed KindUnknown is returned func ParseKind(s string) Kind { s = strings.ToLower(s) switch s { @@ -34,6 +37,7 @@ func ParseKind(s string) Kind { return KindUnknown } +// String returns the string representation of the Kind func (k Kind) String() string { switch k { case KindView: @@ -47,10 +51,12 @@ func (k Kind) String() string { return "Unknown" } +// MarshalJSON the Kind to JSON func (k Kind) MarshalJSON() ([]byte, error) { return json.Marshal(k.String()) } +// UnmarshalJSON the Kind from JSON func (k *Kind) UnmarshalJSON(b []byte) error { var s string if err := json.Unmarshal(b, &s); err != nil { @@ -81,6 +87,7 @@ type Usage struct { Size int64 // provides usage, in bytes, of snapshot } +// Add the provided usage to the current usage func (u *Usage) Add(other Usage) { u.Size += other.Size diff --git a/vendor/github.com/containerd/containerd/spec_opts_windows.go b/vendor/github.com/containerd/containerd/spec_opts_windows.go index 5aa5c3029..1fc5d5e37 100644 --- a/vendor/github.com/containerd/containerd/spec_opts_windows.go +++ b/vendor/github.com/containerd/containerd/spec_opts_windows.go @@ -15,6 +15,7 @@ import ( specs "github.com/opencontainers/runtime-spec/specs-go" ) +// WithImageConfig configures the spec to from the configuration of an Image func WithImageConfig(i Image) SpecOpts { return func(ctx context.Context, client *Client, _ *containers.Container, s *specs.Spec) error { var ( @@ -51,6 +52,8 @@ func WithImageConfig(i Image) SpecOpts { } } +// WithTTY sets the information on the spec as well as the environment variables for +// using a TTY func WithTTY(width, height int) SpecOpts { return func(_ context.Context, _ *Client, _ *containers.Container, s *specs.Spec) error { s.Process.Terminal = true @@ -63,6 +66,7 @@ func WithTTY(width, height int) SpecOpts { } } +// WithResources sets the provided resources on the spec for task updates func WithResources(resources *specs.WindowsResources) UpdateTaskOpts { return func(ctx context.Context, client *Client, r *UpdateTaskInfo) error { r.Resources = resources diff --git a/vendor/github.com/containerd/containerd/sys/oom_windows.go b/vendor/github.com/containerd/containerd/sys/oom_windows.go index a72568b27..6e42ddce8 100644 --- a/vendor/github.com/containerd/containerd/sys/oom_windows.go +++ b/vendor/github.com/containerd/containerd/sys/oom_windows.go @@ -1,5 +1,8 @@ package sys +// SetOOMScore sets the oom score for the process +// +// Not implemented on Windows func SetOOMScore(pid, score int) error { return nil } diff --git a/vendor/github.com/containerd/containerd/sys/prctl_solaris.go b/vendor/github.com/containerd/containerd/sys/prctl_solaris.go deleted file mode 100644 index 9443f14db..000000000 --- a/vendor/github.com/containerd/containerd/sys/prctl_solaris.go +++ /dev/null @@ -1,19 +0,0 @@ -// +build solaris - -package sys - -import ( - "errors" -) - -//Solaris TODO - -// GetSubreaper returns the subreaper setting for the calling process -func GetSubreaper() (int, error) { - return 0, errors.New("osutils GetSubreaper not implemented on Solaris") -} - -// SetSubreaper sets the value i as the subreaper setting for the calling process -func SetSubreaper(i int) error { - return errors.New("osutils SetSubreaper not implemented on Solaris") -} diff --git a/vendor/github.com/containerd/containerd/sys/stat_unix.go b/vendor/github.com/containerd/containerd/sys/stat_unix.go index da13ed26e..1f983a98d 100644 --- a/vendor/github.com/containerd/containerd/sys/stat_unix.go +++ b/vendor/github.com/containerd/containerd/sys/stat_unix.go @@ -6,14 +6,17 @@ import ( "syscall" ) +// StatAtime returns the Atim func StatAtime(st *syscall.Stat_t) syscall.Timespec { return st.Atim } +// StatCtime returns the Ctim func StatCtime(st *syscall.Stat_t) syscall.Timespec { return st.Ctim } +// StatMtime returns the Mtim func StatMtime(st *syscall.Stat_t) syscall.Timespec { return st.Mtim } diff --git a/vendor/github.com/containerd/containerd/vendor.conf b/vendor/github.com/containerd/containerd/vendor.conf index f751909b2..671346821 100644 --- a/vendor/github.com/containerd/containerd/vendor.conf +++ b/vendor/github.com/containerd/containerd/vendor.conf @@ -23,7 +23,7 @@ github.com/stretchr/testify v1.1.4 github.com/davecgh/go-spew v1.1.0 github.com/pmezard/go-difflib v1.0.0 github.com/containerd/fifo fbfb6a11ec671efbe94ad1c12c2e98773f19e1e6 -github.com/urfave/cli 8ba6f23b6e36d03666a14bd9421f5e3efcb59aca +github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c golang.org/x/net 7dcfb8076726a3fdd9353b6b8a1f1b6be6811bd6 google.golang.org/grpc v1.3.0 github.com/pkg/errors v0.8.0