diff --git a/vendor.conf b/vendor.conf index e8820f0be..8b1b6407d 100644 --- a/vendor.conf +++ b/vendor.conf @@ -10,7 +10,7 @@ github.com/BurntSushi/toml 3012a1dbe2e4bd1391d42b32f057 github.com/cespare/xxhash/v2 d7df74196a9e781ede915320c11c378c1b2f3a1f # v2.1.1 github.com/containerd/cgroups b4448137398923af7f4918b8b2ad8249172ca7a6 github.com/containerd/console 8375c3424e4d7b114e8a90a4a40c8e1b40d1d4e6 # v1.0.0 -github.com/containerd/containerd 01310155947cb6eec37dcae29742a165e56acb4a +github.com/containerd/containerd ed261720c86d1e700cd5d39175128322baac6dda github.com/containerd/continuity 0ec596719c75bfd42908850990acea594b7593ac github.com/containerd/fifo bda0ff6ed73c67bfb5e62bc9c697f146b7fd7f13 github.com/containerd/go-runc a5c2862aed5e6358b305b0e16bfce58e0549b1cd @@ -27,6 +27,8 @@ github.com/gogo/protobuf 5628607bb4c51c3157aacc3a50f0 github.com/golang/protobuf d23c5127dc24889085f8ccea5c9d560a57a879d8 # v1.3.3 github.com/google/uuid 0cd6bf5da1e1c83f8b45653022c74f71af0538a4 # v1.1.1 github.com/grpc-ecosystem/go-grpc-prometheus c225b8c3b01faf2899099b768856a9e916e5087b # v1.2.0 +github.com/hashicorp/errwrap 8a6fb523712970c966eefc6b39ed2c5e74880354 # v1.0.0 +github.com/hashicorp/go-multierror 886a7fbe3eb1c874d46f623bfa70af45f425b3d1 # v1.0.0 github.com/hashicorp/golang-lru 7f827b33c0f158ec5dfbba01bb0b14a4541fd81d # v0.5.3 github.com/imdario/mergo 7c29201646fa3de8506f701213473dd407f19646 # v0.3.7 github.com/konsorten/go-windows-terminal-sequences edb144dfd453055e1e49a3d8b410a660b5a87613 # v1.0.3 diff --git a/vendor/github.com/containerd/containerd/README.md b/vendor/github.com/containerd/containerd/README.md index 68e57a78c..de8adfb63 100644 --- a/vendor/github.com/containerd/containerd/README.md +++ b/vendor/github.com/containerd/containerd/README.md @@ -1,9 +1,9 @@ ![containerd banner](https://raw.githubusercontent.com/cncf/artwork/master/projects/containerd/horizontal/color/containerd-horizontal-color.png) [![GoDoc](https://godoc.org/github.com/containerd/containerd?status.svg)](https://godoc.org/github.com/containerd/containerd) -[![Build Status](https://travis-ci.org/containerd/containerd.svg?branch=master)](https://travis-ci.org/containerd/containerd) +[![Build Status](https://github.com/containerd/containerd/workflows/CI/badge.svg)](https://github.com/containerd/containerd/actions?query=workflow%3ACI) [![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/containerd/containerd?branch=master&svg=true)](https://ci.appveyor.com/project/mlaventure/containerd-3g73f?branch=master) -![](https://github.com/containerd/containerd/workflows/Nightly/badge.svg) +[![Nightlies](https://github.com/containerd/containerd/workflows/Nightly/badge.svg)](https://github.com/containerd/containerd/actions?query=workflow%3ANightly) [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fcontainerd%2Fcontainerd.svg?type=shield)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fcontainerd%2Fcontainerd?ref=badge_shield) [![Go Report Card](https://goreportcard.com/badge/github.com/containerd/containerd)](https://goreportcard.com/report/github.com/containerd/containerd) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/1271/badge)](https://bestpractices.coreinfrastructure.org/projects/1271) diff --git a/vendor/github.com/containerd/containerd/archive/tar_unix.go b/vendor/github.com/containerd/containerd/archive/tar_unix.go index d081351f1..6e89d2fdb 100644 --- a/vendor/github.com/containerd/containerd/archive/tar_unix.go +++ b/vendor/github.com/containerd/containerd/archive/tar_unix.go @@ -22,12 +22,11 @@ import ( "archive/tar" "os" "strings" - "sync" "syscall" + "github.com/containerd/containerd/sys" "github.com/containerd/continuity/fs" "github.com/containerd/continuity/sysx" - "github.com/opencontainers/runc/libcontainer/system" "github.com/pkg/errors" "golang.org/x/sys/unix" ) @@ -84,21 +83,11 @@ func mkdir(path string, perm os.FileMode) error { return os.Chmod(path, perm) } -var ( - inUserNS bool - nsOnce sync.Once -) - -func setInUserNS() { - inUserNS = system.RunningInUserNS() -} - func skipFile(hdr *tar.Header) bool { switch hdr.Typeflag { case tar.TypeBlock, tar.TypeChar: // cannot create a device if running in user namespace - nsOnce.Do(setInUserNS) - return inUserNS + return sys.RunningInUserNS() default: return false } @@ -125,7 +114,7 @@ func handleTarTypeBlockCharFifo(hdr *tar.Header, path string) error { func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo) error { if hdr.Typeflag == tar.TypeLink { if fi, err := os.Lstat(hdr.Linkname); err == nil && (fi.Mode()&os.ModeSymlink == 0) { - if err := os.Chmod(path, hdrInfo.Mode()); err != nil { + if err := os.Chmod(path, hdrInfo.Mode()); err != nil && !os.IsNotExist(err) { return err } } diff --git a/vendor/github.com/containerd/containerd/client.go b/vendor/github.com/containerd/containerd/client.go index 1987e45c0..98c2bdd04 100644 --- a/vendor/github.com/containerd/containerd/client.go +++ b/vendor/github.com/containerd/containerd/client.go @@ -58,7 +58,6 @@ import ( "github.com/containerd/containerd/snapshots" snproxy "github.com/containerd/containerd/snapshots/proxy" "github.com/containerd/typeurl" - "github.com/gogo/protobuf/types" ptypes "github.com/gogo/protobuf/types" ocispec "github.com/opencontainers/image-spec/specs-go/v1" specs "github.com/opencontainers/runtime-spec/specs-go" @@ -319,6 +318,9 @@ type RemoteContext struct { // Snapshotter used for unpacking Snapshotter string + // SnapshotterOpts are additional options to be passed to a snapshotter during pull + SnapshotterOpts []snapshots.Opt + // Labels to be applied to the created image Labels map[string]string @@ -720,7 +722,7 @@ func (c *Client) Server(ctx context.Context) (ServerInfo, error) { } c.connMu.Unlock() - response, err := c.IntrospectionService().Server(ctx, &types.Empty{}) + response, err := c.IntrospectionService().Server(ctx, &ptypes.Empty{}) if err != nil { return ServerInfo{}, err } diff --git a/vendor/github.com/containerd/containerd/client_opts.go b/vendor/github.com/containerd/containerd/client_opts.go index 860461efa..d0f884f83 100644 --- a/vendor/github.com/containerd/containerd/client_opts.go +++ b/vendor/github.com/containerd/containerd/client_opts.go @@ -22,6 +22,8 @@ import ( "github.com/containerd/containerd/images" "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/remotes" + "github.com/containerd/containerd/snapshots" + "google.golang.org/grpc" ) @@ -138,10 +140,11 @@ func WithUnpackOpts(opts []UnpackOpt) RemoteOpt { } } -// WithPullSnapshotter specifies snapshotter name used for unpacking -func WithPullSnapshotter(snapshotterName string) RemoteOpt { +// WithPullSnapshotter specifies snapshotter name used for unpacking. +func WithPullSnapshotter(snapshotterName string, opts ...snapshots.Opt) RemoteOpt { return func(_ *Client, c *RemoteContext) error { c.Snapshotter = snapshotterName + c.SnapshotterOpts = opts return nil } } diff --git a/vendor/github.com/containerd/containerd/cmd/containerd/command/main.go b/vendor/github.com/containerd/containerd/cmd/containerd/command/main.go index 3db453303..de5070423 100644 --- a/vendor/github.com/containerd/containerd/cmd/containerd/command/main.go +++ b/vendor/github.com/containerd/containerd/cmd/containerd/command/main.go @@ -227,6 +227,10 @@ can be used and modified as necessary as a custom configuration.` } serve(ctx, l, server.ServeGRPC) + if err := notifyReady(ctx); err != nil { + log.G(ctx).WithError(err).Warn("notify ready failed") + } + log.G(ctx).Infof("containerd successfully booted in %fs", time.Since(start).Seconds()) <-done return nil diff --git a/vendor/github.com/containerd/containerd/cmd/containerd/command/main_unix.go b/vendor/github.com/containerd/containerd/cmd/containerd/command/main_unix.go index c9081eeef..7bc9b1cf9 100644 --- a/vendor/github.com/containerd/containerd/cmd/containerd/command/main_unix.go +++ b/vendor/github.com/containerd/containerd/cmd/containerd/command/main_unix.go @@ -52,6 +52,10 @@ func handleSignals(ctx context.Context, signals chan os.Signal, serverC chan *se case unix.SIGPIPE: continue default: + if err := notifyStopping(ctx); err != nil { + log.G(ctx).WithError(err).Error("notify stopping failed") + } + if server == nil { close(done) return diff --git a/vendor/github.com/containerd/containerd/cmd/containerd/command/main_windows.go b/vendor/github.com/containerd/containerd/cmd/containerd/command/main_windows.go index 2f7cf7471..7e3430bb6 100644 --- a/vendor/github.com/containerd/containerd/cmd/containerd/command/main_windows.go +++ b/vendor/github.com/containerd/containerd/cmd/containerd/command/main_windows.go @@ -50,6 +50,11 @@ func handleSignals(ctx context.Context, signals chan os.Signal, serverC chan *se server = s case s := <-signals: log.G(ctx).WithField("signal", s).Debug("received signal") + + if err := notifyStopping(ctx); err != nil { + log.G(ctx).WithError(err).Error("notify stopping failed") + } + if server == nil { close(done) return diff --git a/vendor/github.com/containerd/containerd/cmd/containerd/command/notify_linux.go b/vendor/github.com/containerd/containerd/cmd/containerd/command/notify_linux.go new file mode 100644 index 000000000..be3d580f2 --- /dev/null +++ b/vendor/github.com/containerd/containerd/cmd/containerd/command/notify_linux.go @@ -0,0 +1,47 @@ +// +build linux + +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package command + +import ( + "context" + + sd "github.com/coreos/go-systemd/v22/daemon" + + "github.com/containerd/containerd/log" +) + +// notifyReady notifies systemd that the daemon is ready to serve requests +func notifyReady(ctx context.Context) error { + return sdNotify(ctx, sd.SdNotifyReady) +} + +// notifyStopping notifies systemd that the daemon is about to be stopped +func notifyStopping(ctx context.Context) error { + return sdNotify(ctx, sd.SdNotifyStopping) +} + +func sdNotify(ctx context.Context, state string) error { + notified, err := sd.SdNotify(false, state) + log.G(ctx). + WithError(err). + WithField("notified", notified). + WithField("state", state). + Debug("sd notification") + return err +} diff --git a/vendor/github.com/containerd/containerd/cmd/containerd/command/notify_unsupported.go b/vendor/github.com/containerd/containerd/cmd/containerd/command/notify_unsupported.go new file mode 100644 index 000000000..3a0513739 --- /dev/null +++ b/vendor/github.com/containerd/containerd/cmd/containerd/command/notify_unsupported.go @@ -0,0 +1,31 @@ +// +build !linux + +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package command + +import ( + "context" +) + +func notifyReady(ctx context.Context) error { + return nil +} + +func notifyStopping(ctx context.Context) error { + return nil +} diff --git a/vendor/github.com/containerd/containerd/cmd/containerd/command/service_windows.go b/vendor/github.com/containerd/containerd/cmd/containerd/command/service_windows.go index 697345910..655295fc8 100644 --- a/vendor/github.com/containerd/containerd/cmd/containerd/command/service_windows.go +++ b/vendor/github.com/containerd/containerd/cmd/containerd/command/service_windows.go @@ -49,8 +49,6 @@ var ( allocConsole = kernel32.NewProc("AllocConsole") oldStderr windows.Handle panicFile *os.File - - service *handler ) const defaultServiceName = "containerd" @@ -282,7 +280,6 @@ func launchService(s *server.Server, done chan struct{}) error { return err } - service = h go func() { if interactive { err = debug.Run(serviceNameFlag, h) diff --git a/vendor/github.com/containerd/containerd/container.go b/vendor/github.com/containerd/containerd/container.go index 187934ead..a893364c5 100644 --- a/vendor/github.com/containerd/containerd/container.go +++ b/vendor/github.com/containerd/containerd/container.go @@ -32,6 +32,7 @@ import ( "github.com/containerd/containerd/images" "github.com/containerd/containerd/oci" "github.com/containerd/containerd/runtime/v2/runc/options" + "github.com/containerd/containerd/sys" "github.com/containerd/typeurl" prototypes "github.com/gogo/protobuf/types" ver "github.com/opencontainers/image-spec/specs-go" @@ -422,14 +423,33 @@ func attachExistingIO(response *tasks.GetResponse, ioAttach cio.Attach) (cio.IO, // loadFifos loads the containers fifos func loadFifos(response *tasks.GetResponse) *cio.FIFOSet { - path := getFifoDir([]string{ + fifos := []string{ response.Process.Stdin, response.Process.Stdout, response.Process.Stderr, - }) - closer := func() error { - return os.RemoveAll(path) } + closer := func() error { + var ( + err error + dirs = map[string]struct{}{} + ) + for _, fifo := range fifos { + if isFifo, _ := sys.IsFifo(fifo); isFifo { + if rerr := os.Remove(fifo); err == nil { + err = rerr + } + dirs[filepath.Dir(fifo)] = struct{}{} + } + } + for dir := range dirs { + // we ignore errors here because we don't + // want to remove the directory if it isn't + // empty + os.Remove(dir) + } + return err + } + return cio.NewFIFOSet(cio.Config{ Stdin: response.Process.Stdin, Stdout: response.Process.Stdout, @@ -437,14 +457,3 @@ func loadFifos(response *tasks.GetResponse) *cio.FIFOSet { Terminal: response.Process.Terminal, }, closer) } - -// getFifoDir looks for any non-empty path for a stdio fifo -// and returns the dir for where it is located -func getFifoDir(paths []string) string { - for _, p := range paths { - if p != "" { - return filepath.Dir(p) - } - } - return "" -} diff --git a/vendor/github.com/containerd/containerd/content/local/store.go b/vendor/github.com/containerd/containerd/content/local/store.go index efc58ea79..87056814a 100644 --- a/vendor/github.com/containerd/containerd/content/local/store.go +++ b/vendor/github.com/containerd/containerd/content/local/store.go @@ -92,7 +92,11 @@ func NewLabeledStore(root string, ls LabelStore) (content.Store, error) { } func (s *store) Info(ctx context.Context, dgst digest.Digest) (content.Info, error) { - p := s.blobPath(dgst) + p, err := s.blobPath(dgst) + if err != nil { + return content.Info{}, errors.Wrapf(err, "calculating blob info path") + } + fi, err := os.Stat(p) if err != nil { if os.IsNotExist(err) { @@ -123,7 +127,10 @@ func (s *store) info(dgst digest.Digest, fi os.FileInfo, labels map[string]strin // ReaderAt returns an io.ReaderAt for the blob. func (s *store) ReaderAt(ctx context.Context, desc ocispec.Descriptor) (content.ReaderAt, error) { - p := s.blobPath(desc.Digest) + p, err := s.blobPath(desc.Digest) + if err != nil { + return nil, errors.Wrapf(err, "calculating blob path for ReaderAt") + } fi, err := os.Stat(p) if err != nil { if !os.IsNotExist(err) { @@ -150,7 +157,12 @@ func (s *store) ReaderAt(ctx context.Context, desc ocispec.Descriptor) (content. // While this is safe to do concurrently, safe exist-removal logic must hold // some global lock on the store. func (s *store) Delete(ctx context.Context, dgst digest.Digest) error { - if err := os.RemoveAll(s.blobPath(dgst)); err != nil { + bp, err := s.blobPath(dgst) + if err != nil { + return errors.Wrapf(err, "calculating blob path for delete") + } + + if err := os.RemoveAll(bp); err != nil { if !os.IsNotExist(err) { return err } @@ -166,7 +178,11 @@ func (s *store) Update(ctx context.Context, info content.Info, fieldpaths ...str return content.Info{}, errors.Wrapf(errdefs.ErrFailedPrecondition, "update not supported on immutable content store") } - p := s.blobPath(info.Digest) + p, err := s.blobPath(info.Digest) + if err != nil { + return content.Info{}, errors.Wrapf(err, "calculating blob path for update") + } + fi, err := os.Stat(p) if err != nil { if os.IsNotExist(err) { @@ -512,7 +528,10 @@ func (s *store) writer(ctx context.Context, ref string, total int64, expected di // TODO(stevvooe): Need to actually store expected here. We have // code in the service that shouldn't be dealing with this. if expected != "" { - p := s.blobPath(expected) + p, err := s.blobPath(expected) + if err != nil { + return nil, errors.Wrap(err, "calculating expected blob path for writer") + } if _, err := os.Stat(p); err == nil { return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "content %v", expected) } @@ -607,11 +626,17 @@ func (s *store) Abort(ctx context.Context, ref string) error { return nil } -func (s *store) blobPath(dgst digest.Digest) string { - return filepath.Join(s.root, "blobs", dgst.Algorithm().String(), dgst.Hex()) +func (s *store) blobPath(dgst digest.Digest) (string, error) { + if err := dgst.Validate(); err != nil { + return "", errors.Wrapf(errdefs.ErrInvalidArgument, "cannot calculate blob path from invalid digest: %v", err) + } + + return filepath.Join(s.root, "blobs", dgst.Algorithm().String(), dgst.Hex()), nil } func (s *store) ingestRoot(ref string) string { + // we take a digest of the ref to keep the ingest paths constant length. + // Note that this is not the current or potential digest of incoming content. dgst := digest.FromString(ref) return filepath.Join(s.root, "ingest", dgst.Hex()) } diff --git a/vendor/github.com/containerd/containerd/content/local/writer.go b/vendor/github.com/containerd/containerd/content/local/writer.go index 3a94744e7..0a11f4d91 100644 --- a/vendor/github.com/containerd/containerd/content/local/writer.go +++ b/vendor/github.com/containerd/containerd/content/local/writer.go @@ -115,8 +115,8 @@ func (w *writer) Commit(ctx context.Context, size int64, expected digest.Digest, } var ( - ingest = filepath.Join(w.path, "data") - target = w.s.blobPath(dgst) + ingest = filepath.Join(w.path, "data") + target, _ = w.s.blobPath(dgst) // ignore error because we calculated this dgst ) // make sure parent directories of blob exist diff --git a/vendor/github.com/containerd/containerd/contrib/seccomp/seccomp_default.go b/vendor/github.com/containerd/containerd/contrib/seccomp/seccomp_default.go index af40395de..d75139927 100644 --- a/vendor/github.com/containerd/containerd/contrib/seccomp/seccomp_default.go +++ b/vendor/github.com/containerd/containerd/contrib/seccomp/seccomp_default.go @@ -56,7 +56,6 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { "accept4", "access", "alarm", - "alarm", "bind", "brk", "capget", @@ -66,8 +65,11 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { "chown", "chown32", "clock_getres", + "clock_getres_time64", "clock_gettime", + "clock_gettime64", "clock_nanosleep", + "clock_nanosleep_time64", "close", "connect", "copy_file_range", @@ -117,6 +119,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { "ftruncate", "ftruncate64", "futex", + "futex_time64", "futimesat", "getcpu", "getcwd", @@ -163,6 +166,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { "io_destroy", "io_getevents", "io_pgetevents", + "io_pgetevents_time64", "ioprio_get", "ioprio_set", "io_setup", @@ -200,7 +204,9 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { "mq_notify", "mq_open", "mq_timedreceive", + "mq_timedreceive_time64", "mq_timedsend", + "mq_timedsend_time64", "mq_unlink", "mremap", "msgctl", @@ -221,11 +227,13 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { "pipe2", "poll", "ppoll", + "ppoll_time64", "prctl", "pread64", "preadv", "prlimit64", "pselect6", + "pselect6_time64", "pwrite64", "pwritev", "read", @@ -236,6 +244,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { "recv", "recvfrom", "recvmmsg", + "recvmmsg_time64", "recvmsg", "remap_file_pages", "removexattr", @@ -251,6 +260,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { "rt_sigreturn", "rt_sigsuspend", "rt_sigtimedwait", + "rt_sigtimedwait_time64", "rt_tgsigqueueinfo", "sched_getaffinity", "sched_getattr", @@ -259,6 +269,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { "sched_get_priority_min", "sched_getscheduler", "sched_rr_get_interval", + "sched_rr_get_interval_time64", "sched_setaffinity", "sched_setattr", "sched_setparam", @@ -270,6 +281,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { "semget", "semop", "semtimedop", + "semtimedop_time64", "send", "sendfile", "sendfile64", @@ -335,12 +347,16 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { "time", "timer_create", "timer_delete", - "timerfd_create", - "timerfd_gettime", - "timerfd_settime", "timer_getoverrun", "timer_gettime", + "timer_gettime64", "timer_settime", + "timer_settime64", + "timerfd_create", + "timerfd_gettime", + "timerfd_gettime64", + "timerfd_settime", + "timerfd_settime64", "times", "tkill", "truncate", @@ -352,6 +368,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { "unlinkat", "utime", "utimensat", + "utimensat_time64", "utimes", "vfork", "vmsplice", diff --git a/vendor/github.com/containerd/containerd/diff/apply/apply_linux.go b/vendor/github.com/containerd/containerd/diff/apply/apply_linux.go index bbe9c17d9..5eeeced5c 100644 --- a/vendor/github.com/containerd/containerd/diff/apply/apply_linux.go +++ b/vendor/github.com/containerd/containerd/diff/apply/apply_linux.go @@ -26,7 +26,7 @@ import ( "github.com/containerd/containerd/archive" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/mount" - "github.com/opencontainers/runc/libcontainer/system" + "github.com/containerd/containerd/sys" "github.com/pkg/errors" ) @@ -35,7 +35,7 @@ func apply(ctx context.Context, mounts []mount.Mount, r io.Reader) error { case len(mounts) == 1 && mounts[0].Type == "overlay": // OverlayConvertWhiteout (mknod c 0 0) doesn't work in userns. // https://github.com/containerd/containerd/issues/3762 - if system.RunningInUserNS() { + if sys.RunningInUserNS() { break } path, parents, err := getOverlayPath(mounts[0].Options) diff --git a/vendor/github.com/containerd/containerd/lease.go b/vendor/github.com/containerd/containerd/lease.go index 0e7619b8a..07ea6d932 100644 --- a/vendor/github.com/containerd/containerd/lease.go +++ b/vendor/github.com/containerd/containerd/lease.go @@ -25,11 +25,11 @@ import ( // WithLease attaches a lease on the context func (c *Client) WithLease(ctx context.Context, opts ...leases.Opt) (context.Context, func(context.Context) error, error) { + nop := func(context.Context) error { return nil } + _, ok := leases.FromContext(ctx) if ok { - return ctx, func(context.Context) error { - return nil - }, nil + return ctx, nop, nil } ls := c.LeasesService() @@ -44,7 +44,7 @@ func (c *Client) WithLease(ctx context.Context, opts ...leases.Opt) (context.Con l, err := ls.Create(ctx, opts...) if err != nil { - return nil, nil, err + return ctx, nop, err } ctx = leases.WithLease(ctx, l.ID) diff --git a/vendor/github.com/containerd/containerd/metrics/cgroups/v1/cgroups.go b/vendor/github.com/containerd/containerd/metrics/cgroups/v1/cgroups.go index 23e4893da..80cf20ac0 100644 --- a/vendor/github.com/containerd/containerd/metrics/cgroups/v1/cgroups.go +++ b/vendor/github.com/containerd/containerd/metrics/cgroups/v1/cgroups.go @@ -35,7 +35,7 @@ import ( // NewTaskMonitor returns a new cgroups monitor func NewTaskMonitor(ctx context.Context, publisher events.Publisher, ns *metrics.Namespace) (runtime.TaskMonitor, error) { - collector := newCollector(ns) + collector := NewCollector(ns) oom, err := newOOMCollector(ns) if err != nil { return nil, err @@ -49,7 +49,7 @@ func NewTaskMonitor(ctx context.Context, publisher events.Publisher, ns *metrics } type cgroupsMonitor struct { - collector *collector + collector *Collector oom *oomCollector context context.Context publisher events.Publisher diff --git a/vendor/github.com/containerd/containerd/metrics/cgroups/v1/metric.go b/vendor/github.com/containerd/containerd/metrics/cgroups/v1/metric.go index 14a9410b9..dd9c30314 100644 --- a/vendor/github.com/containerd/containerd/metrics/cgroups/v1/metric.go +++ b/vendor/github.com/containerd/containerd/metrics/cgroups/v1/metric.go @@ -24,6 +24,9 @@ import ( "github.com/prometheus/client_golang/prometheus" ) +// IDName is the name that is used to identify the id being collected in the metric +var IDName = "container_id" + type value struct { v float64 l []string @@ -41,7 +44,7 @@ type metric struct { func (m *metric) desc(ns *metrics.Namespace) *prometheus.Desc { // the namespace label is for containerd namespaces - return ns.NewDesc(m.name, m.help, m.unit, append([]string{"container_id", "namespace"}, m.labels...)...) + return ns.NewDesc(m.name, m.help, m.unit, append([]string{IDName, "namespace"}, m.labels...)...) } func (m *metric) collect(id, namespace string, stats *v1.Metrics, ns *metrics.Namespace, ch chan<- prometheus.Metric, block bool) { diff --git a/vendor/github.com/containerd/containerd/metrics/cgroups/v1/metrics.go b/vendor/github.com/containerd/containerd/metrics/cgroups/v1/metrics.go index e4a41edd6..eac3e26db 100644 --- a/vendor/github.com/containerd/containerd/metrics/cgroups/v1/metrics.go +++ b/vendor/github.com/containerd/containerd/metrics/cgroups/v1/metrics.go @@ -27,26 +27,33 @@ import ( "github.com/containerd/containerd/log" v1 "github.com/containerd/containerd/metrics/types/v1" "github.com/containerd/containerd/namespaces" - "github.com/containerd/containerd/runtime" "github.com/containerd/typeurl" metrics "github.com/docker/go-metrics" + "github.com/gogo/protobuf/types" "github.com/prometheus/client_golang/prometheus" ) +// Statable type that returns cgroup metrics +type Statable interface { + ID() string + Namespace() string + Stats(context.Context) (*types.Any, error) +} + // Trigger will be called when an event happens and provides the cgroup // where the event originated from type Trigger func(string, string, cgroups.Cgroup) -// newCollector registers the collector with the provided namespace and returns it so +// NewCollector registers the collector with the provided namespace and returns it so // that cgroups can be added for collection -func newCollector(ns *metrics.Namespace) *collector { +func NewCollector(ns *metrics.Namespace) *Collector { if ns == nil { - return &collector{} + return &Collector{} } // add machine cpus and memory info - c := &collector{ + c := &Collector{ ns: ns, - tasks: make(map[string]runtime.Task), + tasks: make(map[string]Statable), } c.metrics = append(c.metrics, pidMetrics...) c.metrics = append(c.metrics, cpuMetrics...) @@ -62,24 +69,26 @@ func taskID(id, namespace string) string { return fmt.Sprintf("%s-%s", id, namespace) } -// collector provides the ability to collect container stats and export +// Collector provides the ability to collect container stats and export // them in the prometheus format -type collector struct { +type Collector struct { mu sync.RWMutex - tasks map[string]runtime.Task + tasks map[string]Statable ns *metrics.Namespace metrics []*metric storedMetrics chan prometheus.Metric } -func (c *collector) Describe(ch chan<- *prometheus.Desc) { +// Describe prometheus metrics +func (c *Collector) Describe(ch chan<- *prometheus.Desc) { for _, m := range c.metrics { ch <- m.desc(c.ns) } } -func (c *collector) Collect(ch chan<- prometheus.Metric) { +// Collect prometheus metrics +func (c *Collector) Collect(ch chan<- prometheus.Metric) { c.mu.RLock() wg := &sync.WaitGroup{} for _, t := range c.tasks { @@ -100,7 +109,7 @@ storedLoop: wg.Wait() } -func (c *collector) collect(t runtime.Task, ch chan<- prometheus.Metric, block bool, wg *sync.WaitGroup) { +func (c *Collector) collect(t Statable, ch chan<- prometheus.Metric, block bool, wg *sync.WaitGroup) { if wg != nil { defer wg.Done() } @@ -126,7 +135,7 @@ func (c *collector) collect(t runtime.Task, ch chan<- prometheus.Metric, block b } // Add adds the provided cgroup and id so that metrics are collected and exported -func (c *collector) Add(t runtime.Task) error { +func (c *Collector) Add(t Statable) error { if c.ns == nil { return nil } @@ -141,11 +150,21 @@ func (c *collector) Add(t runtime.Task) error { } // Remove removes the provided cgroup by id from the collector -func (c *collector) Remove(t runtime.Task) { +func (c *Collector) Remove(t Statable) { if c.ns == nil { return } c.mu.Lock() - defer c.mu.Unlock() delete(c.tasks, taskID(t.ID(), t.Namespace())) + c.mu.Unlock() +} + +// RemoveAll statable items from the collector +func (c *Collector) RemoveAll() { + if c.ns == nil { + return + } + c.mu.Lock() + c.tasks = make(map[string]Statable) + c.mu.Unlock() } diff --git a/vendor/github.com/containerd/containerd/metrics/cgroups/v2/cgroups.go b/vendor/github.com/containerd/containerd/metrics/cgroups/v2/cgroups.go index 1f54049f1..c0bce5996 100644 --- a/vendor/github.com/containerd/containerd/metrics/cgroups/v2/cgroups.go +++ b/vendor/github.com/containerd/containerd/metrics/cgroups/v2/cgroups.go @@ -30,7 +30,7 @@ import ( // NewTaskMonitor returns a new cgroups monitor func NewTaskMonitor(ctx context.Context, publisher events.Publisher, ns *metrics.Namespace) (runtime.TaskMonitor, error) { - collector := newCollector(ns) + collector := NewCollector(ns) return &cgroupsMonitor{ collector: collector, context: ctx, @@ -39,7 +39,7 @@ func NewTaskMonitor(ctx context.Context, publisher events.Publisher, ns *metrics } type cgroupsMonitor struct { - collector *collector + collector *Collector context context.Context publisher events.Publisher } diff --git a/vendor/github.com/containerd/containerd/metrics/cgroups/v2/metric.go b/vendor/github.com/containerd/containerd/metrics/cgroups/v2/metric.go index 1b8a8e139..ea995d243 100644 --- a/vendor/github.com/containerd/containerd/metrics/cgroups/v2/metric.go +++ b/vendor/github.com/containerd/containerd/metrics/cgroups/v2/metric.go @@ -24,6 +24,9 @@ import ( "github.com/prometheus/client_golang/prometheus" ) +// IDName is the name that is used to identify the id being collected in the metric +var IDName = "container_id" + type value struct { v float64 l []string @@ -41,7 +44,7 @@ type metric struct { func (m *metric) desc(ns *metrics.Namespace) *prometheus.Desc { // the namespace label is for containerd namespaces - return ns.NewDesc(m.name, m.help, m.unit, append([]string{"container_id", "namespace"}, m.labels...)...) + return ns.NewDesc(m.name, m.help, m.unit, append([]string{IDName, "namespace"}, m.labels...)...) } func (m *metric) collect(id, namespace string, stats *v2.Metrics, ns *metrics.Namespace, ch chan<- prometheus.Metric, block bool) { diff --git a/vendor/github.com/containerd/containerd/metrics/cgroups/v2/metrics.go b/vendor/github.com/containerd/containerd/metrics/cgroups/v2/metrics.go index e352cd1fc..e8bade1a6 100644 --- a/vendor/github.com/containerd/containerd/metrics/cgroups/v2/metrics.go +++ b/vendor/github.com/containerd/containerd/metrics/cgroups/v2/metrics.go @@ -26,21 +26,28 @@ import ( "github.com/containerd/containerd/log" v2 "github.com/containerd/containerd/metrics/types/v2" "github.com/containerd/containerd/namespaces" - "github.com/containerd/containerd/runtime" "github.com/containerd/typeurl" metrics "github.com/docker/go-metrics" + "github.com/gogo/protobuf/types" "github.com/prometheus/client_golang/prometheus" ) -// newCollector registers the collector with the provided namespace and returns it so +// Statable type that returns cgroup metrics +type Statable interface { + ID() string + Namespace() string + Stats(context.Context) (*types.Any, error) +} + +// NewCollector registers the collector with the provided namespace and returns it so // that cgroups can be added for collection -func newCollector(ns *metrics.Namespace) *collector { +func NewCollector(ns *metrics.Namespace) *Collector { if ns == nil { - return &collector{} + return &Collector{} } - c := &collector{ + c := &Collector{ ns: ns, - tasks: make(map[string]runtime.Task), + tasks: make(map[string]Statable), } c.metrics = append(c.metrics, pidMetrics...) c.metrics = append(c.metrics, cpuMetrics...) @@ -55,24 +62,26 @@ func taskID(id, namespace string) string { return fmt.Sprintf("%s-%s", id, namespace) } -// collector provides the ability to collect container stats and export +// Collector provides the ability to collect container stats and export // them in the prometheus format -type collector struct { +type Collector struct { mu sync.RWMutex - tasks map[string]runtime.Task + tasks map[string]Statable ns *metrics.Namespace metrics []*metric storedMetrics chan prometheus.Metric } -func (c *collector) Describe(ch chan<- *prometheus.Desc) { +// Describe prometheus metrics +func (c *Collector) Describe(ch chan<- *prometheus.Desc) { for _, m := range c.metrics { ch <- m.desc(c.ns) } } -func (c *collector) Collect(ch chan<- prometheus.Metric) { +// Collect prometheus metrics +func (c *Collector) Collect(ch chan<- prometheus.Metric) { c.mu.RLock() wg := &sync.WaitGroup{} for _, t := range c.tasks { @@ -93,7 +102,7 @@ storedLoop: wg.Wait() } -func (c *collector) collect(t runtime.Task, ch chan<- prometheus.Metric, block bool, wg *sync.WaitGroup) { +func (c *Collector) collect(t Statable, ch chan<- prometheus.Metric, block bool, wg *sync.WaitGroup) { if wg != nil { defer wg.Done() } @@ -119,7 +128,7 @@ func (c *collector) collect(t runtime.Task, ch chan<- prometheus.Metric, block b } // Add adds the provided cgroup and id so that metrics are collected and exported -func (c *collector) Add(t runtime.Task) error { +func (c *Collector) Add(t Statable) error { if c.ns == nil { return nil } @@ -134,7 +143,7 @@ func (c *collector) Add(t runtime.Task) error { } // Remove removes the provided cgroup by id from the collector -func (c *collector) Remove(t runtime.Task) { +func (c *Collector) Remove(t Statable) { if c.ns == nil { return } @@ -142,3 +151,13 @@ func (c *collector) Remove(t runtime.Task) { defer c.mu.Unlock() delete(c.tasks, taskID(t.ID(), t.Namespace())) } + +// RemoveAll statable items from the collector +func (c *Collector) RemoveAll() { + if c.ns == nil { + return + } + c.mu.Lock() + c.tasks = make(map[string]Statable) + c.mu.Unlock() +} diff --git a/vendor/github.com/containerd/containerd/mount/mountinfo_linux.go b/vendor/github.com/containerd/containerd/mount/mountinfo_linux.go index a7407c50e..d089890fe 100644 --- a/vendor/github.com/containerd/containerd/mount/mountinfo_linux.go +++ b/vendor/github.com/containerd/containerd/mount/mountinfo_linux.go @@ -45,10 +45,6 @@ func parseInfoFile(r io.Reader) ([]Info, error) { out := []Info{} var err error for s.Scan() { - if err = s.Err(); err != nil { - return nil, err - } - /* See http://man7.org/linux/man-pages/man5/proc.5.html @@ -128,6 +124,10 @@ func parseInfoFile(r io.Reader) ([]Info, error) { out = append(out, p) } + if err = s.Err(); err != nil { + return nil, err + } + return out, nil } diff --git a/vendor/github.com/containerd/containerd/oci/spec_opts.go b/vendor/github.com/containerd/containerd/oci/spec_opts.go index 59dbfdb19..89346fe8b 100644 --- a/vendor/github.com/containerd/containerd/oci/spec_opts.go +++ b/vendor/github.com/containerd/containerd/oci/spec_opts.go @@ -1238,11 +1238,11 @@ func WithEnvFile(path string) SpecOpts { sc := bufio.NewScanner(f) for sc.Scan() { - if sc.Err() != nil { - return sc.Err() - } vars = append(vars, sc.Text()) } + if err = sc.Err(); err != nil { + return err + } return WithEnv(vars)(nil, nil, nil, s) } } diff --git a/vendor/github.com/containerd/containerd/pkg/process/io.go b/vendor/github.com/containerd/containerd/pkg/process/io.go index 28a94a5ec..9b5503497 100644 --- a/vendor/github.com/containerd/containerd/pkg/process/io.go +++ b/vendor/github.com/containerd/containerd/pkg/process/io.go @@ -29,15 +29,20 @@ import ( "sync" "sync/atomic" "syscall" + "time" "github.com/containerd/containerd/log" "github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/pkg/stdio" + "github.com/containerd/containerd/sys" "github.com/containerd/fifo" runc "github.com/containerd/go-runc" + "github.com/hashicorp/go-multierror" "github.com/pkg/errors" ) +const binaryIOProcTermTimeout = 12 * time.Second // Give logger process solid 10 seconds for cleanup + var bufPool = sync.Pool{ New: func() interface{} { // setting to 4096 to align with PIPE_BUF @@ -174,7 +179,7 @@ func copyPipes(ctx context.Context, rio runc.IO, stdin, stdout, stderr string, w }, }, } { - ok, err := isFifo(i.name) + ok, err := sys.IsFifo(i.name) if err != nil { return err } @@ -240,28 +245,13 @@ func (c *countingWriteCloser) Close() error { return c.WriteCloser.Close() } -// isFifo checks if a file is a fifo -// if the file does not exist then it returns false -func isFifo(path string) (bool, error) { - stat, err := os.Stat(path) - if err != nil { - if os.IsNotExist(err) { - return false, nil - } - return false, err - } - if stat.Mode()&os.ModeNamedPipe == os.ModeNamedPipe { - return true, nil - } - return false, nil -} - // NewBinaryIO runs a custom binary process for pluggable shim logging -func NewBinaryIO(ctx context.Context, id string, uri *url.URL) (runc.IO, error) { +func NewBinaryIO(ctx context.Context, id string, uri *url.URL) (_ runc.IO, err error) { ns, err := namespaces.NamespaceRequired(ctx) if err != nil { return nil, err } + var args []string for k, vs := range uri.Query() { args = append(args, k) @@ -269,86 +259,146 @@ func NewBinaryIO(ctx context.Context, id string, uri *url.URL) (runc.IO, error) args = append(args, vs[0]) } } - ctx, cancel := context.WithCancel(ctx) - cmd := exec.CommandContext(ctx, uri.Path, args...) + + var closers []func() error + defer func() { + if err == nil { + return + } + result := multierror.Append(err) + for _, fn := range closers { + result = multierror.Append(result, fn()) + } + err = multierror.Flatten(result) + }() + + out, err := newPipe() + if err != nil { + return nil, errors.Wrap(err, "failed to create stdout pipes") + } + closers = append(closers, out.Close) + + serr, err := newPipe() + if err != nil { + return nil, errors.Wrap(err, "failed to create stderr pipes") + } + closers = append(closers, serr.Close) + + r, w, err := os.Pipe() + if err != nil { + return nil, err + } + closers = append(closers, r.Close, w.Close) + + cmd := exec.Command(uri.Path, args...) cmd.Env = append(cmd.Env, "CONTAINER_ID="+id, "CONTAINER_NAMESPACE="+ns, ) - out, err := newPipe() - if err != nil { - cancel() - return nil, err - } - serr, err := newPipe() - if err != nil { - cancel() - return nil, err - } - r, w, err := os.Pipe() - if err != nil { - cancel() - return nil, err - } + cmd.ExtraFiles = append(cmd.ExtraFiles, out.r, serr.r, w) // don't need to register this with the reaper or wait when // running inside a shim if err := cmd.Start(); err != nil { - cancel() - return nil, err + return nil, errors.Wrap(err, "failed to start binary process") } + closers = append(closers, func() error { return cmd.Process.Kill() }) + // close our side of the pipe after start if err := w.Close(); err != nil { - cancel() - return nil, err + return nil, errors.Wrap(err, "failed to close write pipe after start") } + // wait for the logging binary to be ready b := make([]byte, 1) if _, err := r.Read(b); err != nil && err != io.EOF { - cancel() - return nil, err + return nil, errors.Wrap(err, "failed to read from logging binary") } + return &binaryIO{ - cmd: cmd, - cancel: cancel, - out: out, - err: serr, + cmd: cmd, + out: out, + err: serr, }, nil } type binaryIO struct { cmd *exec.Cmd - cancel func() out, err *pipe } -func (b *binaryIO) CloseAfterStart() (err error) { - for _, v := range []*pipe{ - b.out, - b.err, - } { +func (b *binaryIO) CloseAfterStart() error { + var ( + result *multierror.Error + ) + + for _, v := range []*pipe{b.out, b.err} { if v != nil { - if cerr := v.r.Close(); err == nil { - err = cerr + if err := v.r.Close(); err != nil { + result = multierror.Append(result, err) } } } - return err + + return result.ErrorOrNil() } -func (b *binaryIO) Close() (err error) { - b.cancel() - for _, v := range []*pipe{ - b.out, - b.err, - } { +func (b *binaryIO) Close() error { + var ( + result *multierror.Error + ) + + for _, v := range []*pipe{b.out, b.err} { if v != nil { - if cerr := v.Close(); err == nil { - err = cerr + if err := v.Close(); err != nil { + result = multierror.Append(result, err) } } } - return err + + if err := b.cancel(); err != nil { + result = multierror.Append(result, err) + } + + return result.ErrorOrNil() +} + +func (b *binaryIO) cancel() error { + if b.cmd == nil || b.cmd.Process == nil { + return nil + } + + // Send SIGTERM first, so logger process has a chance to flush and exit properly + if err := b.cmd.Process.Signal(syscall.SIGTERM); err != nil { + result := multierror.Append(errors.Wrap(err, "failed to send SIGTERM")) + + log.L.WithError(err).Warn("failed to send SIGTERM signal, killing logging shim") + + if err := b.cmd.Process.Kill(); err != nil { + result = multierror.Append(result, errors.Wrap(err, "failed to kill process after faulty SIGTERM")) + } + + return result.ErrorOrNil() + } + + done := make(chan error) + go func() { + done <- b.cmd.Wait() + }() + + select { + case err := <-done: + return err + case <-time.After(binaryIOProcTermTimeout): + log.L.Warn("failed to wait for shim logger process to exit, killing") + + err := b.cmd.Process.Kill() + if err != nil { + return errors.Wrap(err, "failed to kill shim logger process") + } + + return nil + } } func (b *binaryIO) Stdin() io.WriteCloser { @@ -389,9 +439,15 @@ type pipe struct { } func (p *pipe) Close() error { - err := p.w.Close() - if rerr := p.r.Close(); err == nil { - err = rerr + var result *multierror.Error + + if err := p.w.Close(); err != nil { + result = multierror.Append(result, errors.Wrap(err, "failed to close write pipe")) } - return err + + if err := p.r.Close(); err != nil { + result = multierror.Append(result, errors.Wrap(err, "failed to close read pipe")) + } + + return multierror.Prefix(result.ErrorOrNil(), "pipe:") } diff --git a/vendor/github.com/containerd/containerd/pkg/ttrpcutil/client.go b/vendor/github.com/containerd/containerd/pkg/ttrpcutil/client.go index 5edb19dc3..8b4d925d2 100644 --- a/vendor/github.com/containerd/containerd/pkg/ttrpcutil/client.go +++ b/vendor/github.com/containerd/containerd/pkg/ttrpcutil/client.go @@ -50,14 +50,8 @@ func NewClient(address string, opts ...ttrpc.ClientOpts) (*Client, error) { return client, nil } - client, err := connector() - if err != nil { - return nil, err - } - return &Client{ connector: connector, - client: client, }, nil } @@ -74,6 +68,12 @@ func (c *Client) Reconnect() error { return errors.New("client is closed") } + if c.client != nil { + if err := c.client.Close(); err != nil { + return err + } + } + client, err := c.connector() if err != nil { return err @@ -84,16 +84,26 @@ func (c *Client) Reconnect() error { } // EventsService creates an EventsService client -func (c *Client) EventsService() v1.EventsService { - return v1.NewEventsClient(c.Client()) +func (c *Client) EventsService() (v1.EventsService, error) { + client, err := c.Client() + if err != nil { + return nil, err + } + return v1.NewEventsClient(client), nil } // Client returns the underlying TTRPC client object -func (c *Client) Client() *ttrpc.Client { +func (c *Client) Client() (*ttrpc.Client, error) { c.mu.Lock() defer c.mu.Unlock() - - return c.client + if c.client == nil { + client, err := c.connector() + if err != nil { + return nil, err + } + c.client = client + } + return c.client, nil } // Close closes the clients TTRPC connection to containerd @@ -102,5 +112,8 @@ func (c *Client) Close() error { defer c.mu.Unlock() c.closed = true - return c.client.Close() + if c.client != nil { + return c.client.Close() + } + return nil } diff --git a/vendor/github.com/containerd/containerd/pull.go b/vendor/github.com/containerd/containerd/pull.go index c4cd919b5..f1ee7ff67 100644 --- a/vendor/github.com/containerd/containerd/pull.go +++ b/vendor/github.com/containerd/containerd/pull.go @@ -72,7 +72,7 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (_ Ima if err != nil { return nil, errors.Wrap(err, "create unpacker") } - unpackWrapper, unpackEg = u.handlerWrapper(ctx, &unpacks) + unpackWrapper, unpackEg = u.handlerWrapper(ctx, pullCtx, &unpacks) defer func() { if err := unpackEg.Wait(); err != nil { if retErr == nil { diff --git a/vendor/github.com/containerd/containerd/rootfs/apply.go b/vendor/github.com/containerd/containerd/rootfs/apply.go index 73d4ccca5..1db1bf14c 100644 --- a/vendor/github.com/containerd/containerd/rootfs/apply.go +++ b/vendor/github.com/containerd/containerd/rootfs/apply.go @@ -129,7 +129,7 @@ func applyLayers(ctx context.Context, layers []Layer, chain []digest.Digest, sn mounts, err = sn.Prepare(ctx, key, parent.String(), opts...) if err != nil { if errdefs.IsNotFound(err) && len(layers) > 1 { - if err := applyLayers(ctx, layers[:len(layers)-1], chain[:len(chain)-1], sn, a, nil, applyOpts); err != nil { + if err := applyLayers(ctx, layers[:len(layers)-1], chain[:len(chain)-1], sn, a, opts, applyOpts); err != nil { if !errdefs.IsAlreadyExists(err) { return err } diff --git a/vendor/github.com/containerd/containerd/runtime/v1/shim/service.go b/vendor/github.com/containerd/containerd/runtime/v1/shim/service.go index c0ec03931..6bd6aefa2 100644 --- a/vendor/github.com/containerd/containerd/runtime/v1/shim/service.go +++ b/vendor/github.com/containerd/containerd/runtime/v1/shim/service.go @@ -503,42 +503,37 @@ func (s *Service) processExits() { } } -func (s *Service) allProcesses() []process.Process { - s.mu.Lock() - defer s.mu.Unlock() - - res := make([]process.Process, 0, len(s.processes)) - for _, p := range s.processes { - res = append(res, p) - } - return res -} - func (s *Service) checkProcesses(e runc.Exit) { - for _, p := range s.allProcesses() { - if p.Pid() != e.Pid { - continue + var p process.Process + s.mu.Lock() + for _, proc := range s.processes { + if proc.Pid() == e.Pid { + p = proc + break } - - if ip, ok := p.(*process.Init); ok { - // Ensure all children are killed - if shouldKillAllOnExit(s.context, s.bundle) { - if err := ip.KillAll(s.context); err != nil { - log.G(s.context).WithError(err).WithField("id", ip.ID()). - Error("failed to kill init's children") - } + } + s.mu.Unlock() + if p == nil { + log.G(s.context).Infof("process with id:%d wasn't found", e.Pid) + return + } + if ip, ok := p.(*process.Init); ok { + // Ensure all children are killed + if shouldKillAllOnExit(s.context, s.bundle) { + if err := ip.KillAll(s.context); err != nil { + log.G(s.context).WithError(err).WithField("id", ip.ID()). + Error("failed to kill init's children") } } + } - p.SetExited(e.Status) - s.events <- &eventstypes.TaskExit{ - ContainerID: s.id, - ID: p.ID(), - Pid: uint32(e.Pid), - ExitStatus: uint32(e.Status), - ExitedAt: p.ExitedAt(), - } - return + p.SetExited(e.Status) + s.events <- &eventstypes.TaskExit{ + ContainerID: s.id, + ID: p.ID(), + Pid: uint32(e.Pid), + ExitStatus: uint32(e.Status), + ExitedAt: p.ExitedAt(), } } diff --git a/vendor/github.com/containerd/containerd/runtime/v2/README.md b/vendor/github.com/containerd/containerd/runtime/v2/README.md index 76d30373f..aaa878bfd 100644 --- a/vendor/github.com/containerd/containerd/runtime/v2/README.md +++ b/vendor/github.com/containerd/containerd/runtime/v2/README.md @@ -227,9 +227,6 @@ func copy(wg *sync.WaitGroup, r io.Reader, pri journal.Priority, vars map[string defer wg.Done() s := bufio.NewScanner(r) for s.Scan() { - if s.Err() != nil { - return - } journal.Send(s.Text(), pri, vars) } } diff --git a/vendor/github.com/containerd/containerd/runtime/v2/shim.go b/vendor/github.com/containerd/containerd/runtime/v2/shim.go index 48e411d2c..abb71621f 100644 --- a/vendor/github.com/containerd/containerd/runtime/v2/shim.go +++ b/vendor/github.com/containerd/containerd/runtime/v2/shim.go @@ -226,9 +226,12 @@ func (s *shim) Delete(ctx context.Context) (*runtime.Exit, error) { ID: s.ID(), }) if shimErr != nil { - shimErr = errdefs.FromGRPC(shimErr) - if !errdefs.IsNotFound(shimErr) { - return nil, shimErr + log.G(ctx).WithField("id", s.ID()).WithError(shimErr).Debug("failed to delete task") + if errors.Cause(shimErr) != ttrpc.ErrClosed { + shimErr = errdefs.FromGRPC(shimErr) + if !errdefs.IsNotFound(shimErr) { + return nil, shimErr + } } } // remove self from the runtime task list diff --git a/vendor/github.com/containerd/containerd/runtime/v2/shim/publisher.go b/vendor/github.com/containerd/containerd/runtime/v2/shim/publisher.go index 3dbd0e045..c5c4ecc15 100644 --- a/vendor/github.com/containerd/containerd/runtime/v2/shim/publisher.go +++ b/vendor/github.com/containerd/containerd/runtime/v2/shim/publisher.go @@ -128,9 +128,12 @@ func (l *RemoteEventsPublisher) Publish(ctx context.Context, topic string, event } func (l *RemoteEventsPublisher) forwardRequest(ctx context.Context, req *v1.ForwardRequest) error { - _, err := l.client.EventsService().Forward(ctx, req) + service, err := l.client.EventsService() if err == nil { - return nil + _, err = service.Forward(ctx, req) + if err == nil { + return nil + } } if err != ttrpc.ErrClosed { @@ -138,11 +141,15 @@ func (l *RemoteEventsPublisher) forwardRequest(ctx context.Context, req *v1.Forw } // Reconnect and retry request - if err := l.client.Reconnect(); err != nil { + if err = l.client.Reconnect(); err != nil { return err } - if _, err := l.client.EventsService().Forward(ctx, req); err != nil { + service, err = l.client.EventsService() + if err != nil { + return err + } + if _, err = service.Forward(ctx, req); err != nil { return err } diff --git a/vendor/github.com/containerd/containerd/runtime/v2/shim/shim.go b/vendor/github.com/containerd/containerd/runtime/v2/shim/shim.go index d540aa87e..026ebb4e2 100644 --- a/vendor/github.com/containerd/containerd/runtime/v2/shim/shim.go +++ b/vendor/github.com/containerd/containerd/runtime/v2/shim/shim.go @@ -31,6 +31,7 @@ import ( "github.com/containerd/containerd/log" "github.com/containerd/containerd/namespaces" shimapi "github.com/containerd/containerd/runtime/v2/task" + "github.com/containerd/containerd/version" "github.com/containerd/ttrpc" "github.com/gogo/protobuf/proto" "github.com/pkg/errors" @@ -84,6 +85,7 @@ type Config struct { var ( debugFlag bool + versionFlag bool idFlag string namespaceFlag string socketFlag string @@ -99,6 +101,7 @@ const ( func parseFlags() { flag.BoolVar(&debugFlag, "debug", false, "enable debug output in logs") + flag.BoolVar(&versionFlag, "v", false, "show the shim version and exit") flag.StringVar(&namespaceFlag, "namespace", "", "namespace that owns the shim") flag.StringVar(&idFlag, "id", "", "id of the task") flag.StringVar(&socketFlag, "socket", "", "abstract socket path to serve") @@ -155,6 +158,15 @@ func Run(id string, initFunc Init, opts ...BinaryOpts) { func run(id string, initFunc Init, config Config) error { parseFlags() + if versionFlag { + fmt.Printf("%s:\n", os.Args[0]) + fmt.Println(" Version: ", version.Version) + fmt.Println(" Revision:", version.Revision) + fmt.Println(" Go version:", version.GoVersion) + fmt.Println("") + return nil + } + setRuntime() signals, err := setupSignals(config) diff --git a/vendor/github.com/containerd/containerd/runtime/v2/shim/shim_linux.go b/vendor/github.com/containerd/containerd/runtime/v2/shim/shim_linux.go index 7ad2a7262..06266a533 100644 --- a/vendor/github.com/containerd/containerd/runtime/v2/shim/shim_linux.go +++ b/vendor/github.com/containerd/containerd/runtime/v2/shim/shim_linux.go @@ -17,7 +17,7 @@ package shim import ( - "github.com/containerd/containerd/sys" + "github.com/containerd/containerd/sys/reaper" "github.com/containerd/ttrpc" ) @@ -26,5 +26,5 @@ func newServer() (*ttrpc.Server, error) { } func subreaper() error { - return sys.SetSubreaper(1) + return reaper.SetSubreaper(1) } diff --git a/vendor/github.com/containerd/containerd/signals_unix.go b/vendor/github.com/containerd/containerd/signals_unix.go index 00aa7ca4b..14916a9ff 100644 --- a/vendor/github.com/containerd/containerd/signals_unix.go +++ b/vendor/github.com/containerd/containerd/signals_unix.go @@ -33,11 +33,7 @@ import ( func ParseSignal(rawSignal string) (syscall.Signal, error) { s, err := strconv.Atoi(rawSignal) if err == nil { - signal := syscall.Signal(s) - if unix.SignalName(signal) != "" { - return signal, nil - } - return -1, fmt.Errorf("unknown signal %q", rawSignal) + return syscall.Signal(s), nil } signal := unix.SignalNum(strings.ToUpper(rawSignal)) if signal == 0 { diff --git a/vendor/github.com/containerd/containerd/snapshots/snapshotter.go b/vendor/github.com/containerd/containerd/snapshots/snapshotter.go index edf29d89e..168560e14 100644 --- a/vendor/github.com/containerd/containerd/snapshots/snapshotter.go +++ b/vendor/github.com/containerd/containerd/snapshots/snapshotter.go @@ -355,10 +355,17 @@ type Cleaner interface { // Opt allows setting mutable snapshot properties on creation type Opt func(info *Info) error -// WithLabels adds labels to a created snapshot +// WithLabels appends labels to a created snapshot func WithLabels(labels map[string]string) Opt { return func(info *Info) error { - info.Labels = labels + if info.Labels == nil { + info.Labels = make(map[string]string) + } + + for k, v := range labels { + info.Labels[k] = v + } + return nil } } diff --git a/vendor/github.com/containerd/containerd/sys/epoll.go b/vendor/github.com/containerd/containerd/sys/epoll.go index 683f38eea..28d6c2cab 100644 --- a/vendor/github.com/containerd/containerd/sys/epoll.go +++ b/vendor/github.com/containerd/containerd/sys/epoll.go @@ -20,17 +20,14 @@ package sys import "golang.org/x/sys/unix" -// EpollCreate1 directly calls unix.EpollCreate1 -func EpollCreate1(flag int) (int, error) { - return unix.EpollCreate1(flag) -} +// EpollCreate1 is an alias for unix.EpollCreate1 +// Deprecated: use golang.org/x/sys/unix.EpollCreate1 +var EpollCreate1 = unix.EpollCreate1 -// EpollCtl directly calls unix.EpollCtl -func EpollCtl(epfd int, op int, fd int, event *unix.EpollEvent) error { - return unix.EpollCtl(epfd, op, fd, event) -} +// EpollCtl is an alias for unix.EpollCtl +// Deprecated: use golang.org/x/sys/unix.EpollCtl +var EpollCtl = unix.EpollCtl -// EpollWait directly calls unix.EpollWait -func EpollWait(epfd int, events []unix.EpollEvent, msec int) (int, error) { - return unix.EpollWait(epfd, events, msec) -} +// EpollWait is an alias for unix.EpollWait +// Deprecated: use golang.org/x/sys/unix.EpollWait +var EpollWait = unix.EpollWait diff --git a/vendor/github.com/containerd/containerd/sys/filesys.go b/vendor/github.com/containerd/containerd/sys/filesys.go new file mode 100644 index 000000000..825d21d19 --- /dev/null +++ b/vendor/github.com/containerd/containerd/sys/filesys.go @@ -0,0 +1,35 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package sys + +import "os" + +// IsFifo checks if a file is a (named pipe) fifo +// if the file does not exist then it returns false +func IsFifo(path string) (bool, error) { + stat, err := os.Stat(path) + if err != nil { + if os.IsNotExist(err) { + return false, nil + } + return false, err + } + if stat.Mode()&os.ModeNamedPipe == os.ModeNamedPipe { + return true, nil + } + return false, nil +} diff --git a/vendor/github.com/containerd/containerd/sys/filesys_windows.go b/vendor/github.com/containerd/containerd/sys/filesys_windows.go index 1bdc5317a..2eaee2ca2 100644 --- a/vendor/github.com/containerd/containerd/sys/filesys_windows.go +++ b/vendor/github.com/containerd/containerd/sys/filesys_windows.go @@ -26,8 +26,8 @@ import ( "syscall" "unsafe" - winio "github.com/Microsoft/go-winio" "github.com/Microsoft/hcsshim" + "golang.org/x/sys/windows" ) const ( @@ -41,7 +41,8 @@ func MkdirAllWithACL(path string, perm os.FileMode) error { return mkdirall(path, true) } -// MkdirAll implementation that is volume path aware for Windows. +// MkdirAll implementation that is volume path aware for Windows. It can be used +// as a drop-in replacement for os.MkdirAll() func MkdirAll(path string, _ os.FileMode) error { return mkdirall(path, false) } @@ -111,26 +112,26 @@ func mkdirall(path string, adminAndLocalSystem bool) error { // mkdirWithACL creates a new directory. If there is an error, it will be of // type *PathError. . // -// This is a modified and combined version of os.Mkdir and syscall.Mkdir +// This is a modified and combined version of os.Mkdir and windows.Mkdir // in golang to cater for creating a directory am ACL permitting full // access, with inheritance, to any subfolder/file for Built-in Administrators // and Local System. func mkdirWithACL(name string) error { - sa := syscall.SecurityAttributes{Length: 0} - sd, err := winio.SddlToSecurityDescriptor(SddlAdministratorsLocalSystem) + sa := windows.SecurityAttributes{Length: 0} + sd, err := windows.SecurityDescriptorFromString(SddlAdministratorsLocalSystem) if err != nil { return &os.PathError{Op: "mkdir", Path: name, Err: err} } sa.Length = uint32(unsafe.Sizeof(sa)) sa.InheritHandle = 1 - sa.SecurityDescriptor = uintptr(unsafe.Pointer(&sd[0])) + sa.SecurityDescriptor = sd - namep, err := syscall.UTF16PtrFromString(name) + namep, err := windows.UTF16PtrFromString(name) if err != nil { return &os.PathError{Op: "mkdir", Path: name, Err: err} } - e := syscall.CreateDirectory(namep, &sa) + e := windows.CreateDirectory(namep, &sa) if e != nil { return &os.PathError{Op: "mkdir", Path: name, Err: e} } @@ -153,7 +154,7 @@ func IsAbs(path string) bool { return true } -// The origin of the functions below here are the golang OS and syscall packages, +// The origin of the functions below here are the golang OS and windows packages, // slightly modified to only cope with files, not directories due to the // specific use case. // @@ -185,74 +186,74 @@ func OpenFileSequential(name string, flag int, _ os.FileMode) (*os.File, error) if name == "" { return nil, &os.PathError{Op: "open", Path: name, Err: syscall.ENOENT} } - r, errf := syscallOpenFileSequential(name, flag, 0) + r, errf := windowsOpenFileSequential(name, flag, 0) if errf == nil { return r, nil } return nil, &os.PathError{Op: "open", Path: name, Err: errf} } -func syscallOpenFileSequential(name string, flag int, _ os.FileMode) (file *os.File, err error) { - r, e := syscallOpenSequential(name, flag|syscall.O_CLOEXEC, 0) +func windowsOpenFileSequential(name string, flag int, _ os.FileMode) (file *os.File, err error) { + r, e := windowsOpenSequential(name, flag|windows.O_CLOEXEC, 0) if e != nil { return nil, e } return os.NewFile(uintptr(r), name), nil } -func makeInheritSa() *syscall.SecurityAttributes { - var sa syscall.SecurityAttributes +func makeInheritSa() *windows.SecurityAttributes { + var sa windows.SecurityAttributes sa.Length = uint32(unsafe.Sizeof(sa)) sa.InheritHandle = 1 return &sa } -func syscallOpenSequential(path string, mode int, _ uint32) (fd syscall.Handle, err error) { +func windowsOpenSequential(path string, mode int, _ uint32) (fd windows.Handle, err error) { if len(path) == 0 { - return syscall.InvalidHandle, syscall.ERROR_FILE_NOT_FOUND + return windows.InvalidHandle, windows.ERROR_FILE_NOT_FOUND } - pathp, err := syscall.UTF16PtrFromString(path) + pathp, err := windows.UTF16PtrFromString(path) if err != nil { - return syscall.InvalidHandle, err + return windows.InvalidHandle, err } var access uint32 - switch mode & (syscall.O_RDONLY | syscall.O_WRONLY | syscall.O_RDWR) { - case syscall.O_RDONLY: - access = syscall.GENERIC_READ - case syscall.O_WRONLY: - access = syscall.GENERIC_WRITE - case syscall.O_RDWR: - access = syscall.GENERIC_READ | syscall.GENERIC_WRITE + switch mode & (windows.O_RDONLY | windows.O_WRONLY | windows.O_RDWR) { + case windows.O_RDONLY: + access = windows.GENERIC_READ + case windows.O_WRONLY: + access = windows.GENERIC_WRITE + case windows.O_RDWR: + access = windows.GENERIC_READ | windows.GENERIC_WRITE } - if mode&syscall.O_CREAT != 0 { - access |= syscall.GENERIC_WRITE + if mode&windows.O_CREAT != 0 { + access |= windows.GENERIC_WRITE } - if mode&syscall.O_APPEND != 0 { - access &^= syscall.GENERIC_WRITE - access |= syscall.FILE_APPEND_DATA + if mode&windows.O_APPEND != 0 { + access &^= windows.GENERIC_WRITE + access |= windows.FILE_APPEND_DATA } - sharemode := uint32(syscall.FILE_SHARE_READ | syscall.FILE_SHARE_WRITE) - var sa *syscall.SecurityAttributes - if mode&syscall.O_CLOEXEC == 0 { + sharemode := uint32(windows.FILE_SHARE_READ | windows.FILE_SHARE_WRITE) + var sa *windows.SecurityAttributes + if mode&windows.O_CLOEXEC == 0 { sa = makeInheritSa() } var createmode uint32 switch { - case mode&(syscall.O_CREAT|syscall.O_EXCL) == (syscall.O_CREAT | syscall.O_EXCL): - createmode = syscall.CREATE_NEW - case mode&(syscall.O_CREAT|syscall.O_TRUNC) == (syscall.O_CREAT | syscall.O_TRUNC): - createmode = syscall.CREATE_ALWAYS - case mode&syscall.O_CREAT == syscall.O_CREAT: - createmode = syscall.OPEN_ALWAYS - case mode&syscall.O_TRUNC == syscall.O_TRUNC: - createmode = syscall.TRUNCATE_EXISTING + case mode&(windows.O_CREAT|windows.O_EXCL) == (windows.O_CREAT | windows.O_EXCL): + createmode = windows.CREATE_NEW + case mode&(windows.O_CREAT|windows.O_TRUNC) == (windows.O_CREAT | windows.O_TRUNC): + createmode = windows.CREATE_ALWAYS + case mode&windows.O_CREAT == windows.O_CREAT: + createmode = windows.OPEN_ALWAYS + case mode&windows.O_TRUNC == windows.O_TRUNC: + createmode = windows.TRUNCATE_EXISTING default: - createmode = syscall.OPEN_EXISTING + createmode = windows.OPEN_EXISTING } // Use FILE_FLAG_SEQUENTIAL_SCAN rather than FILE_ATTRIBUTE_NORMAL as implemented in golang. - //https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx + // https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx const fileFlagSequentialScan = 0x08000000 // FILE_FLAG_SEQUENTIAL_SCAN - h, e := syscall.CreateFile(pathp, access, sharemode, sa, createmode, fileFlagSequentialScan, 0) + h, e := windows.CreateFile(pathp, access, sharemode, sa, createmode, fileFlagSequentialScan, 0) return h, e } diff --git a/vendor/github.com/containerd/containerd/sys/mount_linux.go b/vendor/github.com/containerd/containerd/sys/mount_linux.go index a9eee9b73..a21045529 100644 --- a/vendor/github.com/containerd/containerd/sys/mount_linux.go +++ b/vendor/github.com/containerd/containerd/sys/mount_linux.go @@ -21,6 +21,7 @@ import ( "syscall" "unsafe" + "github.com/containerd/containerd/log" "github.com/pkg/errors" "golang.org/x/sys/unix" ) @@ -30,9 +31,8 @@ func FMountat(dirfd uintptr, source, target, fstype string, flags uintptr, data var ( sourceP, targetP, fstypeP, dataP *byte pid uintptr - ws unix.WaitStatus err error - errno syscall.Errno + errno, status syscall.Errno ) sourceP, err = syscall.BytePtrFromString(source) @@ -60,37 +60,62 @@ func FMountat(dirfd uintptr, source, target, fstype string, flags uintptr, data runtime.LockOSThread() defer runtime.UnlockOSThread() + var pipefds [2]int + if err := syscall.Pipe2(pipefds[:], syscall.O_CLOEXEC); err != nil { + return errors.Wrap(err, "failed to open pipe") + } + + defer func() { + // close both ends of the pipe in a deferred function, since open file + // descriptor table is shared with child + syscall.Close(pipefds[0]) + syscall.Close(pipefds[1]) + }() + pid, errno = forkAndMountat(dirfd, uintptr(unsafe.Pointer(sourceP)), uintptr(unsafe.Pointer(targetP)), uintptr(unsafe.Pointer(fstypeP)), flags, - uintptr(unsafe.Pointer(dataP))) + uintptr(unsafe.Pointer(dataP)), + pipefds[1], + ) if errno != 0 { return errors.Wrap(errno, "failed to fork thread") } - _, err = unix.Wait4(int(pid), &ws, 0, nil) - for err == syscall.EINTR { - _, err = unix.Wait4(int(pid), &ws, 0, nil) - } + defer func() { + _, err := unix.Wait4(int(pid), nil, 0, nil) + for err == syscall.EINTR { + _, err = unix.Wait4(int(pid), nil, 0, nil) + } - if err != nil { - return errors.Wrapf(err, "failed to find pid=%d process", pid) - } + if err != nil { + log.L.WithError(err).Debugf("failed to find pid=%d process", pid) + } + }() - errno = syscall.Errno(ws.ExitStatus()) + _, _, errno = syscall.RawSyscall(syscall.SYS_READ, + uintptr(pipefds[0]), + uintptr(unsafe.Pointer(&status)), + unsafe.Sizeof(status)) if errno != 0 { - return errors.Wrap(errno, "failed to mount") + return errors.Wrap(errno, "failed to read pipe") } + + if status != 0 { + return errors.Wrap(status, "failed to mount") + } + return nil } // forkAndMountat will fork thread, change working dir and mount. // // precondition: the runtime OS thread must be locked. -func forkAndMountat(dirfd uintptr, source, target, fstype, flags, data uintptr) (pid uintptr, errno syscall.Errno) { +func forkAndMountat(dirfd uintptr, source, target, fstype, flags, data uintptr, pipefd int) (pid uintptr, errno syscall.Errno) { + // block signal during clone beforeFork() @@ -114,6 +139,7 @@ func forkAndMountat(dirfd uintptr, source, target, fstype, flags, data uintptr) _, _, errno = syscall.RawSyscall6(syscall.SYS_MOUNT, source, target, fstype, flags, data, 0) childerr: + _, _, errno = syscall.RawSyscall(syscall.SYS_WRITE, uintptr(pipefd), uintptr(unsafe.Pointer(&errno)), unsafe.Sizeof(errno)) syscall.RawSyscall(syscall.SYS_EXIT, uintptr(errno), 0, 0) panic("unreachable") } diff --git a/vendor/github.com/containerd/containerd/sys/oom_unix.go b/vendor/github.com/containerd/containerd/sys/oom_unix.go index 54412e9c3..d49d5bc8d 100644 --- a/vendor/github.com/containerd/containerd/sys/oom_unix.go +++ b/vendor/github.com/containerd/containerd/sys/oom_unix.go @@ -24,8 +24,6 @@ import ( "os" "strconv" "strings" - - "github.com/opencontainers/runc/libcontainer/system" ) // OOMScoreMaxKillable is the maximum score keeping the process killable by the oom killer @@ -40,7 +38,7 @@ func SetOOMScore(pid, score int) error { } defer f.Close() if _, err = f.WriteString(strconv.Itoa(score)); err != nil { - if os.IsPermission(err) && (system.RunningInUserNS() || RunningUnprivileged()) { + if os.IsPermission(err) && (RunningInUserNS() || RunningUnprivileged()) { return nil } return err diff --git a/vendor/github.com/containerd/containerd/sys/proc.go b/vendor/github.com/containerd/containerd/sys/proc.go deleted file mode 100644 index 496eb1fea..000000000 --- a/vendor/github.com/containerd/containerd/sys/proc.go +++ /dev/null @@ -1,80 +0,0 @@ -// +build linux - -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package sys - -import ( - "bufio" - "fmt" - "os" - "strconv" - "strings" - - "github.com/opencontainers/runc/libcontainer/system" -) - -const nanoSecondsPerSecond = 1e9 - -var clockTicksPerSecond = uint64(system.GetClockTicks()) - -// GetSystemCPUUsage returns the host system's cpu usage in -// nanoseconds. An error is returned if the format of the underlying -// file does not match. -// -// Uses /proc/stat defined by POSIX. Looks for the cpu -// statistics line and then sums up the first seven fields -// provided. See `man 5 proc` for details on specific field -// information. -func GetSystemCPUUsage() (uint64, error) { - var line string - f, err := os.Open("/proc/stat") - if err != nil { - return 0, err - } - bufReader := bufio.NewReaderSize(nil, 128) - defer func() { - bufReader.Reset(nil) - f.Close() - }() - bufReader.Reset(f) - err = nil - for err == nil { - line, err = bufReader.ReadString('\n') - if err != nil { - break - } - parts := strings.Fields(line) - switch parts[0] { - case "cpu": - if len(parts) < 8 { - return 0, fmt.Errorf("bad format of cpu stats") - } - var totalClockTicks uint64 - for _, i := range parts[1:8] { - v, err := strconv.ParseUint(i, 10, 64) - if err != nil { - return 0, fmt.Errorf("error parsing cpu stats") - } - totalClockTicks += v - } - return (totalClockTicks * nanoSecondsPerSecond) / - clockTicksPerSecond, nil - } - } - return 0, fmt.Errorf("bad stats format") -} diff --git a/vendor/github.com/containerd/containerd/sys/reaper.go b/vendor/github.com/containerd/containerd/sys/reaper.go deleted file mode 100644 index d08ccccfb..000000000 --- a/vendor/github.com/containerd/containerd/sys/reaper.go +++ /dev/null @@ -1,69 +0,0 @@ -// +build !windows - -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package sys - -import ( - "golang.org/x/sys/unix" -) - -// Exit is the wait4 information from an exited process -type Exit struct { - Pid int - Status int -} - -// Reap reaps all child processes for the calling process and returns their -// exit information -func Reap(wait bool) (exits []Exit, err error) { - var ( - ws unix.WaitStatus - rus unix.Rusage - ) - flag := unix.WNOHANG - if wait { - flag = 0 - } - for { - pid, err := unix.Wait4(-1, &ws, flag, &rus) - if err != nil { - if err == unix.ECHILD { - return exits, nil - } - return exits, err - } - if pid <= 0 { - return exits, nil - } - exits = append(exits, Exit{ - Pid: pid, - Status: exitStatus(ws), - }) - } -} - -const exitSignalOffset = 128 - -// exitStatus returns the correct exit status for a process based on if it -// was signaled or exited cleanly -func exitStatus(status unix.WaitStatus) int { - if status.Signaled() { - return exitSignalOffset + int(status.Signal()) - } - return status.ExitStatus() -} diff --git a/vendor/github.com/containerd/containerd/sys/reaper/reaper_unix.go b/vendor/github.com/containerd/containerd/sys/reaper/reaper_unix.go index baab9740b..0033178df 100644 --- a/vendor/github.com/containerd/containerd/sys/reaper/reaper_unix.go +++ b/vendor/github.com/containerd/containerd/sys/reaper/reaper_unix.go @@ -23,9 +23,9 @@ import ( "sync" "time" - "github.com/containerd/containerd/sys" runc "github.com/containerd/go-runc" "github.com/pkg/errors" + "golang.org/x/sys/unix" ) // ErrNoSuchProcess is returned when the process no longer exists @@ -60,7 +60,7 @@ func (s *subscriber) do(fn func()) { // all exited processes and close their wait channels func Reap() error { now := time.Now() - exits, err := sys.Reap(false) + exits, err := reap(false) for _, e := range exits { done := Default.notify(runc.Exit{ Timestamp: now, @@ -200,3 +200,49 @@ func stop(timer *time.Timer, recv bool) { <-timer.C } } + +// exit is the wait4 information from an exited process +type exit struct { + Pid int + Status int +} + +// reap reaps all child processes for the calling process and returns their +// exit information +func reap(wait bool) (exits []exit, err error) { + var ( + ws unix.WaitStatus + rus unix.Rusage + ) + flag := unix.WNOHANG + if wait { + flag = 0 + } + for { + pid, err := unix.Wait4(-1, &ws, flag, &rus) + if err != nil { + if err == unix.ECHILD { + return exits, nil + } + return exits, err + } + if pid <= 0 { + return exits, nil + } + exits = append(exits, exit{ + Pid: pid, + Status: exitStatus(ws), + }) + } +} + +const exitSignalOffset = 128 + +// exitStatus returns the correct exit status for a process based on if it +// was signaled or exited cleanly +func exitStatus(status unix.WaitStatus) int { + if status.Signaled() { + return exitSignalOffset + int(status.Signal()) + } + return status.ExitStatus() +} diff --git a/vendor/github.com/containerd/containerd/sys/reaper_linux.go b/vendor/github.com/containerd/containerd/sys/reaper/reaper_utils_linux.go similarity index 57% rename from vendor/github.com/containerd/containerd/sys/reaper_linux.go rename to vendor/github.com/containerd/containerd/sys/reaper/reaper_utils_linux.go index ecb0bd031..cadcdc42c 100644 --- a/vendor/github.com/containerd/containerd/sys/reaper_linux.go +++ b/vendor/github.com/containerd/containerd/sys/reaper/reaper_utils_linux.go @@ -14,7 +14,7 @@ limitations under the License. */ -package sys +package reaper import ( "unsafe" @@ -22,22 +22,9 @@ import ( "golang.org/x/sys/unix" ) -// If arg2 is nonzero, set the "child subreaper" attribute of the -// calling process; if arg2 is zero, unset the attribute. When a -// process is marked as a child subreaper, all of the children -// that it creates, and their descendants, will be marked as -// having a subreaper. In effect, a subreaper fulfills the role -// of init(1) for its descendant processes. Upon termination of -// a process that is orphaned (i.e., its immediate parent has -// already terminated) and marked as having a subreaper, the -// nearest still living ancestor subreaper will receive a SIGCHLD -// signal and be able to wait(2) on the process to discover its -// termination status. -const setChildSubreaper = 36 - // SetSubreaper sets the value i as the subreaper setting for the calling process func SetSubreaper(i int) error { - return unix.Prctl(setChildSubreaper, uintptr(i), 0, 0, 0) + return unix.Prctl(unix.PR_SET_CHILD_SUBREAPER, uintptr(i), 0, 0, 0) } // GetSubreaper returns the subreaper setting for the calling process diff --git a/vendor/github.com/containerd/containerd/sys/userns_linux.go b/vendor/github.com/containerd/containerd/sys/userns_linux.go new file mode 100644 index 000000000..3cd1a2222 --- /dev/null +++ b/vendor/github.com/containerd/containerd/sys/userns_linux.go @@ -0,0 +1,62 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package sys + +import ( + "bufio" + "fmt" + "os" + "sync" +) + +var ( + inUserNS bool + nsOnce sync.Once +) + +// RunningInUserNS detects whether we are currently running in a user namespace. +// Originally copied from github.com/lxc/lxd/shared/util.go +func RunningInUserNS() bool { + nsOnce.Do(func() { + file, err := os.Open("/proc/self/uid_map") + if err != nil { + // This kernel-provided file only exists if user namespaces are supported + return + } + defer file.Close() + + buf := bufio.NewReader(file) + l, _, err := buf.ReadLine() + if err != nil { + return + } + + line := string(l) + var a, b, c int64 + fmt.Sscanf(line, "%d %d %d", &a, &b, &c) + + /* + * We assume we are in the initial user namespace if we have a full + * range - 4294967295 uids starting at uid 0. + */ + if a == 0 && b == 0 && c == 4294967295 { + return + } + inUserNS = true + }) + return inUserNS +} diff --git a/vendor/github.com/containerd/containerd/sys/userns_unsupported.go b/vendor/github.com/containerd/containerd/sys/userns_unsupported.go new file mode 100644 index 000000000..549b50200 --- /dev/null +++ b/vendor/github.com/containerd/containerd/sys/userns_unsupported.go @@ -0,0 +1,25 @@ +// +build !linux + +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package sys + +// RunningInUserNS is a stub for non-Linux systems +// Always returns false +func RunningInUserNS() bool { + return false +} diff --git a/vendor/github.com/containerd/containerd/unpacker.go b/vendor/github.com/containerd/containerd/unpacker.go index 837734982..eb6981b28 100644 --- a/vendor/github.com/containerd/containerd/unpacker.go +++ b/vendor/github.com/containerd/containerd/unpacker.go @@ -72,7 +72,13 @@ func (c *Client) newUnpacker(ctx context.Context, rCtx *RemoteContext) (*unpacke }, nil } -func (u *unpacker) unpack(ctx context.Context, h images.Handler, config ocispec.Descriptor, layers []ocispec.Descriptor) error { +func (u *unpacker) unpack( + ctx context.Context, + rCtx *RemoteContext, + h images.Handler, + config ocispec.Descriptor, + layers []ocispec.Descriptor, +) error { p, err := content.ReadBlob(ctx, u.c.ContentStore(), config) if err != nil { return err @@ -123,17 +129,17 @@ EachLayer: labels = make(map[string]string) } labels[labelSnapshotRef] = chainID - labelOpt := snapshots.WithLabels(labels) var ( key string mounts []mount.Mount + opts = append(rCtx.SnapshotterOpts, snapshots.WithLabels(labels)) ) for try := 1; try <= 3; try++ { // Prepare snapshot with from parent, label as root key = fmt.Sprintf("extract-%s %s", uniquePart(), chainID) - mounts, err = sn.Prepare(ctx, key, parent.String(), labelOpt) + mounts, err = sn.Prepare(ctx, key, parent.String(), opts...) if err != nil { if errdefs.IsAlreadyExists(err) { if _, err := sn.Stat(ctx, chainID); err != nil { @@ -201,7 +207,7 @@ EachLayer: return errors.Errorf("wrong diff id calculated on extraction %q", diffIDs[i]) } - if err = sn.Commit(ctx, chainID, key, labelOpt); err != nil { + if err = sn.Commit(ctx, chainID, key, opts...); err != nil { abort() if errdefs.IsAlreadyExists(err) { continue @@ -271,7 +277,11 @@ func (u *unpacker) fetch(ctx context.Context, h images.Handler, layers []ocispec return eg.Wait() } -func (u *unpacker) handlerWrapper(uctx context.Context, unpacks *int32) (func(images.Handler) images.Handler, *errgroup.Group) { +func (u *unpacker) handlerWrapper( + uctx context.Context, + rCtx *RemoteContext, + unpacks *int32, +) (func(images.Handler) images.Handler, *errgroup.Group) { eg, uctx := errgroup.WithContext(uctx) return func(f images.Handler) images.Handler { var ( @@ -313,7 +323,7 @@ func (u *unpacker) handlerWrapper(uctx context.Context, unpacks *int32) (func(im if len(l) > 0 { atomic.AddInt32(unpacks, 1) eg.Go(func() error { - return u.unpack(uctx, f, desc, l) + return u.unpack(uctx, rCtx, f, desc, l) }) } } diff --git a/vendor/github.com/containerd/containerd/vendor.conf b/vendor/github.com/containerd/containerd/vendor.conf index f7af5cc55..d5c01b0cc 100644 --- a/vendor/github.com/containerd/containerd/vendor.conf +++ b/vendor/github.com/containerd/containerd/vendor.conf @@ -2,16 +2,16 @@ github.com/beorn7/perks 37c8de3658fcb183f997c4e13e83 github.com/BurntSushi/toml 3012a1dbe2e4bd1391d42b32f0577cb7bbc7f005 # v0.3.1 github.com/cespare/xxhash/v2 d7df74196a9e781ede915320c11c378c1b2f3a1f # v2.1.1 github.com/containerd/btrfs 153935315f4ab9be5bf03650a1341454b05efa5d -github.com/containerd/cgroups 7347743e5d1e8500d9f27c8e748e689ed991d92b -github.com/containerd/console 8375c3424e4d7b114e8a90a4a40c8e1b40d1d4e6 +github.com/containerd/cgroups b4448137398923af7f4918b8b2ad8249172ca7a6 +github.com/containerd/console 8375c3424e4d7b114e8a90a4a40c8e1b40d1d4e6 # v1.0.0 github.com/containerd/continuity 0ec596719c75bfd42908850990acea594b7593ac github.com/containerd/fifo bda0ff6ed73c67bfb5e62bc9c697f146b7fd7f13 github.com/containerd/go-runc a5c2862aed5e6358b305b0e16bfce58e0549b1cd -github.com/containerd/ttrpc 92c8520ef9f86600c650dd540266a007bf03670f -github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40 +github.com/containerd/ttrpc 72bb1b21c5b0a4a107f59dd85f6ab58e564b68d6 # v1.0.1 +github.com/containerd/typeurl cd3ce7159eae562a4f60ceff37dada11a939d247 # v1.0.1 github.com/coreos/go-systemd/v22 2d78030078ef61b3cae27f42ad6d0e46db51b339 # v22.0.0 github.com/cpuguy83/go-md2man 7762f7e404f8416dfa1d9bb6a8c192aa9acb4d19 # v1.0.10 -github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9 +github.com/docker/go-events e31b211e4f1cd09aa76fe4ac244571fab96ae47f github.com/docker/go-metrics b619b3592b65de4f087d9f16863a7e6ff905973c # v0.0.1 github.com/docker/go-units 519db1ee28dcc9fd2474ae59fca29a810482bfb1 # v0.4.0 github.com/godbus/dbus/v5 37bf87eef99d69c4f1d3528bd66e3a87dc201472 # v5.0.3 @@ -25,65 +25,78 @@ github.com/hashicorp/errwrap 8a6fb523712970c966eefc6b39ed github.com/hashicorp/go-multierror 886a7fbe3eb1c874d46f623bfa70af45f425b3d1 # v1.0.0 github.com/hashicorp/golang-lru 7f827b33c0f158ec5dfbba01bb0b14a4541fd81d # v0.5.3 github.com/imdario/mergo 7c29201646fa3de8506f701213473dd407f19646 # v0.3.7 -github.com/konsorten/go-windows-terminal-sequences 5c8c8bd35d3832f5d134ae1e1e375b69a4d25242 # v1.0.1 +github.com/konsorten/go-windows-terminal-sequences edb144dfd453055e1e49a3d8b410a660b5a87613 # v1.0.3 github.com/matttproud/golang_protobuf_extensions c12348ce28de40eed0136aa2b644d0ee0650e56c # v1.0.1 github.com/Microsoft/go-winio 6c72808b55902eae4c5943626030429ff20f3b63 # v0.4.14 -github.com/Microsoft/hcsshim 0b571ac85d7c5842b26d2571de4868634a4c39d7 # v0.8.7-24-g0b571ac8 +github.com/Microsoft/hcsshim 5bc557dd210ff2caf615e6e22d398123de77fc11 # v0.8.9 github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7 github.com/opencontainers/image-spec d60099175f88c47cd379c4738d158884749ed235 # v1.0.1 github.com/opencontainers/runc dc9208a3303feef5b3839f4323d9beb36df0a9dd # v1.0.0-rc10 -github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4 # v1.0.1-59-g29686db -github.com/pkg/errors ba968bfe8b2f7e042a574c888954fccecfa385b4 # v0.8.1 +github.com/opencontainers/runtime-spec c4ee7d12c742ffe806cd9350b6af3b4b19faed6f # v1.0.2 +github.com/pkg/errors 614d223910a179a466c1767a985424175c39b465 # v0.9.1 github.com/prometheus/client_golang c42bebe5a5cddfc6b28cd639103369d8a75dfa89 # v1.3.0 github.com/prometheus/client_model d1d2010b5beead3fa1c5f271a5cf626e40b3ad6e # v0.1.0 github.com/prometheus/common 287d3e634a1e550c9e463dd7e5a75a422c614505 # v0.7.0 github.com/prometheus/procfs 6d489fc7f1d9cd890a250f3ea3431b1744b9623f # v0.0.8 github.com/russross/blackfriday 05f3235734ad95d0016f6a23902f06461fcf567a # v1.5.2 -github.com/sirupsen/logrus 8bdbc7bcc01dcbb8ec23dc8a28e332258d25251f # v1.4.1 +github.com/sirupsen/logrus 60c74ad9be0d874af0ab0daef6ab07c5c5911f0d # v1.6.0 github.com/syndtr/gocapability d98352740cb2c55f81556b63d4a1ec64c5a319c2 github.com/urfave/cli bfe2e925cfb6d44b40ad3a779165ea7e8aff9212 # v1.22.0 go.etcd.io/bbolt a0458a2b35708eef59eb5f620ceb3cd1c01a824d # v1.3.3 go.opencensus.io 9c377598961b706d1542bd2d84d538b5094d596e # v0.22.0 golang.org/x/net f3200d17e092c607f615320ecaad13d87ad9a2b3 golang.org/x/sync 42b317875d0fa942474b76e1b46a6060d720ae6e -golang.org/x/sys c990c680b611ac1aeb7d8f2af94a825f98d69720 https://github.com/golang/sys +golang.org/x/sys 5c8b2ff67527cb88b770f693cebf3799036d8bc0 golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4 google.golang.org/genproto e50cd9704f63023d62cd06a1994b98227fc4d21a google.golang.org/grpc f495f5b15ae7ccda3b38c53a1bfcde4c1a58a2bc # v1.27.1 gotest.tools/v3 bb0d8a963040ea5048dcef1a14d8f8b58a33d4b3 # v3.0.2 +# cgroups dependencies +github.com/cilium/ebpf 4032b1d8aae306b7bb94a2a11002932caf88c644 + # cri dependencies -github.com/containerd/cri c0294ebfe0b4342db85c0faf7727ceb8d8c3afce # master -github.com/containerd/go-cni 0d360c50b10b350b6bb23863fd4dfb1c232b01c9 -github.com/containernetworking/cni 4cfb7b568922a3c79a23e438dc52fe537fc9687e # v0.7.1 -github.com/containernetworking/plugins 9f96827c7cabb03f21d86326000c00f61e181f6a # v0.7.6 +github.com/containerd/cri 65830369b6b2b4edc454bf5cebbd9b76c1c1ac66 # master github.com/davecgh/go-spew 8991bc29aa16c548c550c7ff78260e27b9ab7c73 # v1.1.1 github.com/docker/distribution 0d3efadf0154c2b8a4e7b6621fff9809655cc580 -github.com/docker/docker d1d5f6476656c6aad457e2a91d3436e66b6f2251 +github.com/docker/docker 4634ce647cf2ce2c6031129ccd109e557244986f github.com/docker/spdystream 449fdfce4d962303d702fec724ef0ad181c92528 github.com/emicklei/go-restful b993709ae1a4f6dd19cfa475232614441b11c9d5 # v2.9.5 -github.com/google/gofuzz f140a6486e521aad38f5917de355cbf147cc0496 # v1.0.0 +github.com/google/gofuzz db92cf7ae75e4a7a28abc005addab2b394362888 # v1.1.0 github.com/json-iterator/go 03217c3e97663914aec3faafde50d081f197a0a2 # v1.1.8 github.com/modern-go/concurrent bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94 # 1.0.3 github.com/modern-go/reflect2 4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd # 1.0.1 -github.com/opencontainers/selinux 31f70552238c5e017d78c3f1ba65e85f593f48e0 # 1.3.3 +github.com/opencontainers/selinux 0d49ba2a6aae052c614dfe5de62a158711a6c461 # 1.5.1 github.com/seccomp/libseccomp-golang 689e3c1541a84461afc49c1c87352a6cedf72e9c # v0.9.1 github.com/stretchr/testify 221dbe5ed46703ee255b1da0dec05086f5035f62 # v1.4.0 github.com/tchap/go-patricia 666120de432aea38ab06bd5c818f04f4129882c9 # v2.2.6 -golang.org/x/crypto 1d94cc7ab1c630336ab82ccb9c9cda72a875c382 +golang.org/x/crypto bac4c82f69751a6dd76e702d54b3ceb88adab236 golang.org/x/oauth2 0f29369cfe4552d0e4bcddc57cc75f4d7e672a33 golang.org/x/time 9d24e82272b4f38b78bc8cff74fa936d31ccd8ef gopkg.in/inf.v0 d2d2541c53f18d2a059457998ce2876cc8e67cbf # v0.9.1 gopkg.in/yaml.v2 53403b58ad1b561927d19068c655246f2db79d48 # v2.2.8 -k8s.io/api 7643814f1c97f24ccfb38c2b85a7bb3c7f494346 # kubernetes-1.17.1 -k8s.io/apimachinery 79c2a76c473a20cdc4ce59cae4b72529b5d9d16b # kubernetes-1.17.1 -k8s.io/apiserver 5381f05fcb881d39af12eeecab5645364229300c # kubernetes-1.17.1 -k8s.io/client-go 69012f50f4b0243bccdb82c24402a10224a91f51 # kubernetes-1.17.1 -k8s.io/cri-api 775aa3c1cf7380ba8b7362f5a52f1e6d2e130bb9 # kubernetes-1.17.1 +k8s.io/api d2dce8e1788e4be2be3a62b6439b3eaa087df0df # v0.18.0 +k8s.io/apimachinery 105e0c6d63f10531ed07f3b5a2195771a0fa444b # v0.18.0 +k8s.io/apiserver 5c8e895629a454efd75a453d1dea5b8142db0013 # v0.18.0 +k8s.io/client-go 0b19784585bd0a0ee5509855829ead81feaa2bdc # v0.18.0 +k8s.io/cri-api 3d1680d8d202aa12c5dc5689170c3c03a488d35b # v0.18.0 k8s.io/klog 2ca9ad30301bf30a8a6e0fa2110db6b8df699a91 # v1.0.0 -k8s.io/kubernetes d224476cd0730baca2b6e357d144171ed74192d6 # v1.17.1 -k8s.io/utils e782cd3c129fc98ee807f3c889c0f26eb7c9daf5 -sigs.k8s.io/yaml fd68e9863619f6ec2fdd8625fe1f02e7c877e480 # v1.1.0 +k8s.io/kubernetes 9e991415386e4cf155a24b1da15becaa390438d8 # v1.18.0 +k8s.io/utils a9aa75ae1b89e1b992c33383f48e942d97e52dae +sigs.k8s.io/structured-merge-diff/v3 877aee05330847a873a1a8998b40e12a1e0fde25 # v3.0.0 +sigs.k8s.io/yaml 9fc95527decd95bb9d28cc2eab08179b2d0f6971 # v1.2.0 + +# cni dependencies +github.com/containerd/go-cni 0d360c50b10b350b6bb23863fd4dfb1c232b01c9 +github.com/containernetworking/cni 4cfb7b568922a3c79a23e438dc52fe537fc9687e # v0.7.1 +github.com/containernetworking/plugins 9f96827c7cabb03f21d86326000c00f61e181f6a # v0.7.6 +github.com/fsnotify/fsnotify 4bf2d1fec78374803a39307bfb8d340688f4f28e # v1.4.8 + +# image decrypt depedencies +github.com/containerd/imgcrypt 9e761ccd6069fb707ec9493435f31475b5524b38 # v1.0.1 +github.com/containers/ocicrypt 0343cc6053fd65069df55bce6838096e09b4033a # v1.0.1 from containerd/imgcrypt +github.com/fullsailor/pkcs7 8306686428a5fe132eac8cb7c4848af725098bd4 # from containers/ocicrypt +gopkg.in/square/go-jose.v2 730df5f748271903322feb182be83b43ebbbe27d # v2.3.1 from containers/ocicrypt # zfs dependencies github.com/containerd/zfs 9abf673ca6ff9ab8d9bd776a4ceff8f6dc699c3d @@ -91,6 +104,3 @@ github.com/mistifyio/go-zfs f784269be439d704d3dfa1906f45 # aufs dependencies github.com/containerd/aufs 371312c1e31c210a21e49bf3dfd3f31729ed9f2f - -# cgroups dependencies -github.com/cilium/ebpf 60c3aa43f488292fe2ee50fb8b833b383ca8ebbb diff --git a/vendor/github.com/coreos/go-systemd/v22/daemon/sdnotify.go b/vendor/github.com/coreos/go-systemd/v22/daemon/sdnotify.go new file mode 100644 index 000000000..ba4ae31f1 --- /dev/null +++ b/vendor/github.com/coreos/go-systemd/v22/daemon/sdnotify.go @@ -0,0 +1,84 @@ +// Copyright 2014 Docker, Inc. +// Copyright 2015-2018 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Package daemon provides a Go implementation of the sd_notify protocol. +// It can be used to inform systemd of service start-up completion, watchdog +// events, and other status changes. +// +// https://www.freedesktop.org/software/systemd/man/sd_notify.html#Description +package daemon + +import ( + "net" + "os" +) + +const ( + // SdNotifyReady tells the service manager that service startup is finished + // or the service finished loading its configuration. + SdNotifyReady = "READY=1" + + // SdNotifyStopping tells the service manager that the service is beginning + // its shutdown. + SdNotifyStopping = "STOPPING=1" + + // SdNotifyReloading tells the service manager that this service is + // reloading its configuration. Note that you must call SdNotifyReady when + // it completed reloading. + SdNotifyReloading = "RELOADING=1" + + // SdNotifyWatchdog tells the service manager to update the watchdog + // timestamp for the service. + SdNotifyWatchdog = "WATCHDOG=1" +) + +// SdNotify sends a message to the init daemon. It is common to ignore the error. +// If `unsetEnvironment` is true, the environment variable `NOTIFY_SOCKET` +// will be unconditionally unset. +// +// It returns one of the following: +// (false, nil) - notification not supported (i.e. NOTIFY_SOCKET is unset) +// (false, err) - notification supported, but failure happened (e.g. error connecting to NOTIFY_SOCKET or while sending data) +// (true, nil) - notification supported, data has been sent +func SdNotify(unsetEnvironment bool, state string) (bool, error) { + socketAddr := &net.UnixAddr{ + Name: os.Getenv("NOTIFY_SOCKET"), + Net: "unixgram", + } + + // NOTIFY_SOCKET not set + if socketAddr.Name == "" { + return false, nil + } + + if unsetEnvironment { + if err := os.Unsetenv("NOTIFY_SOCKET"); err != nil { + return false, err + } + } + + conn, err := net.DialUnix(socketAddr.Net, nil, socketAddr) + // Error connecting to NOTIFY_SOCKET + if err != nil { + return false, err + } + defer conn.Close() + + if _, err = conn.Write([]byte(state)); err != nil { + return false, err + } + return true, nil +} diff --git a/vendor/github.com/coreos/go-systemd/v22/daemon/watchdog.go b/vendor/github.com/coreos/go-systemd/v22/daemon/watchdog.go new file mode 100644 index 000000000..7a0e0d3a5 --- /dev/null +++ b/vendor/github.com/coreos/go-systemd/v22/daemon/watchdog.go @@ -0,0 +1,73 @@ +// Copyright 2016 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package daemon + +import ( + "fmt" + "os" + "strconv" + "time" +) + +// SdWatchdogEnabled returns watchdog information for a service. +// Processes should call daemon.SdNotify(false, daemon.SdNotifyWatchdog) every +// time / 2. +// If `unsetEnvironment` is true, the environment variables `WATCHDOG_USEC` and +// `WATCHDOG_PID` will be unconditionally unset. +// +// It returns one of the following: +// (0, nil) - watchdog isn't enabled or we aren't the watched PID. +// (0, err) - an error happened (e.g. error converting time). +// (time, nil) - watchdog is enabled and we can send ping. +// time is delay before inactive service will be killed. +func SdWatchdogEnabled(unsetEnvironment bool) (time.Duration, error) { + wusec := os.Getenv("WATCHDOG_USEC") + wpid := os.Getenv("WATCHDOG_PID") + if unsetEnvironment { + wusecErr := os.Unsetenv("WATCHDOG_USEC") + wpidErr := os.Unsetenv("WATCHDOG_PID") + if wusecErr != nil { + return 0, wusecErr + } + if wpidErr != nil { + return 0, wpidErr + } + } + + if wusec == "" { + return 0, nil + } + s, err := strconv.Atoi(wusec) + if err != nil { + return 0, fmt.Errorf("error converting WATCHDOG_USEC: %s", err) + } + if s <= 0 { + return 0, fmt.Errorf("error WATCHDOG_USEC must be a positive number") + } + interval := time.Duration(s) * time.Microsecond + + if wpid == "" { + return interval, nil + } + p, err := strconv.Atoi(wpid) + if err != nil { + return 0, fmt.Errorf("error converting WATCHDOG_PID: %s", err) + } + if os.Getpid() != p { + return 0, nil + } + + return interval, nil +} diff --git a/vendor/github.com/hashicorp/errwrap/LICENSE b/vendor/github.com/hashicorp/errwrap/LICENSE new file mode 100644 index 000000000..c33dcc7c9 --- /dev/null +++ b/vendor/github.com/hashicorp/errwrap/LICENSE @@ -0,0 +1,354 @@ +Mozilla Public License, version 2.0 + +1. Definitions + +1.1. “Contributor” + + means each individual or legal entity that creates, contributes to the + creation of, or owns Covered Software. + +1.2. “Contributor Version” + + means the combination of the Contributions of others (if any) used by a + Contributor and that particular Contributor’s Contribution. + +1.3. “Contribution” + + means Covered Software of a particular Contributor. + +1.4. “Covered Software” + + means Source Code Form to which the initial Contributor has attached the + notice in Exhibit A, the Executable Form of such Source Code Form, and + Modifications of such Source Code Form, in each case including portions + thereof. + +1.5. “Incompatible With Secondary Licenses” + means + + a. that the initial Contributor has attached the notice described in + Exhibit B to the Covered Software; or + + b. that the Covered Software was made available under the terms of version + 1.1 or earlier of the License, but not also under the terms of a + Secondary License. + +1.6. “Executable Form” + + means any form of the work other than Source Code Form. + +1.7. “Larger Work” + + means a work that combines Covered Software with other material, in a separate + file or files, that is not Covered Software. + +1.8. “License” + + means this document. + +1.9. “Licensable” + + means having the right to grant, to the maximum extent possible, whether at the + time of the initial grant or subsequently, any and all of the rights conveyed by + this License. + +1.10. “Modifications” + + means any of the following: + + a. any file in Source Code Form that results from an addition to, deletion + from, or modification of the contents of Covered Software; or + + b. any new file in Source Code Form that contains any Covered Software. + +1.11. “Patent Claims” of a Contributor + + means any patent claim(s), including without limitation, method, process, + and apparatus claims, in any patent Licensable by such Contributor that + would be infringed, but for the grant of the License, by the making, + using, selling, offering for sale, having made, import, or transfer of + either its Contributions or its Contributor Version. + +1.12. “Secondary License” + + means either the GNU General Public License, Version 2.0, the GNU Lesser + General Public License, Version 2.1, the GNU Affero General Public + License, Version 3.0, or any later versions of those licenses. + +1.13. “Source Code Form” + + means the form of the work preferred for making modifications. + +1.14. “You” (or “Your”) + + means an individual or a legal entity exercising rights under this + License. For legal entities, “You” includes any entity that controls, is + controlled by, or is under common control with You. For purposes of this + definition, “control” means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by contract or + otherwise, or (b) ownership of more than fifty percent (50%) of the + outstanding shares or beneficial ownership of such entity. + + +2. License Grants and Conditions + +2.1. Grants + + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + a. under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or as + part of a Larger Work; and + + b. under Patent Claims of such Contributor to make, use, sell, offer for + sale, have made, import, and otherwise transfer either its Contributions + or its Contributor Version. + +2.2. Effective Date + + The licenses granted in Section 2.1 with respect to any Contribution become + effective for each Contribution on the date the Contributor first distributes + such Contribution. + +2.3. Limitations on Grant Scope + + The licenses granted in this Section 2 are the only rights granted under this + License. No additional rights or licenses will be implied from the distribution + or licensing of Covered Software under this License. Notwithstanding Section + 2.1(b) above, no patent license is granted by a Contributor: + + a. for any code that a Contributor has removed from Covered Software; or + + b. for infringements caused by: (i) Your and any other third party’s + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + + c. under Patent Claims infringed by Covered Software in the absence of its + Contributions. + + This License does not grant any rights in the trademarks, service marks, or + logos of any Contributor (except as may be necessary to comply with the + notice requirements in Section 3.4). + +2.4. Subsequent Licenses + + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this License + (see Section 10.2) or under the terms of a Secondary License (if permitted + under the terms of Section 3.3). + +2.5. Representation + + Each Contributor represents that the Contributor believes its Contributions + are its original creation(s) or it has sufficient rights to grant the + rights to its Contributions conveyed by this License. + +2.6. Fair Use + + This License is not intended to limit any rights You have under applicable + copyright doctrines of fair use, fair dealing, or other equivalents. + +2.7. Conditions + + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in + Section 2.1. + + +3. Responsibilities + +3.1. Distribution of Source Form + + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under the + terms of this License. You must inform recipients that the Source Code Form + of the Covered Software is governed by the terms of this License, and how + they can obtain a copy of this License. You may not attempt to alter or + restrict the recipients’ rights in the Source Code Form. + +3.2. Distribution of Executable Form + + If You distribute Covered Software in Executable Form then: + + a. such Covered Software must also be made available in Source Code Form, + as described in Section 3.1, and You must inform recipients of the + Executable Form how they can obtain a copy of such Source Code Form by + reasonable means in a timely manner, at a charge no more than the cost + of distribution to the recipient; and + + b. You may distribute such Executable Form under the terms of this License, + or sublicense it under different terms, provided that the license for + the Executable Form does not attempt to limit or alter the recipients’ + rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for the + Covered Software. If the Larger Work is a combination of Covered Software + with a work governed by one or more Secondary Licenses, and the Covered + Software is not Incompatible With Secondary Licenses, this License permits + You to additionally distribute such Covered Software under the terms of + such Secondary License(s), so that the recipient of the Larger Work may, at + their option, further distribute the Covered Software under the terms of + either this License or such Secondary License(s). + +3.4. Notices + + You may not remove or alter the substance of any license notices (including + copyright notices, patent notices, disclaimers of warranty, or limitations + of liability) contained within the Source Code Form of the Covered + Software, except that You may alter any license notices to the extent + required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on behalf + of any Contributor. You must make it absolutely clear that any such + warranty, support, indemnity, or liability obligation is offered by You + alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. + +4. Inability to Comply Due to Statute or Regulation + + If it is impossible for You to comply with any of the terms of this License + with respect to some or all of the Covered Software due to statute, judicial + order, or regulation then You must: (a) comply with the terms of this License + to the maximum extent possible; and (b) describe the limitations and the code + they affect. Such description must be placed in a text file included with all + distributions of the Covered Software under this License. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Termination + +5.1. The rights granted under this License will terminate automatically if You + fail to comply with any of its terms. However, if You become compliant, + then the rights granted under this License from a particular Contributor + are reinstated (a) provisionally, unless and until such Contributor + explicitly and finally terminates Your grants, and (b) on an ongoing basis, + if such Contributor fails to notify You of the non-compliance by some + reasonable means prior to 60 days after You have come back into compliance. + Moreover, Your grants from a particular Contributor are reinstated on an + ongoing basis if such Contributor notifies You of the non-compliance by + some reasonable means, this is the first time You have received notice of + non-compliance with this License from such Contributor, and You become + compliant prior to 30 days after Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, counter-claims, + and cross-claims) alleging that a Contributor Version directly or + indirectly infringes any patent, then the rights granted to You by any and + all Contributors for the Covered Software under Section 2.1 of this License + shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user + license agreements (excluding distributors and resellers) which have been + validly granted by You or Your distributors under this License prior to + termination shall survive termination. + +6. Disclaimer of Warranty + + Covered Software is provided under this License on an “as is” basis, without + warranty of any kind, either expressed, implied, or statutory, including, + without limitation, warranties that the Covered Software is free of defects, + merchantable, fit for a particular purpose or non-infringing. The entire + risk as to the quality and performance of the Covered Software is with You. + Should any Covered Software prove defective in any respect, You (not any + Contributor) assume the cost of any necessary servicing, repair, or + correction. This disclaimer of warranty constitutes an essential part of this + License. No use of any Covered Software is authorized under this License + except under this disclaimer. + +7. Limitation of Liability + + Under no circumstances and under no legal theory, whether tort (including + negligence), contract, or otherwise, shall any Contributor, or anyone who + distributes Covered Software as permitted above, be liable to You for any + direct, indirect, special, incidental, or consequential damages of any + character including, without limitation, damages for lost profits, loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses, even if such party shall have been + informed of the possibility of such damages. This limitation of liability + shall not apply to liability for death or personal injury resulting from such + party’s negligence to the extent applicable law prohibits such limitation. + Some jurisdictions do not allow the exclusion or limitation of incidental or + consequential damages, so this exclusion and limitation may not apply to You. + +8. Litigation + + Any litigation relating to this License may be brought only in the courts of + a jurisdiction where the defendant maintains its principal place of business + and such litigation shall be governed by laws of that jurisdiction, without + reference to its conflict-of-law provisions. Nothing in this Section shall + prevent a party’s ability to bring cross-claims or counter-claims. + +9. Miscellaneous + + This License represents the complete agreement concerning the subject matter + hereof. If any provision of this License is held to be unenforceable, such + provision shall be reformed only to the extent necessary to make it + enforceable. Any law or regulation which provides that the language of a + contract shall be construed against the drafter shall not be used to construe + this License against a Contributor. + + +10. Versions of the License + +10.1. New Versions + + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. + +10.2. Effect of New Versions + + You may distribute the Covered Software under the terms of the version of + the License under which You originally received the Covered Software, or + under the terms of any subsequent version published by the license + steward. + +10.3. Modified Versions + + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a modified + version of this License if you rename the license and remove any + references to the name of the license steward (except to note that such + modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses + If You choose to distribute Source Code Form that is Incompatible With + Secondary Licenses under the terms of this version of the License, the + notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the + terms of the Mozilla Public License, v. + 2.0. If a copy of the MPL was not + distributed with this file, You can + obtain one at + http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular file, then +You may include the notice in a location (such as a LICENSE file in a relevant +directory) where a recipient would be likely to look for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - “Incompatible With Secondary Licenses” Notice + + This Source Code Form is “Incompatible + With Secondary Licenses”, as defined by + the Mozilla Public License, v. 2.0. + diff --git a/vendor/github.com/hashicorp/errwrap/README.md b/vendor/github.com/hashicorp/errwrap/README.md new file mode 100644 index 000000000..444df08f8 --- /dev/null +++ b/vendor/github.com/hashicorp/errwrap/README.md @@ -0,0 +1,89 @@ +# errwrap + +`errwrap` is a package for Go that formalizes the pattern of wrapping errors +and checking if an error contains another error. + +There is a common pattern in Go of taking a returned `error` value and +then wrapping it (such as with `fmt.Errorf`) before returning it. The problem +with this pattern is that you completely lose the original `error` structure. + +Arguably the _correct_ approach is that you should make a custom structure +implementing the `error` interface, and have the original error as a field +on that structure, such [as this example](http://golang.org/pkg/os/#PathError). +This is a good approach, but you have to know the entire chain of possible +rewrapping that happens, when you might just care about one. + +`errwrap` formalizes this pattern (it doesn't matter what approach you use +above) by giving a single interface for wrapping errors, checking if a specific +error is wrapped, and extracting that error. + +## Installation and Docs + +Install using `go get github.com/hashicorp/errwrap`. + +Full documentation is available at +http://godoc.org/github.com/hashicorp/errwrap + +## Usage + +#### Basic Usage + +Below is a very basic example of its usage: + +```go +// A function that always returns an error, but wraps it, like a real +// function might. +func tryOpen() error { + _, err := os.Open("/i/dont/exist") + if err != nil { + return errwrap.Wrapf("Doesn't exist: {{err}}", err) + } + + return nil +} + +func main() { + err := tryOpen() + + // We can use the Contains helpers to check if an error contains + // another error. It is safe to do this with a nil error, or with + // an error that doesn't even use the errwrap package. + if errwrap.Contains(err, "does not exist") { + // Do something + } + if errwrap.ContainsType(err, new(os.PathError)) { + // Do something + } + + // Or we can use the associated `Get` functions to just extract + // a specific error. This would return nil if that specific error doesn't + // exist. + perr := errwrap.GetType(err, new(os.PathError)) +} +``` + +#### Custom Types + +If you're already making custom types that properly wrap errors, then +you can get all the functionality of `errwraps.Contains` and such by +implementing the `Wrapper` interface with just one function. Example: + +```go +type AppError { + Code ErrorCode + Err error +} + +func (e *AppError) WrappedErrors() []error { + return []error{e.Err} +} +``` + +Now this works: + +```go +err := &AppError{Err: fmt.Errorf("an error")} +if errwrap.ContainsType(err, fmt.Errorf("")) { + // This will work! +} +``` diff --git a/vendor/github.com/hashicorp/errwrap/errwrap.go b/vendor/github.com/hashicorp/errwrap/errwrap.go new file mode 100644 index 000000000..a733bef18 --- /dev/null +++ b/vendor/github.com/hashicorp/errwrap/errwrap.go @@ -0,0 +1,169 @@ +// Package errwrap implements methods to formalize error wrapping in Go. +// +// All of the top-level functions that take an `error` are built to be able +// to take any error, not just wrapped errors. This allows you to use errwrap +// without having to type-check and type-cast everywhere. +package errwrap + +import ( + "errors" + "reflect" + "strings" +) + +// WalkFunc is the callback called for Walk. +type WalkFunc func(error) + +// Wrapper is an interface that can be implemented by custom types to +// have all the Contains, Get, etc. functions in errwrap work. +// +// When Walk reaches a Wrapper, it will call the callback for every +// wrapped error in addition to the wrapper itself. Since all the top-level +// functions in errwrap use Walk, this means that all those functions work +// with your custom type. +type Wrapper interface { + WrappedErrors() []error +} + +// Wrap defines that outer wraps inner, returning an error type that +// can be cleanly used with the other methods in this package, such as +// Contains, GetAll, etc. +// +// This function won't modify the error message at all (the outer message +// will be used). +func Wrap(outer, inner error) error { + return &wrappedError{ + Outer: outer, + Inner: inner, + } +} + +// Wrapf wraps an error with a formatting message. This is similar to using +// `fmt.Errorf` to wrap an error. If you're using `fmt.Errorf` to wrap +// errors, you should replace it with this. +// +// format is the format of the error message. The string '{{err}}' will +// be replaced with the original error message. +func Wrapf(format string, err error) error { + outerMsg := "" + if err != nil { + outerMsg = err.Error() + } + + outer := errors.New(strings.Replace( + format, "{{err}}", outerMsg, -1)) + + return Wrap(outer, err) +} + +// Contains checks if the given error contains an error with the +// message msg. If err is not a wrapped error, this will always return +// false unless the error itself happens to match this msg. +func Contains(err error, msg string) bool { + return len(GetAll(err, msg)) > 0 +} + +// ContainsType checks if the given error contains an error with +// the same concrete type as v. If err is not a wrapped error, this will +// check the err itself. +func ContainsType(err error, v interface{}) bool { + return len(GetAllType(err, v)) > 0 +} + +// Get is the same as GetAll but returns the deepest matching error. +func Get(err error, msg string) error { + es := GetAll(err, msg) + if len(es) > 0 { + return es[len(es)-1] + } + + return nil +} + +// GetType is the same as GetAllType but returns the deepest matching error. +func GetType(err error, v interface{}) error { + es := GetAllType(err, v) + if len(es) > 0 { + return es[len(es)-1] + } + + return nil +} + +// GetAll gets all the errors that might be wrapped in err with the +// given message. The order of the errors is such that the outermost +// matching error (the most recent wrap) is index zero, and so on. +func GetAll(err error, msg string) []error { + var result []error + + Walk(err, func(err error) { + if err.Error() == msg { + result = append(result, err) + } + }) + + return result +} + +// GetAllType gets all the errors that are the same type as v. +// +// The order of the return value is the same as described in GetAll. +func GetAllType(err error, v interface{}) []error { + var result []error + + var search string + if v != nil { + search = reflect.TypeOf(v).String() + } + Walk(err, func(err error) { + var needle string + if err != nil { + needle = reflect.TypeOf(err).String() + } + + if needle == search { + result = append(result, err) + } + }) + + return result +} + +// Walk walks all the wrapped errors in err and calls the callback. If +// err isn't a wrapped error, this will be called once for err. If err +// is a wrapped error, the callback will be called for both the wrapper +// that implements error as well as the wrapped error itself. +func Walk(err error, cb WalkFunc) { + if err == nil { + return + } + + switch e := err.(type) { + case *wrappedError: + cb(e.Outer) + Walk(e.Inner, cb) + case Wrapper: + cb(err) + + for _, err := range e.WrappedErrors() { + Walk(err, cb) + } + default: + cb(err) + } +} + +// wrappedError is an implementation of error that has both the +// outer and inner errors. +type wrappedError struct { + Outer error + Inner error +} + +func (w *wrappedError) Error() string { + return w.Outer.Error() +} + +func (w *wrappedError) WrappedErrors() []error { + return []error{w.Outer, w.Inner} +} diff --git a/vendor/github.com/hashicorp/errwrap/go.mod b/vendor/github.com/hashicorp/errwrap/go.mod new file mode 100644 index 000000000..c9b84022c --- /dev/null +++ b/vendor/github.com/hashicorp/errwrap/go.mod @@ -0,0 +1 @@ +module github.com/hashicorp/errwrap diff --git a/vendor/github.com/hashicorp/go-multierror/LICENSE b/vendor/github.com/hashicorp/go-multierror/LICENSE new file mode 100644 index 000000000..82b4de97c --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/LICENSE @@ -0,0 +1,353 @@ +Mozilla Public License, version 2.0 + +1. Definitions + +1.1. “Contributor” + + means each individual or legal entity that creates, contributes to the + creation of, or owns Covered Software. + +1.2. “Contributor Version” + + means the combination of the Contributions of others (if any) used by a + Contributor and that particular Contributor’s Contribution. + +1.3. “Contribution” + + means Covered Software of a particular Contributor. + +1.4. “Covered Software” + + means Source Code Form to which the initial Contributor has attached the + notice in Exhibit A, the Executable Form of such Source Code Form, and + Modifications of such Source Code Form, in each case including portions + thereof. + +1.5. “Incompatible With Secondary Licenses” + means + + a. that the initial Contributor has attached the notice described in + Exhibit B to the Covered Software; or + + b. that the Covered Software was made available under the terms of version + 1.1 or earlier of the License, but not also under the terms of a + Secondary License. + +1.6. “Executable Form” + + means any form of the work other than Source Code Form. + +1.7. “Larger Work” + + means a work that combines Covered Software with other material, in a separate + file or files, that is not Covered Software. + +1.8. “License” + + means this document. + +1.9. “Licensable” + + means having the right to grant, to the maximum extent possible, whether at the + time of the initial grant or subsequently, any and all of the rights conveyed by + this License. + +1.10. “Modifications” + + means any of the following: + + a. any file in Source Code Form that results from an addition to, deletion + from, or modification of the contents of Covered Software; or + + b. any new file in Source Code Form that contains any Covered Software. + +1.11. “Patent Claims” of a Contributor + + means any patent claim(s), including without limitation, method, process, + and apparatus claims, in any patent Licensable by such Contributor that + would be infringed, but for the grant of the License, by the making, + using, selling, offering for sale, having made, import, or transfer of + either its Contributions or its Contributor Version. + +1.12. “Secondary License” + + means either the GNU General Public License, Version 2.0, the GNU Lesser + General Public License, Version 2.1, the GNU Affero General Public + License, Version 3.0, or any later versions of those licenses. + +1.13. “Source Code Form” + + means the form of the work preferred for making modifications. + +1.14. “You” (or “Your”) + + means an individual or a legal entity exercising rights under this + License. For legal entities, “You” includes any entity that controls, is + controlled by, or is under common control with You. For purposes of this + definition, “control” means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by contract or + otherwise, or (b) ownership of more than fifty percent (50%) of the + outstanding shares or beneficial ownership of such entity. + + +2. License Grants and Conditions + +2.1. Grants + + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + a. under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or as + part of a Larger Work; and + + b. under Patent Claims of such Contributor to make, use, sell, offer for + sale, have made, import, and otherwise transfer either its Contributions + or its Contributor Version. + +2.2. Effective Date + + The licenses granted in Section 2.1 with respect to any Contribution become + effective for each Contribution on the date the Contributor first distributes + such Contribution. + +2.3. Limitations on Grant Scope + + The licenses granted in this Section 2 are the only rights granted under this + License. No additional rights or licenses will be implied from the distribution + or licensing of Covered Software under this License. Notwithstanding Section + 2.1(b) above, no patent license is granted by a Contributor: + + a. for any code that a Contributor has removed from Covered Software; or + + b. for infringements caused by: (i) Your and any other third party’s + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + + c. under Patent Claims infringed by Covered Software in the absence of its + Contributions. + + This License does not grant any rights in the trademarks, service marks, or + logos of any Contributor (except as may be necessary to comply with the + notice requirements in Section 3.4). + +2.4. Subsequent Licenses + + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this License + (see Section 10.2) or under the terms of a Secondary License (if permitted + under the terms of Section 3.3). + +2.5. Representation + + Each Contributor represents that the Contributor believes its Contributions + are its original creation(s) or it has sufficient rights to grant the + rights to its Contributions conveyed by this License. + +2.6. Fair Use + + This License is not intended to limit any rights You have under applicable + copyright doctrines of fair use, fair dealing, or other equivalents. + +2.7. Conditions + + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in + Section 2.1. + + +3. Responsibilities + +3.1. Distribution of Source Form + + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under the + terms of this License. You must inform recipients that the Source Code Form + of the Covered Software is governed by the terms of this License, and how + they can obtain a copy of this License. You may not attempt to alter or + restrict the recipients’ rights in the Source Code Form. + +3.2. Distribution of Executable Form + + If You distribute Covered Software in Executable Form then: + + a. such Covered Software must also be made available in Source Code Form, + as described in Section 3.1, and You must inform recipients of the + Executable Form how they can obtain a copy of such Source Code Form by + reasonable means in a timely manner, at a charge no more than the cost + of distribution to the recipient; and + + b. You may distribute such Executable Form under the terms of this License, + or sublicense it under different terms, provided that the license for + the Executable Form does not attempt to limit or alter the recipients’ + rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for the + Covered Software. If the Larger Work is a combination of Covered Software + with a work governed by one or more Secondary Licenses, and the Covered + Software is not Incompatible With Secondary Licenses, this License permits + You to additionally distribute such Covered Software under the terms of + such Secondary License(s), so that the recipient of the Larger Work may, at + their option, further distribute the Covered Software under the terms of + either this License or such Secondary License(s). + +3.4. Notices + + You may not remove or alter the substance of any license notices (including + copyright notices, patent notices, disclaimers of warranty, or limitations + of liability) contained within the Source Code Form of the Covered + Software, except that You may alter any license notices to the extent + required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on behalf + of any Contributor. You must make it absolutely clear that any such + warranty, support, indemnity, or liability obligation is offered by You + alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. + +4. Inability to Comply Due to Statute or Regulation + + If it is impossible for You to comply with any of the terms of this License + with respect to some or all of the Covered Software due to statute, judicial + order, or regulation then You must: (a) comply with the terms of this License + to the maximum extent possible; and (b) describe the limitations and the code + they affect. Such description must be placed in a text file included with all + distributions of the Covered Software under this License. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Termination + +5.1. The rights granted under this License will terminate automatically if You + fail to comply with any of its terms. However, if You become compliant, + then the rights granted under this License from a particular Contributor + are reinstated (a) provisionally, unless and until such Contributor + explicitly and finally terminates Your grants, and (b) on an ongoing basis, + if such Contributor fails to notify You of the non-compliance by some + reasonable means prior to 60 days after You have come back into compliance. + Moreover, Your grants from a particular Contributor are reinstated on an + ongoing basis if such Contributor notifies You of the non-compliance by + some reasonable means, this is the first time You have received notice of + non-compliance with this License from such Contributor, and You become + compliant prior to 30 days after Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, counter-claims, + and cross-claims) alleging that a Contributor Version directly or + indirectly infringes any patent, then the rights granted to You by any and + all Contributors for the Covered Software under Section 2.1 of this License + shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user + license agreements (excluding distributors and resellers) which have been + validly granted by You or Your distributors under this License prior to + termination shall survive termination. + +6. Disclaimer of Warranty + + Covered Software is provided under this License on an “as is” basis, without + warranty of any kind, either expressed, implied, or statutory, including, + without limitation, warranties that the Covered Software is free of defects, + merchantable, fit for a particular purpose or non-infringing. The entire + risk as to the quality and performance of the Covered Software is with You. + Should any Covered Software prove defective in any respect, You (not any + Contributor) assume the cost of any necessary servicing, repair, or + correction. This disclaimer of warranty constitutes an essential part of this + License. No use of any Covered Software is authorized under this License + except under this disclaimer. + +7. Limitation of Liability + + Under no circumstances and under no legal theory, whether tort (including + negligence), contract, or otherwise, shall any Contributor, or anyone who + distributes Covered Software as permitted above, be liable to You for any + direct, indirect, special, incidental, or consequential damages of any + character including, without limitation, damages for lost profits, loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses, even if such party shall have been + informed of the possibility of such damages. This limitation of liability + shall not apply to liability for death or personal injury resulting from such + party’s negligence to the extent applicable law prohibits such limitation. + Some jurisdictions do not allow the exclusion or limitation of incidental or + consequential damages, so this exclusion and limitation may not apply to You. + +8. Litigation + + Any litigation relating to this License may be brought only in the courts of + a jurisdiction where the defendant maintains its principal place of business + and such litigation shall be governed by laws of that jurisdiction, without + reference to its conflict-of-law provisions. Nothing in this Section shall + prevent a party’s ability to bring cross-claims or counter-claims. + +9. Miscellaneous + + This License represents the complete agreement concerning the subject matter + hereof. If any provision of this License is held to be unenforceable, such + provision shall be reformed only to the extent necessary to make it + enforceable. Any law or regulation which provides that the language of a + contract shall be construed against the drafter shall not be used to construe + this License against a Contributor. + + +10. Versions of the License + +10.1. New Versions + + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. + +10.2. Effect of New Versions + + You may distribute the Covered Software under the terms of the version of + the License under which You originally received the Covered Software, or + under the terms of any subsequent version published by the license + steward. + +10.3. Modified Versions + + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a modified + version of this License if you rename the license and remove any + references to the name of the license steward (except to note that such + modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses + If You choose to distribute Source Code Form that is Incompatible With + Secondary Licenses under the terms of this version of the License, the + notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the + terms of the Mozilla Public License, v. + 2.0. If a copy of the MPL was not + distributed with this file, You can + obtain one at + http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular file, then +You may include the notice in a location (such as a LICENSE file in a relevant +directory) where a recipient would be likely to look for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - “Incompatible With Secondary Licenses” Notice + + This Source Code Form is “Incompatible + With Secondary Licenses”, as defined by + the Mozilla Public License, v. 2.0. diff --git a/vendor/github.com/hashicorp/go-multierror/README.md b/vendor/github.com/hashicorp/go-multierror/README.md new file mode 100644 index 000000000..ead5830f7 --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/README.md @@ -0,0 +1,97 @@ +# go-multierror + +[![Build Status](http://img.shields.io/travis/hashicorp/go-multierror.svg?style=flat-square)][travis] +[![Go Documentation](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)][godocs] + +[travis]: https://travis-ci.org/hashicorp/go-multierror +[godocs]: https://godoc.org/github.com/hashicorp/go-multierror + +`go-multierror` is a package for Go that provides a mechanism for +representing a list of `error` values as a single `error`. + +This allows a function in Go to return an `error` that might actually +be a list of errors. If the caller knows this, they can unwrap the +list and access the errors. If the caller doesn't know, the error +formats to a nice human-readable format. + +`go-multierror` implements the +[errwrap](https://github.com/hashicorp/errwrap) interface so that it can +be used with that library, as well. + +## Installation and Docs + +Install using `go get github.com/hashicorp/go-multierror`. + +Full documentation is available at +http://godoc.org/github.com/hashicorp/go-multierror + +## Usage + +go-multierror is easy to use and purposely built to be unobtrusive in +existing Go applications/libraries that may not be aware of it. + +**Building a list of errors** + +The `Append` function is used to create a list of errors. This function +behaves a lot like the Go built-in `append` function: it doesn't matter +if the first argument is nil, a `multierror.Error`, or any other `error`, +the function behaves as you would expect. + +```go +var result error + +if err := step1(); err != nil { + result = multierror.Append(result, err) +} +if err := step2(); err != nil { + result = multierror.Append(result, err) +} + +return result +``` + +**Customizing the formatting of the errors** + +By specifying a custom `ErrorFormat`, you can customize the format +of the `Error() string` function: + +```go +var result *multierror.Error + +// ... accumulate errors here, maybe using Append + +if result != nil { + result.ErrorFormat = func([]error) string { + return "errors!" + } +} +``` + +**Accessing the list of errors** + +`multierror.Error` implements `error` so if the caller doesn't know about +multierror, it will work just fine. But if you're aware a multierror might +be returned, you can use type switches to access the list of errors: + +```go +if err := something(); err != nil { + if merr, ok := err.(*multierror.Error); ok { + // Use merr.Errors + } +} +``` + +**Returning a multierror only if there are errors** + +If you build a `multierror.Error`, you can use the `ErrorOrNil` function +to return an `error` implementation only if there are errors to return: + +```go +var result *multierror.Error + +// ... accumulate errors here + +// Return the `error` only if errors were added to the multierror, otherwise +// return nil since there are no errors. +return result.ErrorOrNil() +``` diff --git a/vendor/github.com/hashicorp/go-multierror/append.go b/vendor/github.com/hashicorp/go-multierror/append.go new file mode 100644 index 000000000..775b6e753 --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/append.go @@ -0,0 +1,41 @@ +package multierror + +// Append is a helper function that will append more errors +// onto an Error in order to create a larger multi-error. +// +// If err is not a multierror.Error, then it will be turned into +// one. If any of the errs are multierr.Error, they will be flattened +// one level into err. +func Append(err error, errs ...error) *Error { + switch err := err.(type) { + case *Error: + // Typed nils can reach here, so initialize if we are nil + if err == nil { + err = new(Error) + } + + // Go through each error and flatten + for _, e := range errs { + switch e := e.(type) { + case *Error: + if e != nil { + err.Errors = append(err.Errors, e.Errors...) + } + default: + if e != nil { + err.Errors = append(err.Errors, e) + } + } + } + + return err + default: + newErrs := make([]error, 0, len(errs)+1) + if err != nil { + newErrs = append(newErrs, err) + } + newErrs = append(newErrs, errs...) + + return Append(&Error{}, newErrs...) + } +} diff --git a/vendor/github.com/hashicorp/go-multierror/flatten.go b/vendor/github.com/hashicorp/go-multierror/flatten.go new file mode 100644 index 000000000..aab8e9abe --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/flatten.go @@ -0,0 +1,26 @@ +package multierror + +// Flatten flattens the given error, merging any *Errors together into +// a single *Error. +func Flatten(err error) error { + // If it isn't an *Error, just return the error as-is + if _, ok := err.(*Error); !ok { + return err + } + + // Otherwise, make the result and flatten away! + flatErr := new(Error) + flatten(err, flatErr) + return flatErr +} + +func flatten(err error, flatErr *Error) { + switch err := err.(type) { + case *Error: + for _, e := range err.Errors { + flatten(e, flatErr) + } + default: + flatErr.Errors = append(flatErr.Errors, err) + } +} diff --git a/vendor/github.com/hashicorp/go-multierror/format.go b/vendor/github.com/hashicorp/go-multierror/format.go new file mode 100644 index 000000000..47f13c49a --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/format.go @@ -0,0 +1,27 @@ +package multierror + +import ( + "fmt" + "strings" +) + +// ErrorFormatFunc is a function callback that is called by Error to +// turn the list of errors into a string. +type ErrorFormatFunc func([]error) string + +// ListFormatFunc is a basic formatter that outputs the number of errors +// that occurred along with a bullet point list of the errors. +func ListFormatFunc(es []error) string { + if len(es) == 1 { + return fmt.Sprintf("1 error occurred:\n\t* %s\n\n", es[0]) + } + + points := make([]string, len(es)) + for i, err := range es { + points[i] = fmt.Sprintf("* %s", err) + } + + return fmt.Sprintf( + "%d errors occurred:\n\t%s\n\n", + len(es), strings.Join(points, "\n\t")) +} diff --git a/vendor/github.com/hashicorp/go-multierror/go.mod b/vendor/github.com/hashicorp/go-multierror/go.mod new file mode 100644 index 000000000..2534331d5 --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/go.mod @@ -0,0 +1,3 @@ +module github.com/hashicorp/go-multierror + +require github.com/hashicorp/errwrap v1.0.0 diff --git a/vendor/github.com/hashicorp/go-multierror/multierror.go b/vendor/github.com/hashicorp/go-multierror/multierror.go new file mode 100644 index 000000000..89b1422d1 --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/multierror.go @@ -0,0 +1,51 @@ +package multierror + +import ( + "fmt" +) + +// Error is an error type to track multiple errors. This is used to +// accumulate errors in cases and return them as a single "error". +type Error struct { + Errors []error + ErrorFormat ErrorFormatFunc +} + +func (e *Error) Error() string { + fn := e.ErrorFormat + if fn == nil { + fn = ListFormatFunc + } + + return fn(e.Errors) +} + +// ErrorOrNil returns an error interface if this Error represents +// a list of errors, or returns nil if the list of errors is empty. This +// function is useful at the end of accumulation to make sure that the value +// returned represents the existence of errors. +func (e *Error) ErrorOrNil() error { + if e == nil { + return nil + } + if len(e.Errors) == 0 { + return nil + } + + return e +} + +func (e *Error) GoString() string { + return fmt.Sprintf("*%#v", *e) +} + +// WrappedErrors returns the list of errors that this Error is wrapping. +// It is an implementation of the errwrap.Wrapper interface so that +// multierror.Error can be used with that library. +// +// This method is not safe to be called concurrently and is no different +// than accessing the Errors field directly. It is implemented only to +// satisfy the errwrap.Wrapper interface. +func (e *Error) WrappedErrors() []error { + return e.Errors +} diff --git a/vendor/github.com/hashicorp/go-multierror/prefix.go b/vendor/github.com/hashicorp/go-multierror/prefix.go new file mode 100644 index 000000000..5c477abe4 --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/prefix.go @@ -0,0 +1,37 @@ +package multierror + +import ( + "fmt" + + "github.com/hashicorp/errwrap" +) + +// Prefix is a helper function that will prefix some text +// to the given error. If the error is a multierror.Error, then +// it will be prefixed to each wrapped error. +// +// This is useful to use when appending multiple multierrors +// together in order to give better scoping. +func Prefix(err error, prefix string) error { + if err == nil { + return nil + } + + format := fmt.Sprintf("%s {{err}}", prefix) + switch err := err.(type) { + case *Error: + // Typed nils can reach here, so initialize if we are nil + if err == nil { + err = new(Error) + } + + // Wrap each of the errors + for i, e := range err.Errors { + err.Errors[i] = errwrap.Wrapf(format, e) + } + + return err + default: + return errwrap.Wrapf(format, err) + } +} diff --git a/vendor/github.com/hashicorp/go-multierror/sort.go b/vendor/github.com/hashicorp/go-multierror/sort.go new file mode 100644 index 000000000..fecb14e81 --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/sort.go @@ -0,0 +1,16 @@ +package multierror + +// Len implements sort.Interface function for length +func (err Error) Len() int { + return len(err.Errors) +} + +// Swap implements sort.Interface function for swapping elements +func (err Error) Swap(i, j int) { + err.Errors[i], err.Errors[j] = err.Errors[j], err.Errors[i] +} + +// Less implements sort.Interface function for determining order +func (err Error) Less(i, j int) bool { + return err.Errors[i].Error() < err.Errors[j].Error() +}