From 4d829484f63e261c38133f9e1d1e0583e84ddaf8 Mon Sep 17 00:00:00 2001 From: Erno Aapa Date: Thu, 15 Feb 2018 06:30:16 +0200 Subject: [PATCH] Switch to containerd v1.0.2 --- pkg/runtime/containerd.go | 12 +- .../containerd/containerd/README.md | 3 +- .../containerd/containerd/cio/io.go | 242 +++---- .../containerd/containerd/cio/io_unix.go | 218 +++--- .../containerd/containerd/cio/io_windows.go | 73 +- .../containerd/containerd/client.go | 54 +- .../containerd/containerd/container.go | 32 +- .../containerd/container_opts_unix.go | 40 +- .../containerd/defaults/defaults_unix.go | 19 - .../containerd/defaults/defaults_windows.go | 27 - .../containerd/containerd/defaults/doc.go | 3 - .../containerd/containerd/events/events.go | 4 +- .../containerd/containerd/fs/copy_linux.go | 15 +- .../containerd/containerd/fs/copy_unix.go | 15 +- .../containerd/containerd/fs/diff.go | 2 +- .../containerd/containerd/fs/du_unix.go | 17 +- .../containerd/containerd/fs/hardlink_unix.go | 3 +- .../containerd/containerd/fs/path.go | 4 +- .../containerd/containerd/images/image.go | 26 +- .../containerd/containerd/log/context.go | 41 ++ .../containerd/mount/lookup_unix.go | 19 +- .../containerd/containerd/mount/mount.go | 48 -- .../containerd/mount/mount_windows.go | 72 +- .../containerd/containerd/oci/spec_opts.go | 57 -- .../containerd/oci/spec_opts_unix.go | 181 +++-- .../containerd/platforms/cpuinfo.go | 85 --- .../containerd/platforms/database.go | 18 - .../containerd/platforms/defaults.go | 3 +- .../containerd/containerd/plugin/context.go | 3 +- .../containerd/containerd/process.go | 1 - .../containerd/remotes/docker/resolver.go | 3 - .../containerd/containerd/remotes/handlers.go | 57 +- .../containerd/containerd/remotes/hints.go | 31 + .../containerd/containerd/sys/filesys_unix.go | 10 - .../containerd/sys/filesys_windows.go | 11 - .../containerd/containerd/sys/prctl.go | 41 ++ .../containerd/containerd/sys/stat_bsd.go | 6 - .../containerd/containerd/sys/stat_unix.go | 6 - .../github.com/containerd/containerd/task.go | 5 +- .../containerd/containerd/vendor.conf | 21 +- vendor/github.com/syndtr/gocapability/LICENSE | 24 - .../gocapability/capability/capability.go | 72 -- .../capability/capability_linux.go | 650 ------------------ .../capability/capability_noop.go | 19 - .../syndtr/gocapability/capability/enum.go | 268 -------- .../gocapability/capability/enum_gen.go | 129 ---- .../gocapability/capability/syscall_linux.go | 154 ----- 47 files changed, 623 insertions(+), 2221 deletions(-) delete mode 100644 vendor/github.com/containerd/containerd/defaults/defaults_unix.go delete mode 100644 vendor/github.com/containerd/containerd/defaults/defaults_windows.go delete mode 100644 vendor/github.com/containerd/containerd/defaults/doc.go delete mode 100644 vendor/github.com/containerd/containerd/platforms/cpuinfo.go create mode 100644 vendor/github.com/containerd/containerd/remotes/hints.go delete mode 100644 vendor/github.com/containerd/containerd/sys/filesys_unix.go create mode 100644 vendor/github.com/containerd/containerd/sys/prctl.go delete mode 100644 vendor/github.com/syndtr/gocapability/LICENSE delete mode 100644 vendor/github.com/syndtr/gocapability/capability/capability.go delete mode 100644 vendor/github.com/syndtr/gocapability/capability/capability_linux.go delete mode 100644 vendor/github.com/syndtr/gocapability/capability/capability_noop.go delete mode 100644 vendor/github.com/syndtr/gocapability/capability/enum.go delete mode 100644 vendor/github.com/syndtr/gocapability/capability/enum_gen.go delete mode 100644 vendor/github.com/syndtr/gocapability/capability/syscall_linux.go diff --git a/pkg/runtime/containerd.go b/pkg/runtime/containerd.go index e5b4f351..52356eb7 100644 --- a/pkg/runtime/containerd.go +++ b/pkg/runtime/containerd.go @@ -523,15 +523,7 @@ func (c *ContainerdClient) Exec(namespace, name, id string, args []string, tty b pspec.Terminal = tty pspec.Args = args - ioOpts := []cio.Opt{ - cio.WithStreams(io.Stdin, io.Stdout, io.Stderr), - } - - if tty { - ioOpts = append(ioOpts, cio.WithTerminal) - } - - process, err := task.Exec(ctx, id, pspec, cio.NewCreator(ioOpts...)) + process, err := task.Exec(ctx, id, pspec, cio.NewIOWithTerminal(io.Stdin, io.Stdout, io.Stderr, tty)) if err != nil { return err } @@ -565,7 +557,7 @@ func (c *ContainerdClient) Attach(namespace, name string, io AttachIO) error { return errors.Wrapf(err, "Cannot attach to container [%s] in namespace [%s]", name, namespace) } - task, taskErr := container.Task(ctx, cio.NewAttach(cio.WithStreams(io.Stdin, io.Stdout, io.Stderr))) + task, taskErr := container.Task(ctx, cio.WithAttach(io.Stdin, io.Stdout, io.Stderr)) if taskErr != nil { return taskErr } diff --git a/vendor/github.com/containerd/containerd/README.md b/vendor/github.com/containerd/containerd/README.md index d76ce1b2..84d1eec8 100644 --- a/vendor/github.com/containerd/containerd/README.md +++ b/vendor/github.com/containerd/containerd/README.md @@ -4,7 +4,6 @@ [![Build Status](https://travis-ci.org/containerd/containerd.svg?branch=master)](https://travis-ci.org/containerd/containerd) [![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) containerd is an industry-standard container runtime with an emphasis on simplicity, robustness and portability. It is available as a daemon for Linux and Windows, which can manage the complete container lifecycle of its host system: image transfer and storage, container execution and supervision, low-level storage and network attachments, etc. @@ -14,7 +13,7 @@ containerd is designed to be embedded into a larger system, rather than being us ## Getting Started -See our documentation on [containerd.io](https://containerd.io): +See our documentation on [containerd.io](containerd.io): * [for ops and admins](docs/ops.md) * [namespaces](docs/namespaces.md) * [client options](docs/client-opts.md) diff --git a/vendor/github.com/containerd/containerd/cio/io.go b/vendor/github.com/containerd/containerd/cio/io.go index 87b713e1..4fd9c8d8 100644 --- a/vendor/github.com/containerd/containerd/cio/io.go +++ b/vendor/github.com/containerd/containerd/cio/io.go @@ -6,8 +6,6 @@ import ( "io" "os" "sync" - - "github.com/containerd/containerd/defaults" ) var bufPool = sync.Pool{ @@ -33,167 +31,173 @@ type Config struct { type IO interface { // Config returns the IO configuration. Config() Config - // Cancel aborts all current io operations. + // Cancel aborts all current io operations Cancel() - // Wait blocks until all io copy operations have completed. + // Wait blocks until all io copy operations have completed Wait() - // Close cleans up all open io resources. Cancel() is always called before - // Close() + // Close cleans up all open io resources Close() error } -// Creator creates new IO sets for a task -type Creator func(id string) (IO, error) +// cio is a basic container IO implementation. +type cio struct { + config Config -// Attach allows callers to reattach to running tasks -// -// There should only be one reader for a task's IO set -// because fifo's can only be read from one reader or the output -// will be sent only to the first reads -type Attach func(*FIFOSet) (IO, error) + closer *wgCloser +} -// FIFOSet is a set of file paths to FIFOs for a task's standard IO streams -type FIFOSet struct { - Config - close func() error +func (c *cio) Config() Config { + return c.config } -// Close the FIFOSet -func (f *FIFOSet) Close() error { - if f.close != nil { - return f.close() +func (c *cio) Cancel() { + if c.closer == nil { + return } - return nil + c.closer.Cancel() } -// NewFIFOSet returns a new FIFOSet from a Config and a close function -func NewFIFOSet(config Config, close func() error) *FIFOSet { - return &FIFOSet{Config: config, close: close} +func (c *cio) Wait() { + if c.closer == nil { + return + } + c.closer.Wait() } -// Streams used to configure a Creator or Attach -type Streams struct { - Stdin io.Reader - Stdout io.Writer - Stderr io.Writer - Terminal bool - FIFODir string +func (c *cio) Close() error { + if c.closer == nil { + return nil + } + return c.closer.Close() } -// Opt customize options for creating a Creator or Attach -type Opt func(*Streams) - -// WithStdio sets stream options to the standard input/output streams -func WithStdio(opt *Streams) { - WithStreams(os.Stdin, os.Stdout, os.Stderr)(opt) -} +// Creation creates new IO sets for a task +type Creation func(id string) (IO, error) -// WithTerminal sets the terminal option -func WithTerminal(opt *Streams) { - opt.Terminal = true -} +// Attach allows callers to reattach to running tasks +// +// There should only be one reader for a task's IO set +// because fifo's can only be read from one reader or the output +// will be sent only to the first reads +type Attach func(*FIFOSet) (IO, error) -// WithStreams sets the stream options to the specified Reader and Writers -func WithStreams(stdin io.Reader, stdout, stderr io.Writer) Opt { - return func(opt *Streams) { - opt.Stdin = stdin - opt.Stdout = stdout - opt.Stderr = stderr - } +// NewIO returns an Creation that will provide IO sets without a terminal +func NewIO(stdin io.Reader, stdout, stderr io.Writer) Creation { + return NewIOWithTerminal(stdin, stdout, stderr, false) } -// WithFIFODir sets the fifo directory. -// e.g. "/run/containerd/fifo", "/run/users/1001/containerd/fifo" -func WithFIFODir(dir string) Opt { - return func(opt *Streams) { - opt.FIFODir = dir +// NewIOWithTerminal creates a new io set with the provied io.Reader/Writers for use with a terminal +func NewIOWithTerminal(stdin io.Reader, stdout, stderr io.Writer, terminal bool) Creation { + return func(id string) (_ IO, err error) { + paths, err := NewFifos(id) + if err != nil { + return nil, err + } + defer func() { + if err != nil && paths.Dir != "" { + os.RemoveAll(paths.Dir) + } + }() + cfg := Config{ + Terminal: terminal, + Stdout: paths.Out, + Stderr: paths.Err, + Stdin: paths.In, + } + i := &cio{config: cfg} + set := &ioSet{ + in: stdin, + out: stdout, + err: stderr, + } + closer, err := copyIO(paths, set, cfg.Terminal) + if err != nil { + return nil, err + } + i.closer = closer + return i, nil } } -// NewCreator returns an IO creator from the options -func NewCreator(opts ...Opt) Creator { - streams := &Streams{} - for _, opt := range opts { - opt(streams) - } - if streams.FIFODir == "" { - streams.FIFODir = defaults.DefaultFIFODir - } - return func(id string) (IO, error) { - fifos, err := NewFIFOSetInDir(streams.FIFODir, id, streams.Terminal) +// WithAttach attaches the existing io for a task to the provided io.Reader/Writers +func WithAttach(stdin io.Reader, stdout, stderr io.Writer) Attach { + return func(paths *FIFOSet) (IO, error) { + if paths == nil { + return nil, fmt.Errorf("cannot attach to existing fifos") + } + cfg := Config{ + Terminal: paths.Terminal, + Stdout: paths.Out, + Stderr: paths.Err, + Stdin: paths.In, + } + i := &cio{config: cfg} + set := &ioSet{ + in: stdin, + out: stdout, + err: stderr, + } + closer, err := copyIO(paths, set, cfg.Terminal) if err != nil { return nil, err } - return copyIO(fifos, streams) + i.closer = closer + return i, nil } } -// NewAttach attaches the existing io for a task to the provided io.Reader/Writers -func NewAttach(opts ...Opt) Attach { - streams := &Streams{} - for _, opt := range opts { - opt(streams) - } - return func(fifos *FIFOSet) (IO, error) { - if fifos == nil { - return nil, fmt.Errorf("cannot attach, missing fifos") - } - return copyIO(fifos, streams) - } +// Stdio returns an IO set to be used for a task +// that outputs the container's IO as the current processes Stdio +func Stdio(id string) (IO, error) { + return NewIO(os.Stdin, os.Stdout, os.Stderr)(id) +} + +// StdioTerminal will setup the IO for the task to use a terminal +func StdioTerminal(id string) (IO, error) { + return NewIOWithTerminal(os.Stdin, os.Stdout, os.Stderr, true)(id) } // NullIO redirects the container's IO into /dev/null -func NullIO(_ string) (IO, error) { +func NullIO(id string) (IO, error) { return &cio{}, nil } -// cio is a basic container IO implementation. -type cio struct { - config Config - wg *sync.WaitGroup - closers []io.Closer - cancel context.CancelFunc +// FIFOSet is a set of fifos for use with tasks +type FIFOSet struct { + // Dir is the directory holding the task fifos + Dir string + // In, Out, and Err fifo paths + In, Out, Err string + // Terminal returns true if a terminal is being used for the task + Terminal bool } -func (c *cio) Config() Config { - return c.config +type ioSet struct { + in io.Reader + out, err io.Writer } -func (c *cio) Wait() { - if c.wg != nil { - c.wg.Wait() - } +type wgCloser struct { + wg *sync.WaitGroup + dir string + set []io.Closer + cancel context.CancelFunc } -func (c *cio) Close() error { - var lastErr error - for _, closer := range c.closers { - if closer == nil { - continue - } - if err := closer.Close(); err != nil { - lastErr = err - } - } - return lastErr +func (g *wgCloser) Wait() { + g.wg.Wait() } -func (c *cio) Cancel() { - if c.cancel != nil { - c.cancel() +func (g *wgCloser) Close() error { + for _, f := range g.set { + f.Close() } + if g.dir != "" { + return os.RemoveAll(g.dir) + } + return nil } -type pipes struct { - Stdin io.WriteCloser - Stdout io.ReadCloser - Stderr io.ReadCloser -} - -// DirectIO allows task IO to be handled externally by the caller -type DirectIO struct { - pipes - cio +func (g *wgCloser) Cancel() { + g.cancel() } - -var _ IO = &DirectIO{} diff --git a/vendor/github.com/containerd/containerd/cio/io_unix.go b/vendor/github.com/containerd/containerd/cio/io_unix.go index 1eadcd50..fc047847 100644 --- a/vendor/github.com/containerd/containerd/cio/io_unix.go +++ b/vendor/github.com/containerd/containerd/cio/io_unix.go @@ -12,124 +12,180 @@ import ( "syscall" "github.com/containerd/fifo" - "github.com/pkg/errors" ) -// NewFIFOSetInDir returns a new FIFOSet with paths in a temporary directory under root -func NewFIFOSetInDir(root, id string, terminal bool) (*FIFOSet, error) { - if root != "" { - if err := os.MkdirAll(root, 0700); err != nil { - return nil, err - } +// NewFifos returns a new set of fifos for the task +func NewFifos(id string) (*FIFOSet, error) { + root := "/run/containerd/fifo" + if err := os.MkdirAll(root, 0700); err != nil { + return nil, err } dir, err := ioutil.TempDir(root, "") if err != nil { return nil, err } - closer := func() error { - return os.RemoveAll(dir) - } - return NewFIFOSet(Config{ - Stdin: filepath.Join(dir, id+"-stdin"), - Stdout: filepath.Join(dir, id+"-stdout"), - Stderr: filepath.Join(dir, id+"-stderr"), - Terminal: terminal, - }, closer), nil + return &FIFOSet{ + Dir: dir, + In: filepath.Join(dir, id+"-stdin"), + Out: filepath.Join(dir, id+"-stdout"), + Err: filepath.Join(dir, id+"-stderr"), + }, nil } -func copyIO(fifos *FIFOSet, ioset *Streams) (*cio, error) { - var ctx, cancel = context.WithCancel(context.Background()) - pipes, err := openFifos(ctx, fifos) - if err != nil { - cancel() +func copyIO(fifos *FIFOSet, ioset *ioSet, tty bool) (_ *wgCloser, err error) { + var ( + f io.ReadWriteCloser + set []io.Closer + ctx, cancel = context.WithCancel(context.Background()) + wg = &sync.WaitGroup{} + ) + defer func() { + if err != nil { + for _, f := range set { + f.Close() + } + cancel() + } + }() + + if f, err = fifo.OpenFifo(ctx, fifos.In, syscall.O_WRONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil { return nil, err } + set = append(set, f) + go func(w io.WriteCloser) { + p := bufPool.Get().(*[]byte) + defer bufPool.Put(p) + io.CopyBuffer(w, ioset.in, *p) + w.Close() + }(f) - if fifos.Stdin != "" { - go func() { - p := bufPool.Get().(*[]byte) - defer bufPool.Put(p) - - io.CopyBuffer(pipes.Stdin, ioset.Stdin, *p) - pipes.Stdin.Close() - }() + if f, err = fifo.OpenFifo(ctx, fifos.Out, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil { + return nil, err } - - var wg = &sync.WaitGroup{} + set = append(set, f) wg.Add(1) - go func() { + go func(r io.ReadCloser) { p := bufPool.Get().(*[]byte) defer bufPool.Put(p) - - io.CopyBuffer(ioset.Stdout, pipes.Stdout, *p) - pipes.Stdout.Close() + io.CopyBuffer(ioset.out, r, *p) + r.Close() wg.Done() - }() + }(f) - if !fifos.Terminal { + if f, err = fifo.OpenFifo(ctx, fifos.Err, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil { + return nil, err + } + set = append(set, f) + + if !tty { wg.Add(1) - go func() { + go func(r io.ReadCloser) { p := bufPool.Get().(*[]byte) defer bufPool.Put(p) - io.CopyBuffer(ioset.Stderr, pipes.Stderr, *p) - pipes.Stderr.Close() + io.CopyBuffer(ioset.err, r, *p) + r.Close() wg.Done() - }() + }(f) } - return &cio{ - config: fifos.Config, - wg: wg, - closers: append(pipes.closers(), fifos), - cancel: cancel, + return &wgCloser{ + wg: wg, + dir: fifos.Dir, + set: set, + cancel: cancel, }, nil } -func openFifos(ctx context.Context, fifos *FIFOSet) (pipes, error) { - var err error +// NewDirectIO returns an IO implementation that exposes the pipes directly +func NewDirectIO(ctx context.Context, terminal bool) (*DirectIO, error) { + set, err := NewFifos("") + if err != nil { + return nil, err + } + f := &DirectIO{ + set: set, + terminal: terminal, + } defer func() { if err != nil { - fifos.Close() + f.Delete() } }() - - var f pipes - if fifos.Stdin != "" { - if f.Stdin, err = fifo.OpenFifo(ctx, fifos.Stdin, syscall.O_WRONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil { - return f, errors.Wrapf(err, "failed to open stdin fifo") - } + if f.Stdin, err = fifo.OpenFifo(ctx, set.In, syscall.O_WRONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil { + return nil, err } - if fifos.Stdout != "" { - if f.Stdout, err = fifo.OpenFifo(ctx, fifos.Stdout, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil { - f.Stdin.Close() - return f, errors.Wrapf(err, "failed to open stdout fifo") - } + if f.Stdout, err = fifo.OpenFifo(ctx, set.Out, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil { + f.Stdin.Close() + return nil, err } - if fifos.Stderr != "" { - if f.Stderr, err = fifo.OpenFifo(ctx, fifos.Stderr, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil { - f.Stdin.Close() - f.Stdout.Close() - return f, errors.Wrapf(err, "failed to open stderr fifo") - } + if f.Stderr, err = fifo.OpenFifo(ctx, set.Err, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil { + f.Stdin.Close() + f.Stdout.Close() + return nil, err } return f, nil } -// NewDirectIO returns an IO implementation that exposes the IO streams as io.ReadCloser -// and io.WriteCloser. -func NewDirectIO(ctx context.Context, fifos *FIFOSet) (*DirectIO, error) { - ctx, cancel := context.WithCancel(ctx) - pipes, err := openFifos(ctx, fifos) - return &DirectIO{ - pipes: pipes, - cio: cio{ - config: fifos.Config, - closers: append(pipes.closers(), fifos), - cancel: cancel, - }, - }, err +// DirectIO allows task IO to be handled externally by the caller +type DirectIO struct { + Stdin io.WriteCloser + Stdout io.ReadCloser + Stderr io.ReadCloser + + set *FIFOSet + terminal bool +} + +// IOCreate returns IO avaliable for use with task creation +func (f *DirectIO) IOCreate(id string) (IO, error) { + return f, nil +} + +// IOAttach returns IO avaliable for use with task attachment +func (f *DirectIO) IOAttach(set *FIFOSet) (IO, error) { + return f, nil +} + +// Config returns the Config +func (f *DirectIO) Config() Config { + return Config{ + Terminal: f.terminal, + Stdin: f.set.In, + Stdout: f.set.Out, + Stderr: f.set.Err, + } } -func (p *pipes) closers() []io.Closer { - return []io.Closer{p.Stdin, p.Stdout, p.Stderr} +// Cancel stops any IO copy operations +// +// Not applicable for DirectIO +func (f *DirectIO) Cancel() { + // nothing to cancel as all operations are handled externally +} + +// Wait on any IO copy operations +// +// Not applicable for DirectIO +func (f *DirectIO) Wait() { + // nothing to wait on as all operations are handled externally +} + +// Close closes all open fds +func (f *DirectIO) Close() error { + err := f.Stdin.Close() + if err2 := f.Stdout.Close(); err == nil { + err = err2 + } + if err2 := f.Stderr.Close(); err == nil { + err = err2 + } + return err +} + +// Delete removes the underlying directory containing fifos +func (f *DirectIO) Delete() error { + if f.set.Dir == "" { + return nil + } + return os.RemoveAll(f.set.Dir) } diff --git a/vendor/github.com/containerd/containerd/cio/io_windows.go b/vendor/github.com/containerd/containerd/cio/io_windows.go index 4c1eefac..2c8410fb 100644 --- a/vendor/github.com/containerd/containerd/cio/io_windows.go +++ b/vendor/github.com/containerd/containerd/cio/io_windows.go @@ -13,26 +13,25 @@ import ( const pipeRoot = `\\.\pipe` -// NewFIFOSetInDir returns a new set of fifos for the task -func NewFIFOSetInDir(_, id string, terminal bool) (*FIFOSet, error) { - return NewFIFOSet(Config{ - Terminal: terminal, - Stdin: fmt.Sprintf(`%s\ctr-%s-stdin`, pipeRoot, id), - Stdout: fmt.Sprintf(`%s\ctr-%s-stdout`, pipeRoot, id), - Stderr: fmt.Sprintf(`%s\ctr-%s-stderr`, pipeRoot, id), - }, nil), nil +// NewFifos returns a new set of fifos for the task +func NewFifos(id string) (*FIFOSet, error) { + return &FIFOSet{ + In: fmt.Sprintf(`%s\ctr-%s-stdin`, pipeRoot, id), + Out: fmt.Sprintf(`%s\ctr-%s-stdout`, pipeRoot, id), + Err: fmt.Sprintf(`%s\ctr-%s-stderr`, pipeRoot, id), + }, nil } -func copyIO(fifos *FIFOSet, ioset *Streams) (*cio, error) { +func copyIO(fifos *FIFOSet, ioset *ioSet, tty bool) (_ *wgCloser, err error) { var ( wg sync.WaitGroup set []io.Closer ) - if fifos.Stdin != "" { - l, err := winio.ListenPipe(fifos.Stdin, nil) + if fifos.In != "" { + l, err := winio.ListenPipe(fifos.In, nil) if err != nil { - return nil, errors.Wrapf(err, "failed to create stdin pipe %s", fifos.Stdin) + return nil, errors.Wrapf(err, "failed to create stdin pipe %s", fifos.In) } defer func(l net.Listener) { if err != nil { @@ -44,23 +43,23 @@ func copyIO(fifos *FIFOSet, ioset *Streams) (*cio, error) { go func() { c, err := l.Accept() if err != nil { - log.L.WithError(err).Errorf("failed to accept stdin connection on %s", fifos.Stdin) + log.L.WithError(err).Errorf("failed to accept stdin connection on %s", fifos.In) return } p := bufPool.Get().(*[]byte) defer bufPool.Put(p) - io.CopyBuffer(c, ioset.Stdin, *p) + io.CopyBuffer(c, ioset.in, *p) c.Close() l.Close() }() } - if fifos.Stdout != "" { - l, err := winio.ListenPipe(fifos.Stdout, nil) + if fifos.Out != "" { + l, err := winio.ListenPipe(fifos.Out, nil) if err != nil { - return nil, errors.Wrapf(err, "failed to create stdin pipe %s", fifos.Stdout) + return nil, errors.Wrapf(err, "failed to create stdin pipe %s", fifos.Out) } defer func(l net.Listener) { if err != nil { @@ -74,23 +73,22 @@ func copyIO(fifos *FIFOSet, ioset *Streams) (*cio, error) { defer wg.Done() c, err := l.Accept() if err != nil { - log.L.WithError(err).Errorf("failed to accept stdout connection on %s", fifos.Stdout) + log.L.WithError(err).Errorf("failed to accept stdout connection on %s", fifos.Out) return } - p := bufPool.Get().(*[]byte) defer bufPool.Put(p) - io.CopyBuffer(ioset.Stdout, c, *p) + io.CopyBuffer(ioset.out, c, *p) c.Close() l.Close() }() } - if !fifos.Terminal && fifos.Stderr != "" { - l, err := winio.ListenPipe(fifos.Stderr, nil) + if !tty && fifos.Err != "" { + l, err := winio.ListenPipe(fifos.Err, nil) if err != nil { - return nil, errors.Wrapf(err, "failed to create stderr pipe %s", fifos.Stderr) + return nil, errors.Wrapf(err, "failed to create stderr pipe %s", fifos.Err) } defer func(l net.Listener) { if err != nil { @@ -104,33 +102,26 @@ func copyIO(fifos *FIFOSet, ioset *Streams) (*cio, error) { defer wg.Done() c, err := l.Accept() if err != nil { - log.L.WithError(err).Errorf("failed to accept stderr connection on %s", fifos.Stderr) + log.L.WithError(err).Errorf("failed to accept stderr connection on %s", fifos.Err) return } - p := bufPool.Get().(*[]byte) defer bufPool.Put(p) - io.CopyBuffer(ioset.Stderr, c, *p) + io.CopyBuffer(ioset.err, c, *p) c.Close() l.Close() }() } - return &cio{config: fifos.Config, closers: set}, nil -} - -// NewDirectIO returns an IO implementation that exposes the IO streams as io.ReadCloser -// and io.WriteCloser. -func NewDirectIO(stdin io.WriteCloser, stdout, stderr io.ReadCloser, terminal bool) *DirectIO { - return &DirectIO{ - pipes: pipes{ - Stdin: stdin, - Stdout: stdout, - Stderr: stderr, - }, - cio: cio{ - config: Config{Terminal: terminal}, + return &wgCloser{ + wg: &wg, + dir: fifos.Dir, + set: set, + cancel: func() { + for _, l := range set { + l.Close() + } }, - } + }, nil } diff --git a/vendor/github.com/containerd/containerd/client.go b/vendor/github.com/containerd/containerd/client.go index 5c01d577..39547f58 100644 --- a/vendor/github.com/containerd/containerd/client.go +++ b/vendor/github.com/containerd/containerd/client.go @@ -7,6 +7,8 @@ import ( "net/http" "runtime" "strconv" + "strings" + "sync" "time" containersapi "github.com/containerd/containerd/api/services/containers/v1" @@ -220,11 +222,11 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (Image name, desc, err := pullCtx.Resolver.Resolve(ctx, ref) if err != nil { - return nil, errors.Wrapf(err, "failed to resolve reference %q", ref) + return nil, err } fetcher, err := pullCtx.Resolver.Fetcher(ctx, name) if err != nil { - return nil, errors.Wrapf(err, "failed to get fetcher for %q", name) + return nil, err } var ( @@ -279,7 +281,7 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (Image } if pullCtx.Unpack { if err := img.Unpack(ctx, pullCtx.Snapshotter); err != nil { - errors.Wrapf(err, "failed to unpack image on snapshotter %s", pullCtx.Snapshotter) + return nil, err } } return img, nil @@ -299,7 +301,51 @@ func (c *Client) Push(ctx context.Context, ref string, desc ocispec.Descriptor, return err } - return remotes.PushContent(ctx, pusher, desc, c.ContentStore(), pushCtx.BaseHandlers...) + var m sync.Mutex + manifestStack := []ocispec.Descriptor{} + + filterHandler := images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { + switch desc.MediaType { + case images.MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest, + images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex: + m.Lock() + manifestStack = append(manifestStack, desc) + m.Unlock() + return nil, images.ErrStopHandler + default: + return nil, nil + } + }) + + cs := c.ContentStore() + pushHandler := remotes.PushHandler(cs, pusher) + + handlers := append(pushCtx.BaseHandlers, + images.ChildrenHandler(cs, platforms.Default()), + filterHandler, + pushHandler, + ) + + if err := images.Dispatch(ctx, images.Handlers(handlers...), desc); err != nil { + return err + } + + // Iterate in reverse order as seen, parent always uploaded after child + for i := len(manifestStack) - 1; i >= 0; i-- { + _, err := pushHandler(ctx, manifestStack[i]) + if err != nil { + // TODO(estesp): until we have a more complete method for index push, we need to report + // missing dependencies in an index/manifest list by sensing the "400 Bad Request" + // as a marker for this problem + if (manifestStack[i].MediaType == ocispec.MediaTypeImageIndex || + manifestStack[i].MediaType == images.MediaTypeDockerSchema2ManifestList) && + errors.Cause(err) != nil && strings.Contains(errors.Cause(err).Error(), "400 Bad Request") { + return errors.Wrap(err, "manifest list/index references to blobs and/or manifests are missing in your target registry") + } + return err + } + } + return nil } // GetImage returns an existing image diff --git a/vendor/github.com/containerd/containerd/container.go b/vendor/github.com/containerd/containerd/container.go index ad60c69e..716e0456 100644 --- a/vendor/github.com/containerd/containerd/container.go +++ b/vendor/github.com/containerd/containerd/container.go @@ -3,7 +3,6 @@ package containerd import ( "context" "encoding/json" - "os" "path/filepath" "strings" @@ -27,7 +26,7 @@ type Container interface { // Delete removes the container Delete(context.Context, ...DeleteOpts) error // NewTask creates a new task based on the container metadata - NewTask(context.Context, cio.Creator, ...NewTaskOpts) (Task, error) + NewTask(context.Context, cio.Creation, ...NewTaskOpts) (Task, error) // Spec returns the OCI runtime specification Spec(context.Context) (*specs.Spec, error) // Task returns the current task for the container @@ -163,7 +162,7 @@ func (c *container) Image(ctx context.Context) (Image, error) { }, nil } -func (c *container) NewTask(ctx context.Context, ioCreate cio.Creator, opts ...NewTaskOpts) (_ Task, err error) { +func (c *container) NewTask(ctx context.Context, ioCreate cio.Creation, opts ...NewTaskOpts) (_ Task, err error) { i, err := ioCreate(c.id) if err != nil { return nil, err @@ -289,23 +288,20 @@ func (c *container) get(ctx context.Context) (containers.Container, error) { return c.client.ContainerService().Get(ctx, c.id) } -// get the existing fifo paths from the task information stored by the daemon func attachExistingIO(response *tasks.GetResponse, ioAttach cio.Attach) (cio.IO, error) { - path := getFifoDir([]string{ - response.Process.Stdin, - response.Process.Stdout, - response.Process.Stderr, - }) - closer := func() error { - return os.RemoveAll(path) - } - fifoSet := cio.NewFIFOSet(cio.Config{ - Stdin: response.Process.Stdin, - Stdout: response.Process.Stdout, - Stderr: response.Process.Stderr, + // get the existing fifo paths from the task information stored by the daemon + paths := &cio.FIFOSet{ + Dir: getFifoDir([]string{ + response.Process.Stdin, + response.Process.Stdout, + response.Process.Stderr, + }), + In: response.Process.Stdin, + Out: response.Process.Stdout, + Err: response.Process.Stderr, Terminal: response.Process.Terminal, - }, closer) - return ioAttach(fifoSet) + } + return ioAttach(paths) } // getFifoDir looks for any non-empty path for a stdio fifo diff --git a/vendor/github.com/containerd/containerd/container_opts_unix.go b/vendor/github.com/containerd/containerd/container_opts_unix.go index deda0f70..b678033b 100644 --- a/vendor/github.com/containerd/containerd/container_opts_unix.go +++ b/vendor/github.com/containerd/containerd/container_opts_unix.go @@ -6,6 +6,7 @@ import ( "context" "encoding/json" "fmt" + "io/ioutil" "os" "path/filepath" "syscall" @@ -15,7 +16,6 @@ import ( "github.com/containerd/containerd/content" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" - "github.com/containerd/containerd/linux/runctypes" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/platforms" "github.com/gogo/protobuf/proto" @@ -166,7 +166,7 @@ func withRemappedSnapshotBase(id string, i Image, uid, gid uint32, readonly bool if err != nil { return err } - if err := remapRootFS(ctx, mounts, uid, gid); err != nil { + if err := remapRootFS(mounts, uid, gid); err != nil { snapshotter.Remove(ctx, usernsID) return err } @@ -187,10 +187,22 @@ func withRemappedSnapshotBase(id string, i Image, uid, gid uint32, readonly bool } } -func remapRootFS(ctx context.Context, mounts []mount.Mount, uid, gid uint32) error { - return mount.WithTempMount(ctx, mounts, func(root string) error { - return filepath.Walk(root, incrementFS(root, uid, gid)) - }) +func remapRootFS(mounts []mount.Mount, uid, gid uint32) error { + root, err := ioutil.TempDir("", "ctd-remap") + if err != nil { + return err + } + defer os.Remove(root) + for _, m := range mounts { + if err := m.Mount(root); err != nil { + return err + } + } + err = filepath.Walk(root, incrementFS(root, uid, gid)) + if uerr := mount.Unmount(root, 0); err == nil { + err = uerr + } + return err } func incrementFS(root string, uidInc, gidInc uint32) filepath.WalkFunc { @@ -206,19 +218,3 @@ func incrementFS(root string, uidInc, gidInc uint32) filepath.WalkFunc { return os.Lchown(path, u, g) } } - -// WithNoPivotRoot instructs the runtime not to you pivot_root -func WithNoPivotRoot(_ context.Context, _ *Client, info *TaskInfo) error { - if info.Options == nil { - info.Options = &runctypes.CreateOptions{ - NoPivotRoot: true, - } - return nil - } - copts, ok := info.Options.(*runctypes.CreateOptions) - if !ok { - return errors.New("invalid options type, expected runctypes.CreateOptions") - } - copts.NoPivotRoot = true - return nil -} diff --git a/vendor/github.com/containerd/containerd/defaults/defaults_unix.go b/vendor/github.com/containerd/containerd/defaults/defaults_unix.go deleted file mode 100644 index 1a76d569..00000000 --- a/vendor/github.com/containerd/containerd/defaults/defaults_unix.go +++ /dev/null @@ -1,19 +0,0 @@ -// +build !windows - -package defaults - -const ( - // DefaultRootDir is the default location used by containerd to store - // persistent data - DefaultRootDir = "/var/lib/containerd" - // DefaultStateDir is the default location used by containerd to store - // transient data - DefaultStateDir = "/run/containerd" - // DefaultAddress is the default unix socket address - DefaultAddress = "/run/containerd/containerd.sock" - // DefaultDebugAddress is the default unix socket address for pprof data - DefaultDebugAddress = "/run/containerd/debug.sock" - // DefaultFIFODir is the default location used by client-side cio library - // to store FIFOs. - DefaultFIFODir = "/run/containerd/fifo" -) diff --git a/vendor/github.com/containerd/containerd/defaults/defaults_windows.go b/vendor/github.com/containerd/containerd/defaults/defaults_windows.go deleted file mode 100644 index 7d74d22e..00000000 --- a/vendor/github.com/containerd/containerd/defaults/defaults_windows.go +++ /dev/null @@ -1,27 +0,0 @@ -// +build windows - -package defaults - -import ( - "os" - "path/filepath" -) - -var ( - // DefaultRootDir is the default location used by containerd to store - // persistent data - DefaultRootDir = filepath.Join(os.Getenv("programfiles"), "containerd", "root") - // DefaultStateDir is the default location used by containerd to store - // transient data - DefaultStateDir = filepath.Join(os.Getenv("programfiles"), "containerd", "state") -) - -const ( - // DefaultAddress is the default winpipe address - DefaultAddress = `\\.\pipe\containerd-containerd` - // DefaultDebugAddress is the default winpipe address for pprof data - DefaultDebugAddress = `\\.\pipe\containerd-debug` - // DefaultFIFODir is the default location used by client-side cio library - // to store FIFOs. Unused on Windows. - DefaultFIFODir = "" -) diff --git a/vendor/github.com/containerd/containerd/defaults/doc.go b/vendor/github.com/containerd/containerd/defaults/doc.go deleted file mode 100644 index 2c6e39f5..00000000 --- a/vendor/github.com/containerd/containerd/defaults/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package defaults provides several common defaults for interacting wtih -// containerd. These can be used on the client-side or server-side. -package defaults diff --git a/vendor/github.com/containerd/containerd/events/events.go b/vendor/github.com/containerd/containerd/events/events.go index 6f4c8b3a..2bfedb1e 100644 --- a/vendor/github.com/containerd/containerd/events/events.go +++ b/vendor/github.com/containerd/containerd/events/events.go @@ -26,9 +26,9 @@ func (e *Envelope) Field(fieldpath []string) (string, bool) { switch fieldpath[0] { // unhandled: timestamp case "namespace": - return e.Namespace, len(e.Namespace) > 0 + return string(e.Namespace), len(e.Namespace) > 0 case "topic": - return e.Topic, len(e.Topic) > 0 + return string(e.Topic), len(e.Topic) > 0 case "event": decoded, err := typeurl.UnmarshalAny(e.Event) if err != nil { diff --git a/vendor/github.com/containerd/containerd/fs/copy_linux.go b/vendor/github.com/containerd/containerd/fs/copy_linux.go index 47272963..c1fb2d1c 100644 --- a/vendor/github.com/containerd/containerd/fs/copy_linux.go +++ b/vendor/github.com/containerd/containerd/fs/copy_linux.go @@ -14,20 +14,7 @@ import ( func copyFileInfo(fi os.FileInfo, name string) error { st := fi.Sys().(*syscall.Stat_t) if err := os.Lchown(name, int(st.Uid), int(st.Gid)); err != nil { - if os.IsPermission(err) { - // Normally if uid/gid are the same this would be a no-op, but some - // filesystems may still return EPERM... for instance NFS does this. - // In such a case, this is not an error. - if dstStat, err2 := os.Lstat(name); err2 == nil { - st2 := dstStat.Sys().(*syscall.Stat_t) - if st.Uid == st2.Uid && st.Gid == st2.Gid { - err = nil - } - } - } - if err != nil { - return errors.Wrapf(err, "failed to chown %s", name) - } + return errors.Wrapf(err, "failed to chown %s", name) } if (fi.Mode() & os.ModeSymlink) != os.ModeSymlink { diff --git a/vendor/github.com/containerd/containerd/fs/copy_unix.go b/vendor/github.com/containerd/containerd/fs/copy_unix.go index fceb0e63..b31a14fc 100644 --- a/vendor/github.com/containerd/containerd/fs/copy_unix.go +++ b/vendor/github.com/containerd/containerd/fs/copy_unix.go @@ -16,20 +16,7 @@ import ( func copyFileInfo(fi os.FileInfo, name string) error { st := fi.Sys().(*syscall.Stat_t) if err := os.Lchown(name, int(st.Uid), int(st.Gid)); err != nil { - if os.IsPermission(err) { - // Normally if uid/gid are the same this would be a no-op, but some - // filesystems may still return EPERM... for instance NFS does this. - // In such a case, this is not an error. - if dstStat, err2 := os.Lstat(name); err2 == nil { - st2 := dstStat.Sys().(*syscall.Stat_t) - if st.Uid == st2.Uid && st.Gid == st2.Gid { - err = nil - } - } - } - if err != nil { - return errors.Wrapf(err, "failed to chown %s", name) - } + return errors.Wrapf(err, "failed to chown %s", name) } if (fi.Mode() & os.ModeSymlink) != os.ModeSymlink { diff --git a/vendor/github.com/containerd/containerd/fs/diff.go b/vendor/github.com/containerd/containerd/fs/diff.go index 9073d0d9..f2300e84 100644 --- a/vendor/github.com/containerd/containerd/fs/diff.go +++ b/vendor/github.com/containerd/containerd/fs/diff.go @@ -273,7 +273,7 @@ func doubleWalkDiff(ctx context.Context, changeFn ChangeFunc, a, b string) (err if rmdir != "" && strings.HasPrefix(f1.path, rmdir) { f1 = nil continue - } else if rmdir == "" && f1.f.IsDir() { + } else if f1.f.IsDir() { rmdir = f1.path + string(os.PathSeparator) } else if rmdir != "" { rmdir = "" diff --git a/vendor/github.com/containerd/containerd/fs/du_unix.go b/vendor/github.com/containerd/containerd/fs/du_unix.go index fe3426d2..6328e80f 100644 --- a/vendor/github.com/containerd/containerd/fs/du_unix.go +++ b/vendor/github.com/containerd/containerd/fs/du_unix.go @@ -15,15 +15,6 @@ type inode struct { dev, ino uint64 } -func newInode(stat *syscall.Stat_t) inode { - return inode{ - // Dev is uint32 on darwin/bsd, uint64 on linux/solaris - dev: uint64(stat.Dev), // nolint: unconvert - // Ino is uint32 on bsd, uint64 on darwin/linux/solaris - ino: uint64(stat.Ino), // nolint: unconvert - } -} - func diskUsage(roots ...string) (Usage, error) { var ( @@ -37,7 +28,9 @@ func diskUsage(roots ...string) (Usage, error) { return err } - inoKey := newInode(fi.Sys().(*syscall.Stat_t)) + stat := fi.Sys().(*syscall.Stat_t) + + inoKey := inode{dev: uint64(stat.Dev), ino: uint64(stat.Ino)} if _, ok := inodes[inoKey]; !ok { inodes[inoKey] = struct{}{} size += fi.Size() @@ -67,7 +60,9 @@ func diffUsage(ctx context.Context, a, b string) (Usage, error) { } if kind == ChangeKindAdd || kind == ChangeKindModify { - inoKey := newInode(fi.Sys().(*syscall.Stat_t)) + stat := fi.Sys().(*syscall.Stat_t) + + inoKey := inode{dev: uint64(stat.Dev), ino: uint64(stat.Ino)} if _, ok := inodes[inoKey]; !ok { inodes[inoKey] = struct{}{} size += fi.Size() diff --git a/vendor/github.com/containerd/containerd/fs/hardlink_unix.go b/vendor/github.com/containerd/containerd/fs/hardlink_unix.go index a6f99778..3b825c94 100644 --- a/vendor/github.com/containerd/containerd/fs/hardlink_unix.go +++ b/vendor/github.com/containerd/containerd/fs/hardlink_unix.go @@ -13,6 +13,5 @@ func getLinkInfo(fi os.FileInfo) (uint64, bool) { return 0, false } - // Ino is uint32 on bsd, uint64 on darwin/linux/solaris - return uint64(s.Ino), !fi.IsDir() && s.Nlink > 1 // nolint: unconvert + return uint64(s.Ino), !fi.IsDir() && s.Nlink > 1 } diff --git a/vendor/github.com/containerd/containerd/fs/path.go b/vendor/github.com/containerd/containerd/fs/path.go index 13fb8263..412da671 100644 --- a/vendor/github.com/containerd/containerd/fs/path.go +++ b/vendor/github.com/containerd/containerd/fs/path.go @@ -71,9 +71,9 @@ func sameFile(f1, f2 *currentPath) (bool, error) { return false, nil } - // If the timestamp may have been truncated in both of the + // If the timestamp may have been truncated in one of the // files, check content of file to determine difference - if t1.Nanosecond() == 0 && t2.Nanosecond() == 0 { + if t1.Nanosecond() == 0 || t2.Nanosecond() == 0 { var eq bool if (f1.f.Mode() & os.ModeSymlink) == os.ModeSymlink { eq, err = compareSymlinkTarget(f1.fullPath, f2.fullPath) diff --git a/vendor/github.com/containerd/containerd/images/image.go b/vendor/github.com/containerd/containerd/images/image.go index 5fea0dcf..7b4215fa 100644 --- a/vendor/github.com/containerd/containerd/images/image.go +++ b/vendor/github.com/containerd/containerd/images/image.go @@ -3,7 +3,6 @@ package images import ( "context" "encoding/json" - "strings" "time" "github.com/containerd/containerd/content" @@ -358,24 +357,13 @@ func RootFS(ctx context.Context, provider content.Provider, configDesc ocispec.D if err := json.Unmarshal(p, &config); err != nil { return nil, err } - return config.RootFS.DiffIDs, nil -} -// IsCompressedDiff returns true if mediaType is a known compressed diff media type. -// It returns false if the media type is a diff, but not compressed. If the media type -// is not a known diff type, it returns errdefs.ErrNotImplemented -func IsCompressedDiff(ctx context.Context, mediaType string) (bool, error) { - switch mediaType { - case ocispec.MediaTypeImageLayer, MediaTypeDockerSchema2Layer: - case ocispec.MediaTypeImageLayerGzip, MediaTypeDockerSchema2LayerGzip: - return true, nil - default: - // Still apply all generic media types *.tar[.+]gzip and *.tar - if strings.HasSuffix(mediaType, ".tar.gzip") || strings.HasSuffix(mediaType, ".tar+gzip") { - return true, nil - } else if !strings.HasSuffix(mediaType, ".tar") { - return false, errdefs.ErrNotImplemented - } + // TODO(stevvooe): Remove this bit when OCI structure uses correct type for + // rootfs.DiffIDs. + var diffIDs []digest.Digest + for _, diffID := range config.RootFS.DiffIDs { + diffIDs = append(diffIDs, digest.Digest(diffID)) } - return false, nil + + return diffIDs, nil } diff --git a/vendor/github.com/containerd/containerd/log/context.go b/vendor/github.com/containerd/containerd/log/context.go index 471c3527..1081719c 100644 --- a/vendor/github.com/containerd/containerd/log/context.go +++ b/vendor/github.com/containerd/containerd/log/context.go @@ -2,6 +2,7 @@ package log import ( "context" + "path" "github.com/sirupsen/logrus" ) @@ -19,6 +20,7 @@ var ( type ( loggerKey struct{} + moduleKey struct{} ) // WithLogger returns a new context with the provided logger. Use in @@ -38,3 +40,42 @@ func GetLogger(ctx context.Context) *logrus.Entry { return logger.(*logrus.Entry) } + +// WithModule adds the module to the context, appending it with a slash if a +// module already exists. A module is just an roughly correlated defined by the +// call tree for a given context. +// +// As an example, we might have a "node" module already part of a context. If +// this function is called with "tls", the new value of module will be +// "node/tls". +// +// Modules represent the call path. If the new module and last module are the +// same, a new module entry will not be created. If the new module and old +// older module are the same but separated by other modules, the cycle will be +// represented by the module path. +func WithModule(ctx context.Context, module string) context.Context { + parent := GetModulePath(ctx) + + if parent != "" { + // don't re-append module when module is the same. + if path.Base(parent) == module { + return ctx + } + + module = path.Join(parent, module) + } + + ctx = WithLogger(ctx, GetLogger(ctx).WithField("module", module)) + return context.WithValue(ctx, moduleKey{}, module) +} + +// GetModulePath returns the module path for the provided context. If no module +// is set, an empty string is returned. +func GetModulePath(ctx context.Context) string { + module := ctx.Value(moduleKey{}) + if module == nil { + return "" + } + + return module.(string) +} diff --git a/vendor/github.com/containerd/containerd/mount/lookup_unix.go b/vendor/github.com/containerd/containerd/mount/lookup_unix.go index 6e4fd0d2..df9625a9 100644 --- a/vendor/github.com/containerd/containerd/mount/lookup_unix.go +++ b/vendor/github.com/containerd/containerd/mount/lookup_unix.go @@ -3,16 +3,22 @@ package mount import ( + "fmt" "path/filepath" "sort" "strings" + "syscall" "github.com/pkg/errors" ) // Lookup returns the mount info corresponds to the path. func Lookup(dir string) (Info, error) { + var dirStat syscall.Stat_t dir = filepath.Clean(dir) + if err := syscall.Stat(dir, &dirStat); err != nil { + return Info{}, errors.Wrapf(err, "failed to access %q", dir) + } mounts, err := Self() if err != nil { @@ -20,18 +26,21 @@ func Lookup(dir string) (Info, error) { } // Sort descending order by Info.Mountpoint - sort.SliceStable(mounts, func(i, j int) bool { + sort.Slice(mounts, func(i, j int) bool { return mounts[j].Mountpoint < mounts[i].Mountpoint }) for _, m := range mounts { // Note that m.{Major, Minor} are generally unreliable for our purpose here // https://www.spinics.net/lists/linux-btrfs/msg58908.html - // Note that device number is not checked here, because for overlayfs files - // may have different device number with the mountpoint. - if strings.HasPrefix(dir, m.Mountpoint) { + var st syscall.Stat_t + if err := syscall.Stat(m.Mountpoint, &st); err != nil { + // may fail; ignore err + continue + } + if st.Dev == dirStat.Dev && strings.HasPrefix(dir, m.Mountpoint) { return m, nil } } - return Info{}, errors.Errorf("failed to find the mount info for %q", dir) + return Info{}, fmt.Errorf("failed to find the mount info for %q", dir) } diff --git a/vendor/github.com/containerd/containerd/mount/mount.go b/vendor/github.com/containerd/containerd/mount/mount.go index 323e6e2f..94c2c9f9 100644 --- a/vendor/github.com/containerd/containerd/mount/mount.go +++ b/vendor/github.com/containerd/containerd/mount/mount.go @@ -1,14 +1,5 @@ package mount -import ( - "context" - "io/ioutil" - "os" - - "github.com/containerd/containerd/log" - "github.com/pkg/errors" -) - // Mount is the lingua franca of containerd. A mount represents a // serialized mount syscall. Components either emit or consume mounts. type Mount struct { @@ -31,42 +22,3 @@ func All(mounts []Mount, target string) error { } return nil } - -// WithTempMount mounts the provided mounts to a temp dir, and pass the temp dir to f. -// The mounts are valid during the call to the f. -// Finally we will unmount and remove the temp dir regardless of the result of f. -func WithTempMount(ctx context.Context, mounts []Mount, f func(root string) error) (err error) { - root, uerr := ioutil.TempDir("", "containerd-WithTempMount") - if uerr != nil { - return errors.Wrapf(uerr, "failed to create temp dir") - } - // We use Remove here instead of RemoveAll. - // The RemoveAll will delete the temp dir and all children it contains. - // When the Unmount fails, RemoveAll will incorrectly delete data from - // the mounted dir. However, if we use Remove, even though we won't - // successfully delete the temp dir and it may leak, we won't loss data - // from the mounted dir. - // For details, please refer to #1868 #1785. - defer func() { - if uerr = os.Remove(root); uerr != nil { - log.G(ctx).WithError(uerr).WithField("dir", root).Errorf("failed to remove mount temp dir") - } - }() - - // We should do defer first, if not we will not do Unmount when only a part of Mounts are failed. - defer func() { - if uerr = UnmountAll(root, 0); uerr != nil { - uerr = errors.Wrapf(uerr, "failed to unmount %s", root) - if err == nil { - err = uerr - } else { - err = errors.Wrap(err, uerr.Error()) - } - } - }() - if uerr = All(mounts, root); uerr != nil { - return errors.Wrapf(uerr, "failed to mount %s", root) - } - - return errors.Wrapf(f(root), "mount callback failed on %s", root) -} diff --git a/vendor/github.com/containerd/containerd/mount/mount_windows.go b/vendor/github.com/containerd/containerd/mount/mount_windows.go index 6d37fda2..8ad7eab1 100644 --- a/vendor/github.com/containerd/containerd/mount/mount_windows.go +++ b/vendor/github.com/containerd/containerd/mount/mount_windows.go @@ -1,13 +1,6 @@ package mount -import ( - "encoding/json" - "path/filepath" - "strings" - - "github.com/Microsoft/hcsshim" - "github.com/pkg/errors" -) +import "github.com/pkg/errors" var ( // ErrNotImplementOnWindows is returned when an action is not implemented for windows @@ -16,70 +9,15 @@ var ( // Mount to the provided target func (m *Mount) Mount(target string) error { - home, layerID := filepath.Split(m.Source) - - parentLayerPaths, err := m.GetParentPaths() - if err != nil { - return err - } - - var di = hcsshim.DriverInfo{ - HomeDir: home, - } - - if err = hcsshim.ActivateLayer(di, layerID); err != nil { - return errors.Wrapf(err, "failed to activate layer %s", m.Source) - } - defer func() { - if err != nil { - hcsshim.DeactivateLayer(di, layerID) - } - }() - - if err = hcsshim.PrepareLayer(di, layerID, parentLayerPaths); err != nil { - return errors.Wrapf(err, "failed to prepare layer %s", m.Source) - } - return nil -} - -// ParentLayerPathsFlag is the options flag used to represent the JSON encoded -// list of parent layers required to use the layer -const ParentLayerPathsFlag = "parentLayerPaths=" - -// GetParentPaths of the mount -func (m *Mount) GetParentPaths() ([]string, error) { - var parentLayerPaths []string - for _, option := range m.Options { - if strings.HasPrefix(option, ParentLayerPathsFlag) { - err := json.Unmarshal([]byte(option[len(ParentLayerPathsFlag):]), &parentLayerPaths) - if err != nil { - return nil, errors.Wrap(err, "failed to unmarshal parent layer paths from mount") - } - } - } - return parentLayerPaths, nil + return ErrNotImplementOnWindows } // Unmount the mount at the provided path func Unmount(mount string, flags int) error { - var ( - home, layerID = filepath.Split(mount) - di = hcsshim.DriverInfo{ - HomeDir: home, - } - ) - - if err := hcsshim.UnprepareLayer(di, layerID); err != nil { - return errors.Wrapf(err, "failed to unprepare layer %s", mount) - } - if err := hcsshim.DeactivateLayer(di, layerID); err != nil { - return errors.Wrapf(err, "failed to deactivate layer %s", mount) - } - - return nil + return ErrNotImplementOnWindows } -// UnmountAll unmounts from the provided path +// UnmountAll mounts at the provided path func UnmountAll(mount string, flags int) error { - return Unmount(mount, flags) + return ErrNotImplementOnWindows } diff --git a/vendor/github.com/containerd/containerd/oci/spec_opts.go b/vendor/github.com/containerd/containerd/oci/spec_opts.go index 19126b22..c940c7aa 100644 --- a/vendor/github.com/containerd/containerd/oci/spec_opts.go +++ b/vendor/github.com/containerd/containerd/oci/spec_opts.go @@ -2,7 +2,6 @@ package oci import ( "context" - "strings" "github.com/containerd/containerd/containers" specs "github.com/opencontainers/runtime-spec/specs-go" @@ -34,59 +33,3 @@ func WithHostname(name string) SpecOpts { return nil } } - -// WithEnv appends environment variables -func WithEnv(environmnetVariables []string) SpecOpts { - return func(_ context.Context, _ Client, _ *containers.Container, s *specs.Spec) error { - if len(environmnetVariables) > 0 { - s.Process.Env = replaceOrAppendEnvValues(s.Process.Env, environmnetVariables) - } - return nil - } -} - -// WithMounts appends mounts -func WithMounts(mounts []specs.Mount) SpecOpts { - return func(_ context.Context, _ Client, _ *containers.Container, s *specs.Spec) error { - s.Mounts = append(s.Mounts, mounts...) - return nil - } -} - -// replaceOrAppendEnvValues returns the defaults with the overrides either -// replaced by env key or appended to the list -func replaceOrAppendEnvValues(defaults, overrides []string) []string { - cache := make(map[string]int, len(defaults)) - for i, e := range defaults { - parts := strings.SplitN(e, "=", 2) - cache[parts[0]] = i - } - - for _, value := range overrides { - // Values w/o = means they want this env to be removed/unset. - if !strings.Contains(value, "=") { - if i, exists := cache[value]; exists { - defaults[i] = "" // Used to indicate it should be removed - } - continue - } - - // Just do a normal set/update - parts := strings.SplitN(value, "=", 2) - if i, exists := cache[parts[0]]; exists { - defaults[i] = value - } else { - defaults = append(defaults, value) - } - } - - // Now remove all entries that we want to "unset" - for i := 0; i < len(defaults); i++ { - if defaults[i] == "" { - defaults = append(defaults[:i], defaults[i+1:]...) - i-- - } - } - - return defaults -} diff --git a/vendor/github.com/containerd/containerd/oci/spec_opts_unix.go b/vendor/github.com/containerd/containerd/oci/spec_opts_unix.go index 3e6d82c7..23c3fb22 100644 --- a/vendor/github.com/containerd/containerd/oci/spec_opts_unix.go +++ b/vendor/github.com/containerd/containerd/oci/spec_opts_unix.go @@ -6,6 +6,7 @@ import ( "context" "encoding/json" "fmt" + "io/ioutil" "os" "path/filepath" "strconv" @@ -21,7 +22,6 @@ import ( "github.com/opencontainers/runc/libcontainer/user" specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" - "github.com/syndtr/gocapability/capability" ) // WithTTY sets the information on the spec as well as the environment variables for @@ -258,24 +258,7 @@ func WithUIDGID(uid, gid uint32) SpecOpts { // uid, and not returns error. func WithUserID(uid uint32) SpecOpts { return func(ctx context.Context, client Client, c *containers.Container, s *specs.Spec) (err error) { - if c.Snapshotter == "" && c.SnapshotKey == "" { - if !isRootfsAbs(s.Root.Path) { - return errors.Errorf("rootfs absolute path is required") - } - uuid, ugid, err := getUIDGIDFromPath(s.Root.Path, func(u user.User) bool { - return u.Uid == int(uid) - }) - if err != nil { - if os.IsNotExist(err) || err == errNoUsersFound { - s.Process.User.UID, s.Process.User.GID = uid, uid - return nil - } - return err - } - s.Process.User.UID, s.Process.User.GID = uuid, ugid - return nil - - } + // TODO: support non-snapshot rootfs if c.Snapshotter == "" { return errors.Errorf("no snapshotter set for container") } @@ -287,20 +270,49 @@ func WithUserID(uid uint32) SpecOpts { if err != nil { return err } - return mount.WithTempMount(ctx, mounts, func(root string) error { - uuid, ugid, err := getUIDGIDFromPath(root, func(u user.User) bool { - return u.Uid == int(uid) - }) - if err != nil { - if os.IsNotExist(err) || err == errNoUsersFound { - s.Process.User.UID, s.Process.User.GID = uid, uid - return nil - } + root, err := ioutil.TempDir("", "ctd-username") + if err != nil { + return err + } + defer os.Remove(root) + for _, m := range mounts { + if err := m.Mount(root); err != nil { return err } - s.Process.User.UID, s.Process.User.GID = uuid, ugid - return nil + } + defer func() { + if uerr := mount.Unmount(root, 0); uerr != nil { + if err == nil { + err = uerr + } + } + }() + ppath, err := fs.RootPath(root, "/etc/passwd") + if err != nil { + return err + } + f, err := os.Open(ppath) + if err != nil { + if os.IsNotExist(err) { + s.Process.User.UID, s.Process.User.GID = uid, uid + return nil + } + return err + } + defer f.Close() + users, err := user.ParsePasswdFilter(f, func(u user.User) bool { + return u.Uid == int(uid) }) + if err != nil { + return err + } + if len(users) == 0 { + s.Process.User.UID, s.Process.User.GID = uid, uid + return nil + } + u := users[0] + s.Process.User.UID, s.Process.User.GID = uint32(u.Uid), uint32(u.Gid) + return nil } } @@ -309,20 +321,8 @@ func WithUserID(uid uint32) SpecOpts { // does not exist, or the username is not found in /etc/passwd, // it returns error. func WithUsername(username string) SpecOpts { + // TODO: support non-snapshot rootfs return func(ctx context.Context, client Client, c *containers.Container, s *specs.Spec) (err error) { - if c.Snapshotter == "" && c.SnapshotKey == "" { - if !isRootfsAbs(s.Root.Path) { - return errors.Errorf("rootfs absolute path is required") - } - uid, gid, err := getUIDGIDFromPath(s.Root.Path, func(u user.User) bool { - return u.Name == username - }) - if err != nil { - return err - } - s.Process.User.UID, s.Process.User.GID = uid, gid - return nil - } if c.Snapshotter == "" { return errors.Errorf("no snapshotter set for container") } @@ -334,70 +334,43 @@ func WithUsername(username string) SpecOpts { if err != nil { return err } - return mount.WithTempMount(ctx, mounts, func(root string) error { - uid, gid, err := getUIDGIDFromPath(root, func(u user.User) bool { - return u.Name == username - }) - if err != nil { + root, err := ioutil.TempDir("", "ctd-username") + if err != nil { + return err + } + defer os.Remove(root) + for _, m := range mounts { + if err := m.Mount(root); err != nil { return err } - s.Process.User.UID, s.Process.User.GID = uid, gid - return nil + } + defer func() { + if uerr := mount.Unmount(root, 0); uerr != nil { + if err == nil { + err = uerr + } + } + }() + ppath, err := fs.RootPath(root, "/etc/passwd") + if err != nil { + return err + } + f, err := os.Open(ppath) + if err != nil { + return err + } + defer f.Close() + users, err := user.ParsePasswdFilter(f, func(u user.User) bool { + return u.Name == username }) - } -} - -// WithAllCapabilities set all linux capabilities for the process -func WithAllCapabilities(_ context.Context, _ Client, _ *containers.Container, s *specs.Spec) error { - caps := getAllCapabilities() - - s.Process.Capabilities.Bounding = caps - s.Process.Capabilities.Effective = caps - s.Process.Capabilities.Permitted = caps - s.Process.Capabilities.Inheritable = caps - - return nil -} - -func getAllCapabilities() []string { - last := capability.CAP_LAST_CAP - // hack for RHEL6 which has no /proc/sys/kernel/cap_last_cap - if last == capability.Cap(63) { - last = capability.CAP_BLOCK_SUSPEND - } - var caps []string - for _, cap := range capability.List() { - if cap > last { - continue + if err != nil { + return err } - caps = append(caps, "CAP_"+strings.ToUpper(cap.String())) - } - return caps -} - -var errNoUsersFound = errors.New("no users found") - -func getUIDGIDFromPath(root string, filter func(user.User) bool) (uid, gid uint32, err error) { - ppath, err := fs.RootPath(root, "/etc/passwd") - if err != nil { - return 0, 0, err - } - f, err := os.Open(ppath) - if err != nil { - return 0, 0, err - } - defer f.Close() - users, err := user.ParsePasswdFilter(f, filter) - if err != nil { - return 0, 0, err - } - if len(users) == 0 { - return 0, 0, errNoUsersFound + if len(users) == 0 { + return errors.Errorf("no users found for %s", username) + } + u := users[0] + s.Process.User.UID, s.Process.User.GID = uint32(u.Uid), uint32(u.Gid) + return nil } - u := users[0] - return uint32(u.Uid), uint32(u.Gid), nil -} - -func isRootfsAbs(root string) bool { - return filepath.IsAbs(root) } diff --git a/vendor/github.com/containerd/containerd/platforms/cpuinfo.go b/vendor/github.com/containerd/containerd/platforms/cpuinfo.go deleted file mode 100644 index b7c23cc1..00000000 --- a/vendor/github.com/containerd/containerd/platforms/cpuinfo.go +++ /dev/null @@ -1,85 +0,0 @@ -package platforms - -import ( - "bufio" - "os" - "runtime" - "strings" - - "github.com/containerd/containerd/errdefs" - "github.com/containerd/containerd/log" - "github.com/pkg/errors" -) - -// Present the ARM instruction set architecture, eg: v7, v8 -var cpuVariant string - -func init() { - if isArmArch(runtime.GOARCH) { - cpuVariant = getCPUVariant() - } else { - cpuVariant = "" - } -} - -// For Linux, the kernel has already detected the ABI, ISA and Features. -// So we don't need to access the ARM registers to detect platform information -// by ourselves. We can just parse these information from /proc/cpuinfo -func getCPUInfo(pattern string) (info string, err error) { - if !isLinuxOS(runtime.GOOS) { - return "", errors.Wrapf(errdefs.ErrNotImplemented, "getCPUInfo for OS %s", runtime.GOOS) - } - - cpuinfo, err := os.Open("/proc/cpuinfo") - if err != nil { - return "", err - } - defer cpuinfo.Close() - - // Start to Parse the Cpuinfo line by line. For SMP SoC, we parse - // the first core is enough. - scanner := bufio.NewScanner(cpuinfo) - for scanner.Scan() { - newline := scanner.Text() - list := strings.Split(newline, ":") - - if len(list) > 1 && strings.EqualFold(strings.TrimSpace(list[0]), pattern) { - return strings.TrimSpace(list[1]), nil - } - } - - // Check whether the scanner encountered errors - err = scanner.Err() - if err != nil { - return "", err - } - - return "", errors.Wrapf(errdefs.ErrNotFound, "getCPUInfo for pattern: %s", pattern) -} - -func getCPUVariant() string { - variant, err := getCPUInfo("Cpu architecture") - if err != nil { - log.L.WithError(err).Error("failure getting variant") - return "" - } - - switch variant { - case "8": - variant = "v8" - case "7", "7M", "?(12)", "?(13)", "?(14)", "?(15)", "?(16)", "?(17)": - variant = "v7" - case "6", "6TEJ": - variant = "v6" - case "5", "5T", "5TE", "5TEJ": - variant = "v5" - case "4", "4T": - variant = "v4" - case "3": - variant = "v3" - default: - variant = "unknown" - } - - return variant -} diff --git a/vendor/github.com/containerd/containerd/platforms/database.go b/vendor/github.com/containerd/containerd/platforms/database.go index 362b005a..bd66e251 100644 --- a/vendor/github.com/containerd/containerd/platforms/database.go +++ b/vendor/github.com/containerd/containerd/platforms/database.go @@ -5,13 +5,6 @@ import ( "strings" ) -// isLinuxOS returns true if the operating system is Linux. -// -// The OS value should be normalized before calling this function. -func isLinuxOS(os string) bool { - return os == "linux" -} - // These function are generated from from https://golang.org/src/go/build/syslist.go. // // We use switch statements because they are slightly faster than map lookups @@ -28,17 +21,6 @@ func isKnownOS(os string) bool { return false } -// isArmArch returns true if the architecture is ARM. -// -// The arch value should be normalized before being passed to this function. -func isArmArch(arch string) bool { - switch arch { - case "arm", "arm64": - return true - } - return false -} - // isKnownArch returns true if we know about the architecture. // // The arch value should be normalized before being passed to this function. diff --git a/vendor/github.com/containerd/containerd/platforms/defaults.go b/vendor/github.com/containerd/containerd/platforms/defaults.go index ed493ab2..2b57b497 100644 --- a/vendor/github.com/containerd/containerd/platforms/defaults.go +++ b/vendor/github.com/containerd/containerd/platforms/defaults.go @@ -16,7 +16,6 @@ func DefaultSpec() specs.Platform { return specs.Platform{ OS: runtime.GOOS, Architecture: runtime.GOARCH, - // The Variant field will be empty if arch != ARM. - Variant: cpuVariant, + // TODO(stevvooe): Need to resolve GOARM for arm hosts. } } diff --git a/vendor/github.com/containerd/containerd/plugin/context.go b/vendor/github.com/containerd/containerd/plugin/context.go index eca4a020..87e53b84 100644 --- a/vendor/github.com/containerd/containerd/plugin/context.go +++ b/vendor/github.com/containerd/containerd/plugin/context.go @@ -6,6 +6,7 @@ import ( "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/events/exchange" + "github.com/containerd/containerd/log" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" ) @@ -27,7 +28,7 @@ type InitContext struct { // NewContext returns a new plugin InitContext func NewContext(ctx context.Context, r *Registration, plugins *Set, root, state string) *InitContext { return &InitContext{ - Context: ctx, + Context: log.WithModule(ctx, r.URI()), Root: filepath.Join(root, r.URI()), State: filepath.Join(state, r.URI()), Meta: &Meta{ diff --git a/vendor/github.com/containerd/containerd/process.go b/vendor/github.com/containerd/containerd/process.go index 32049cf0..ad1a2a1f 100644 --- a/vendor/github.com/containerd/containerd/process.go +++ b/vendor/github.com/containerd/containerd/process.go @@ -191,7 +191,6 @@ func (p *process) Delete(ctx context.Context, opts ...ProcessDeleteOpts) (*ExitS return nil, errdefs.FromGRPC(err) } if p.io != nil { - p.io.Cancel() p.io.Wait() p.io.Close() } diff --git a/vendor/github.com/containerd/containerd/remotes/docker/resolver.go b/vendor/github.com/containerd/containerd/remotes/docker/resolver.go index edc99415..57a18b66 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/resolver.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/resolver.go @@ -136,9 +136,6 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp log.G(ctx).Debug("resolving") resp, err := fetcher.doRequestWithRetries(ctx, req, nil) if err != nil { - if errors.Cause(err) == ErrInvalidAuthorization { - err = errors.Wrapf(err, "pull access denied, repository does not exist or may require authorization") - } return "", ocispec.Descriptor{}, err } resp.Body.Close() // don't care about body contents. diff --git a/vendor/github.com/containerd/containerd/remotes/handlers.go b/vendor/github.com/containerd/containerd/remotes/handlers.go index a37af65e..ad4cd9f3 100644 --- a/vendor/github.com/containerd/containerd/remotes/handlers.go +++ b/vendor/github.com/containerd/containerd/remotes/handlers.go @@ -6,15 +6,12 @@ import ( "fmt" "io" "math/rand" - "strings" - "sync" "time" "github.com/containerd/containerd/content" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" "github.com/containerd/containerd/log" - "github.com/containerd/containerd/platforms" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -183,7 +180,7 @@ func commitOpts(desc ocispec.Descriptor, r io.Reader) (io.Reader, []content.Opt) // PushHandler returns a handler that will push all content from the provider // using a writer from the pusher. -func PushHandler(pusher Pusher, provider content.Provider) images.HandlerFunc { +func PushHandler(provider content.Provider, pusher Pusher) images.HandlerFunc { return func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { ctx = log.WithLogger(ctx, log.G(ctx).WithFields(logrus.Fields{ "digest": desc.Digest, @@ -218,55 +215,3 @@ func push(ctx context.Context, provider content.Provider, pusher Pusher, desc oc rd := io.NewSectionReader(ra, 0, desc.Size) return content.Copy(ctx, cw, rd, desc.Size, desc.Digest) } - -// PushContent pushes content specified by the descriptor from the provider. -// -// Base handlers can be provided which will be called before any push specific -// handlers. -func PushContent(ctx context.Context, pusher Pusher, desc ocispec.Descriptor, provider content.Provider, baseHandlers ...images.Handler) error { - var m sync.Mutex - manifestStack := []ocispec.Descriptor{} - - filterHandler := images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { - switch desc.MediaType { - case images.MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest, - images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex: - m.Lock() - manifestStack = append(manifestStack, desc) - m.Unlock() - return nil, images.ErrStopHandler - default: - return nil, nil - } - }) - - pushHandler := PushHandler(pusher, provider) - - handlers := append(baseHandlers, - images.ChildrenHandler(provider, platforms.Default()), - filterHandler, - pushHandler, - ) - - if err := images.Dispatch(ctx, images.Handlers(handlers...), desc); err != nil { - return err - } - - // Iterate in reverse order as seen, parent always uploaded after child - for i := len(manifestStack) - 1; i >= 0; i-- { - _, err := pushHandler(ctx, manifestStack[i]) - if err != nil { - // TODO(estesp): until we have a more complete method for index push, we need to report - // missing dependencies in an index/manifest list by sensing the "400 Bad Request" - // as a marker for this problem - if (manifestStack[i].MediaType == ocispec.MediaTypeImageIndex || - manifestStack[i].MediaType == images.MediaTypeDockerSchema2ManifestList) && - errors.Cause(err) != nil && strings.Contains(errors.Cause(err).Error(), "400 Bad Request") { - return errors.Wrap(err, "manifest list/index references to blobs and/or manifests are missing in your target registry") - } - return err - } - } - - return nil -} diff --git a/vendor/github.com/containerd/containerd/remotes/hints.go b/vendor/github.com/containerd/containerd/remotes/hints.go new file mode 100644 index 00000000..1694477a --- /dev/null +++ b/vendor/github.com/containerd/containerd/remotes/hints.go @@ -0,0 +1,31 @@ +package remotes + +import "strings" + +// HintExists returns true if a hint of the provided kind and values exists in +// the set of provided hints. +func HintExists(kind, value string, hints ...string) bool { + for _, hint := range hints { + if strings.HasPrefix(hint, kind) && strings.HasSuffix(hint, value) { + return true + } + } + + return false +} + +// HintValues returns a slice of the values of the hints that match kind. +func HintValues(kind string, hints ...string) []string { + var values []string + for _, hint := range hints { + if strings.HasPrefix(hint, kind) { + parts := strings.SplitN(hint, ":", 2) + if len(parts) < 2 { + continue + } + values = append(values, parts[1]) + } + } + + return values +} diff --git a/vendor/github.com/containerd/containerd/sys/filesys_unix.go b/vendor/github.com/containerd/containerd/sys/filesys_unix.go deleted file mode 100644 index ed23609c..00000000 --- a/vendor/github.com/containerd/containerd/sys/filesys_unix.go +++ /dev/null @@ -1,10 +0,0 @@ -// +build !windows - -package sys - -import "os" - -// ForceRemoveAll on unix is just a wrapper for os.RemoveAll -func ForceRemoveAll(path string) error { - return os.RemoveAll(path) -} diff --git a/vendor/github.com/containerd/containerd/sys/filesys_windows.go b/vendor/github.com/containerd/containerd/sys/filesys_windows.go index 36395c55..b5ce1357 100644 --- a/vendor/github.com/containerd/containerd/sys/filesys_windows.go +++ b/vendor/github.com/containerd/containerd/sys/filesys_windows.go @@ -11,7 +11,6 @@ import ( "unsafe" winio "github.com/Microsoft/go-winio" - "github.com/Microsoft/hcsshim" ) // MkdirAllWithACL is a wrapper for MkdirAll that creates a directory @@ -235,13 +234,3 @@ func syscallOpenSequential(path string, mode int, _ uint32) (fd syscall.Handle, h, e := syscall.CreateFile(pathp, access, sharemode, sa, createmode, fileFlagSequentialScan, 0) return h, e } - -// ForceRemoveAll is the same as os.RemoveAll, but uses hcsshim.DestroyLayer in order -// to delete container layers. -func ForceRemoveAll(path string) error { - info := hcsshim.DriverInfo{ - HomeDir: filepath.Dir(path), - } - - return hcsshim.DestroyLayer(info, filepath.Base(path)) -} diff --git a/vendor/github.com/containerd/containerd/sys/prctl.go b/vendor/github.com/containerd/containerd/sys/prctl.go new file mode 100644 index 00000000..aa1a4ad3 --- /dev/null +++ b/vendor/github.com/containerd/containerd/sys/prctl.go @@ -0,0 +1,41 @@ +// +build linux + +// Package sys provides access to the Get Child and Set Child prctl flags. +// See http://man7.org/linux/man-pages/man2/prctl.2.html +package sys + +import ( + "unsafe" + + "golang.org/x/sys/unix" +) + +// GetSubreaper returns the subreaper setting for the calling process +func GetSubreaper() (int, error) { + var i uintptr + // PR_GET_CHILD_SUBREAPER allows retrieving the current child + // subreaper. + // Returns the "child subreaper" setting of the caller, in the + // location pointed to by (int *) arg2. + if err := unix.Prctl(unix.PR_GET_CHILD_SUBREAPER, uintptr(unsafe.Pointer(&i)), 0, 0, 0); err != nil { + return -1, err + } + return int(i), nil +} + +// SetSubreaper sets the value i as the subreaper setting for the calling process +func SetSubreaper(i int) error { + // PR_SET_CHILD_SUBREAPER allows setting the child subreaper. + // 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. + return unix.Prctl(unix.PR_SET_CHILD_SUBREAPER, uintptr(i), 0, 0, 0) +} diff --git a/vendor/github.com/containerd/containerd/sys/stat_bsd.go b/vendor/github.com/containerd/containerd/sys/stat_bsd.go index 84c59ab6..e043ae52 100644 --- a/vendor/github.com/containerd/containerd/sys/stat_bsd.go +++ b/vendor/github.com/containerd/containerd/sys/stat_bsd.go @@ -4,7 +4,6 @@ package sys import ( "syscall" - "time" ) // StatAtime returns the access time from a stat struct @@ -21,8 +20,3 @@ func StatCtime(st *syscall.Stat_t) syscall.Timespec { func StatMtime(st *syscall.Stat_t) syscall.Timespec { return st.Mtimespec } - -// StatATimeAsTime returns the access time as a time.Time -func StatATimeAsTime(st *syscall.Stat_t) time.Time { - return time.Unix(int64(st.Atimespec.Sec), int64(st.Atimespec.Nsec)) // nolint: unconvert -} diff --git a/vendor/github.com/containerd/containerd/sys/stat_unix.go b/vendor/github.com/containerd/containerd/sys/stat_unix.go index 799b9b99..1f983a98 100644 --- a/vendor/github.com/containerd/containerd/sys/stat_unix.go +++ b/vendor/github.com/containerd/containerd/sys/stat_unix.go @@ -4,7 +4,6 @@ package sys import ( "syscall" - "time" ) // StatAtime returns the Atim @@ -21,8 +20,3 @@ func StatCtime(st *syscall.Stat_t) syscall.Timespec { func StatMtime(st *syscall.Stat_t) syscall.Timespec { return st.Mtim } - -// StatATimeAsTime returns st.Atim as a time.Time -func StatATimeAsTime(st *syscall.Stat_t) time.Time { - return time.Unix(st.Atim.Sec, st.Atim.Nsec) -} diff --git a/vendor/github.com/containerd/containerd/task.go b/vendor/github.com/containerd/containerd/task.go index 121da9af..8d256834 100644 --- a/vendor/github.com/containerd/containerd/task.go +++ b/vendor/github.com/containerd/containerd/task.go @@ -123,7 +123,7 @@ type Task interface { // Resume the execution of the task Resume(context.Context) error // Exec creates a new process inside the task - Exec(context.Context, string, *specs.Process, cio.Creator) (Process, error) + Exec(context.Context, string, *specs.Process, cio.Creation) (Process, error) // Pids returns a list of system specific process ids inside the task Pids(context.Context) ([]ProcessInfo, error) // Checkpoint serializes the runtime and memory information of a task into an @@ -163,7 +163,6 @@ func (t *task) Start(ctx context.Context) error { ContainerID: t.id, }) if err != nil { - t.io.Cancel() t.io.Close() return errdefs.FromGRPC(err) } @@ -278,7 +277,7 @@ func (t *task) Delete(ctx context.Context, opts ...ProcessDeleteOpts) (*ExitStat return &ExitStatus{code: r.ExitStatus, exitedAt: r.ExitedAt}, nil } -func (t *task) Exec(ctx context.Context, id string, spec *specs.Process, ioCreate cio.Creator) (_ Process, err error) { +func (t *task) Exec(ctx context.Context, id string, spec *specs.Process, ioCreate cio.Creation) (_ Process, err error) { if id == "" { return nil, errors.Wrapf(errdefs.ErrInvalidArgument, "exec id must not be empty") } diff --git a/vendor/github.com/containerd/containerd/vendor.conf b/vendor/github.com/containerd/containerd/vendor.conf index 67910bdc..0514e3d1 100644 --- a/vendor/github.com/containerd/containerd/vendor.conf +++ b/vendor/github.com/containerd/containerd/vendor.conf @@ -3,19 +3,19 @@ github.com/containerd/go-runc 4f6e87ae043f859a38255247b49c9abc262d002f github.com/containerd/console 84eeaae905fa414d03e07bcd6c8d3f19e7cf180e github.com/containerd/cgroups c0710c92e8b3a44681d1321dcfd1360fc5c6c089 github.com/containerd/typeurl f6943554a7e7e88b3c14aad190bf05932da84788 -github.com/docker/go-metrics 4ea375f7759c82740c893fc030bc37088d2ec098 +github.com/docker/go-metrics 8fd5772bf1584597834c6f7961a530f06cbfbb87 github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9 github.com/godbus/dbus c7fdd8b5cd55e87b4e1f4e372cdb1db61dd6c66f -github.com/prometheus/client_golang f4fb1b73fb099f396a7f0036bf86aa8def4ed823 -github.com/prometheus/client_model 99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c -github.com/prometheus/common 89604d197083d4781071d3c65855d24ecfb0a563 -github.com/prometheus/procfs cb4147076ac75738c9a7d279075a253c0cc5acbd +github.com/prometheus/client_golang v0.8.0 +github.com/prometheus/client_model fa8ad6fec33561be4280a8f0514318c79d7f6cb6 +github.com/prometheus/common 195bde7883f7c39ea62b0d92ab7359b5327065cb +github.com/prometheus/procfs fcdb11ccb4389efb1b210b7ffb623ab71c5fdd60 github.com/beorn7/perks 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9 github.com/matttproud/golang_protobuf_extensions v1.0.0 github.com/docker/go-units v0.3.1 github.com/gogo/protobuf v0.5 github.com/golang/protobuf 1643683e1b54a9e88ad26d98f81400c8c9d9f4f9 -github.com/opencontainers/runtime-spec v1.0.1 +github.com/opencontainers/runtime-spec v1.0.0 github.com/opencontainers/runc 9f9c96235cc97674e935002fc3d78361b696a69e github.com/sirupsen/logrus v1.0.0 github.com/containerd/btrfs cc52c4dea2ce11a44e6639e561bb5c2af9ada9e3 @@ -25,20 +25,19 @@ github.com/pmezard/go-difflib v1.0.0 github.com/containerd/fifo fbfb6a11ec671efbe94ad1c12c2e98773f19e1e6 github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c golang.org/x/net 7dcfb8076726a3fdd9353b6b8a1f1b6be6811bd6 -google.golang.org/grpc v1.7.4 +google.golang.org/grpc v1.7.2 github.com/pkg/errors v0.8.0 github.com/opencontainers/go-digest 21dfd564fd89c944783d00d069f33e3e7123c448 golang.org/x/sys 314a259e304ff91bd6985da2a7149bbf91237993 https://github.com/golang/sys -github.com/opencontainers/image-spec v1.0.1 +github.com/opencontainers/image-spec v1.0.0 github.com/containerd/continuity cf279e6ac893682272b4479d4c67fd3abf878b4e golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895 github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0 -github.com/Microsoft/go-winio v0.4.5 +github.com/Microsoft/go-winio v0.4.4 github.com/Microsoft/hcsshim v0.6.7 github.com/boltdb/bolt e9cf4fae01b5a8ff89d0ec6b32f0d9c9f79aefdd google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944 golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4 github.com/dmcgowan/go-tar go1.10 -github.com/stevvooe/ttrpc d2710463e497617f16f26d1e715a3308609e7982 -github.com/syndtr/gocapability db04d3cc01c8b54962a58ec7e491717d06cfcc16 +github.com/stevvooe/ttrpc d4528379866b0ce7e9d71f3eb96f0582fc374577 diff --git a/vendor/github.com/syndtr/gocapability/LICENSE b/vendor/github.com/syndtr/gocapability/LICENSE deleted file mode 100644 index 80dd96de..00000000 --- a/vendor/github.com/syndtr/gocapability/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -Copyright 2013 Suryandaru Triandana -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/syndtr/gocapability/capability/capability.go b/vendor/github.com/syndtr/gocapability/capability/capability.go deleted file mode 100644 index c07c5579..00000000 --- a/vendor/github.com/syndtr/gocapability/capability/capability.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2013, Suryandaru Triandana -// All rights reserved. -// -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Package capability provides utilities for manipulating POSIX capabilities. -package capability - -type Capabilities interface { - // Get check whether a capability present in the given - // capabilities set. The 'which' value should be one of EFFECTIVE, - // PERMITTED, INHERITABLE, BOUNDING or AMBIENT. - Get(which CapType, what Cap) bool - - // Empty check whether all capability bits of the given capabilities - // set are zero. The 'which' value should be one of EFFECTIVE, - // PERMITTED, INHERITABLE, BOUNDING or AMBIENT. - Empty(which CapType) bool - - // Full check whether all capability bits of the given capabilities - // set are one. The 'which' value should be one of EFFECTIVE, - // PERMITTED, INHERITABLE, BOUNDING or AMBIENT. - Full(which CapType) bool - - // Set sets capabilities of the given capabilities sets. The - // 'which' value should be one or combination (OR'ed) of EFFECTIVE, - // PERMITTED, INHERITABLE, BOUNDING or AMBIENT. - Set(which CapType, caps ...Cap) - - // Unset unsets capabilities of the given capabilities sets. The - // 'which' value should be one or combination (OR'ed) of EFFECTIVE, - // PERMITTED, INHERITABLE, BOUNDING or AMBIENT. - Unset(which CapType, caps ...Cap) - - // Fill sets all bits of the given capabilities kind to one. The - // 'kind' value should be one or combination (OR'ed) of CAPS, - // BOUNDS or AMBS. - Fill(kind CapType) - - // Clear sets all bits of the given capabilities kind to zero. The - // 'kind' value should be one or combination (OR'ed) of CAPS, - // BOUNDS or AMBS. - Clear(kind CapType) - - // String return current capabilities state of the given capabilities - // set as string. The 'which' value should be one of EFFECTIVE, - // PERMITTED, INHERITABLE BOUNDING or AMBIENT - StringCap(which CapType) string - - // String return current capabilities state as string. - String() string - - // Load load actual capabilities value. This will overwrite all - // outstanding changes. - Load() error - - // Apply apply the capabilities settings, so all changes will take - // effect. - Apply(kind CapType) error -} - -// NewPid create new initialized Capabilities object for given pid when it -// is nonzero, or for the current pid if pid is 0 -func NewPid(pid int) (Capabilities, error) { - return newPid(pid) -} - -// NewFile create new initialized Capabilities object for given named file. -func NewFile(name string) (Capabilities, error) { - return newFile(name) -} diff --git a/vendor/github.com/syndtr/gocapability/capability/capability_linux.go b/vendor/github.com/syndtr/gocapability/capability/capability_linux.go deleted file mode 100644 index 205e0f70..00000000 --- a/vendor/github.com/syndtr/gocapability/capability/capability_linux.go +++ /dev/null @@ -1,650 +0,0 @@ -// Copyright (c) 2013, Suryandaru Triandana -// All rights reserved. -// -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package capability - -import ( - "bufio" - "errors" - "fmt" - "io" - "os" - "strings" - "syscall" -) - -var errUnknownVers = errors.New("unknown capability version") - -const ( - linuxCapVer1 = 0x19980330 - linuxCapVer2 = 0x20071026 - linuxCapVer3 = 0x20080522 -) - -var ( - capVers uint32 - capLastCap Cap -) - -func init() { - var hdr capHeader - capget(&hdr, nil) - capVers = hdr.version - - if initLastCap() == nil { - CAP_LAST_CAP = capLastCap - if capLastCap > 31 { - capUpperMask = (uint32(1) << (uint(capLastCap) - 31)) - 1 - } else { - capUpperMask = 0 - } - } -} - -func initLastCap() error { - if capLastCap != 0 { - return nil - } - - f, err := os.Open("/proc/sys/kernel/cap_last_cap") - if err != nil { - return err - } - defer f.Close() - - var b []byte = make([]byte, 11) - _, err = f.Read(b) - if err != nil { - return err - } - - fmt.Sscanf(string(b), "%d", &capLastCap) - - return nil -} - -func mkStringCap(c Capabilities, which CapType) (ret string) { - for i, first := Cap(0), true; i <= CAP_LAST_CAP; i++ { - if !c.Get(which, i) { - continue - } - if first { - first = false - } else { - ret += ", " - } - ret += i.String() - } - return -} - -func mkString(c Capabilities, max CapType) (ret string) { - ret = "{" - for i := CapType(1); i <= max; i <<= 1 { - ret += " " + i.String() + "=\"" - if c.Empty(i) { - ret += "empty" - } else if c.Full(i) { - ret += "full" - } else { - ret += c.StringCap(i) - } - ret += "\"" - } - ret += " }" - return -} - -func newPid(pid int) (c Capabilities, err error) { - switch capVers { - case linuxCapVer1: - p := new(capsV1) - p.hdr.version = capVers - p.hdr.pid = pid - c = p - case linuxCapVer2, linuxCapVer3: - p := new(capsV3) - p.hdr.version = capVers - p.hdr.pid = pid - c = p - default: - err = errUnknownVers - return - } - err = c.Load() - if err != nil { - c = nil - } - return -} - -type capsV1 struct { - hdr capHeader - data capData -} - -func (c *capsV1) Get(which CapType, what Cap) bool { - if what > 32 { - return false - } - - switch which { - case EFFECTIVE: - return (1< 32 { - continue - } - - if which&EFFECTIVE != 0 { - c.data.effective |= 1 << uint(what) - } - if which&PERMITTED != 0 { - c.data.permitted |= 1 << uint(what) - } - if which&INHERITABLE != 0 { - c.data.inheritable |= 1 << uint(what) - } - } -} - -func (c *capsV1) Unset(which CapType, caps ...Cap) { - for _, what := range caps { - if what > 32 { - continue - } - - if which&EFFECTIVE != 0 { - c.data.effective &= ^(1 << uint(what)) - } - if which&PERMITTED != 0 { - c.data.permitted &= ^(1 << uint(what)) - } - if which&INHERITABLE != 0 { - c.data.inheritable &= ^(1 << uint(what)) - } - } -} - -func (c *capsV1) Fill(kind CapType) { - if kind&CAPS == CAPS { - c.data.effective = 0x7fffffff - c.data.permitted = 0x7fffffff - c.data.inheritable = 0 - } -} - -func (c *capsV1) Clear(kind CapType) { - if kind&CAPS == CAPS { - c.data.effective = 0 - c.data.permitted = 0 - c.data.inheritable = 0 - } -} - -func (c *capsV1) StringCap(which CapType) (ret string) { - return mkStringCap(c, which) -} - -func (c *capsV1) String() (ret string) { - return mkString(c, BOUNDING) -} - -func (c *capsV1) Load() (err error) { - return capget(&c.hdr, &c.data) -} - -func (c *capsV1) Apply(kind CapType) error { - if kind&CAPS == CAPS { - return capset(&c.hdr, &c.data) - } - return nil -} - -type capsV3 struct { - hdr capHeader - data [2]capData - bounds [2]uint32 - ambient [2]uint32 -} - -func (c *capsV3) Get(which CapType, what Cap) bool { - var i uint - if what > 31 { - i = uint(what) >> 5 - what %= 32 - } - - switch which { - case EFFECTIVE: - return (1< 31 { - i = uint(what) >> 5 - what %= 32 - } - - if which&EFFECTIVE != 0 { - c.data[i].effective |= 1 << uint(what) - } - if which&PERMITTED != 0 { - c.data[i].permitted |= 1 << uint(what) - } - if which&INHERITABLE != 0 { - c.data[i].inheritable |= 1 << uint(what) - } - if which&BOUNDING != 0 { - c.bounds[i] |= 1 << uint(what) - } - if which&AMBIENT != 0 { - c.ambient[i] |= 1 << uint(what) - } - } -} - -func (c *capsV3) Unset(which CapType, caps ...Cap) { - for _, what := range caps { - var i uint - if what > 31 { - i = uint(what) >> 5 - what %= 32 - } - - if which&EFFECTIVE != 0 { - c.data[i].effective &= ^(1 << uint(what)) - } - if which&PERMITTED != 0 { - c.data[i].permitted &= ^(1 << uint(what)) - } - if which&INHERITABLE != 0 { - c.data[i].inheritable &= ^(1 << uint(what)) - } - if which&BOUNDING != 0 { - c.bounds[i] &= ^(1 << uint(what)) - } - if which&AMBIENT != 0 { - c.ambient[i] &= ^(1 << uint(what)) - } - } -} - -func (c *capsV3) Fill(kind CapType) { - if kind&CAPS == CAPS { - c.data[0].effective = 0xffffffff - c.data[0].permitted = 0xffffffff - c.data[0].inheritable = 0 - c.data[1].effective = 0xffffffff - c.data[1].permitted = 0xffffffff - c.data[1].inheritable = 0 - } - - if kind&BOUNDS == BOUNDS { - c.bounds[0] = 0xffffffff - c.bounds[1] = 0xffffffff - } - if kind&AMBS == AMBS { - c.ambient[0] = 0xffffffff - c.ambient[1] = 0xffffffff - } -} - -func (c *capsV3) Clear(kind CapType) { - if kind&CAPS == CAPS { - c.data[0].effective = 0 - c.data[0].permitted = 0 - c.data[0].inheritable = 0 - c.data[1].effective = 0 - c.data[1].permitted = 0 - c.data[1].inheritable = 0 - } - - if kind&BOUNDS == BOUNDS { - c.bounds[0] = 0 - c.bounds[1] = 0 - } - if kind&AMBS == AMBS { - c.ambient[0] = 0 - c.ambient[1] = 0 - } -} - -func (c *capsV3) StringCap(which CapType) (ret string) { - return mkStringCap(c, which) -} - -func (c *capsV3) String() (ret string) { - return mkString(c, BOUNDING) -} - -func (c *capsV3) Load() (err error) { - err = capget(&c.hdr, &c.data[0]) - if err != nil { - return - } - - var status_path string - - if c.hdr.pid == 0 { - status_path = fmt.Sprintf("/proc/self/status") - } else { - status_path = fmt.Sprintf("/proc/%d/status", c.hdr.pid) - } - - f, err := os.Open(status_path) - if err != nil { - return - } - b := bufio.NewReader(f) - for { - line, e := b.ReadString('\n') - if e != nil { - if e != io.EOF { - err = e - } - break - } - if strings.HasPrefix(line, "CapB") { - fmt.Sscanf(line[4:], "nd: %08x%08x", &c.bounds[1], &c.bounds[0]) - continue - } - if strings.HasPrefix(line, "CapA") { - fmt.Sscanf(line[4:], "mb: %08x%08x", &c.ambient[1], &c.ambient[0]) - continue - } - } - f.Close() - - return -} - -func (c *capsV3) Apply(kind CapType) (err error) { - if kind&BOUNDS == BOUNDS { - var data [2]capData - err = capget(&c.hdr, &data[0]) - if err != nil { - return - } - if (1< 31 { - if c.data.version == 1 { - return false - } - i = uint(what) >> 5 - what %= 32 - } - - switch which { - case EFFECTIVE: - return (1< 31 { - if c.data.version == 1 { - continue - } - i = uint(what) >> 5 - what %= 32 - } - - if which&EFFECTIVE != 0 { - c.data.effective[i] |= 1 << uint(what) - } - if which&PERMITTED != 0 { - c.data.data[i].permitted |= 1 << uint(what) - } - if which&INHERITABLE != 0 { - c.data.data[i].inheritable |= 1 << uint(what) - } - } -} - -func (c *capsFile) Unset(which CapType, caps ...Cap) { - for _, what := range caps { - var i uint - if what > 31 { - if c.data.version == 1 { - continue - } - i = uint(what) >> 5 - what %= 32 - } - - if which&EFFECTIVE != 0 { - c.data.effective[i] &= ^(1 << uint(what)) - } - if which&PERMITTED != 0 { - c.data.data[i].permitted &= ^(1 << uint(what)) - } - if which&INHERITABLE != 0 { - c.data.data[i].inheritable &= ^(1 << uint(what)) - } - } -} - -func (c *capsFile) Fill(kind CapType) { - if kind&CAPS == CAPS { - c.data.effective[0] = 0xffffffff - c.data.data[0].permitted = 0xffffffff - c.data.data[0].inheritable = 0 - if c.data.version == 2 { - c.data.effective[1] = 0xffffffff - c.data.data[1].permitted = 0xffffffff - c.data.data[1].inheritable = 0 - } - } -} - -func (c *capsFile) Clear(kind CapType) { - if kind&CAPS == CAPS { - c.data.effective[0] = 0 - c.data.data[0].permitted = 0 - c.data.data[0].inheritable = 0 - if c.data.version == 2 { - c.data.effective[1] = 0 - c.data.data[1].permitted = 0 - c.data.data[1].inheritable = 0 - } - } -} - -func (c *capsFile) StringCap(which CapType) (ret string) { - return mkStringCap(c, which) -} - -func (c *capsFile) String() (ret string) { - return mkString(c, INHERITABLE) -} - -func (c *capsFile) Load() (err error) { - return getVfsCap(c.path, &c.data) -} - -func (c *capsFile) Apply(kind CapType) (err error) { - if kind&CAPS == CAPS { - return setVfsCap(c.path, &c.data) - } - return -} diff --git a/vendor/github.com/syndtr/gocapability/capability/capability_noop.go b/vendor/github.com/syndtr/gocapability/capability/capability_noop.go deleted file mode 100644 index 9bb3070c..00000000 --- a/vendor/github.com/syndtr/gocapability/capability/capability_noop.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2013, Suryandaru Triandana -// All rights reserved. -// -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// +build !linux - -package capability - -import "errors" - -func newPid(pid int) (Capabilities, error) { - return nil, errors.New("not supported") -} - -func newFile(path string) (Capabilities, error) { - return nil, errors.New("not supported") -} diff --git a/vendor/github.com/syndtr/gocapability/capability/enum.go b/vendor/github.com/syndtr/gocapability/capability/enum.go deleted file mode 100644 index 69381731..00000000 --- a/vendor/github.com/syndtr/gocapability/capability/enum.go +++ /dev/null @@ -1,268 +0,0 @@ -// Copyright (c) 2013, Suryandaru Triandana -// All rights reserved. -// -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package capability - -type CapType uint - -func (c CapType) String() string { - switch c { - case EFFECTIVE: - return "effective" - case PERMITTED: - return "permitted" - case INHERITABLE: - return "inheritable" - case BOUNDING: - return "bounding" - case CAPS: - return "caps" - case AMBIENT: - return "ambient" - } - return "unknown" -} - -const ( - EFFECTIVE CapType = 1 << iota - PERMITTED - INHERITABLE - BOUNDING - AMBIENT - - CAPS = EFFECTIVE | PERMITTED | INHERITABLE - BOUNDS = BOUNDING - AMBS = AMBIENT -) - -//go:generate go run enumgen/gen.go -type Cap int - -// POSIX-draft defined capabilities. -const ( - // In a system with the [_POSIX_CHOWN_RESTRICTED] option defined, this - // overrides the restriction of changing file ownership and group - // ownership. - CAP_CHOWN = Cap(0) - - // Override all DAC access, including ACL execute access if - // [_POSIX_ACL] is defined. Excluding DAC access covered by - // CAP_LINUX_IMMUTABLE. - CAP_DAC_OVERRIDE = Cap(1) - - // Overrides all DAC restrictions regarding read and search on files - // and directories, including ACL restrictions if [_POSIX_ACL] is - // defined. Excluding DAC access covered by CAP_LINUX_IMMUTABLE. - CAP_DAC_READ_SEARCH = Cap(2) - - // Overrides all restrictions about allowed operations on files, where - // file owner ID must be equal to the user ID, except where CAP_FSETID - // is applicable. It doesn't override MAC and DAC restrictions. - CAP_FOWNER = Cap(3) - - // Overrides the following restrictions that the effective user ID - // shall match the file owner ID when setting the S_ISUID and S_ISGID - // bits on that file; that the effective group ID (or one of the - // supplementary group IDs) shall match the file owner ID when setting - // the S_ISGID bit on that file; that the S_ISUID and S_ISGID bits are - // cleared on successful return from chown(2) (not implemented). - CAP_FSETID = Cap(4) - - // Overrides the restriction that the real or effective user ID of a - // process sending a signal must match the real or effective user ID - // of the process receiving the signal. - CAP_KILL = Cap(5) - - // Allows setgid(2) manipulation - // Allows setgroups(2) - // Allows forged gids on socket credentials passing. - CAP_SETGID = Cap(6) - - // Allows set*uid(2) manipulation (including fsuid). - // Allows forged pids on socket credentials passing. - CAP_SETUID = Cap(7) - - // Linux-specific capabilities - - // Without VFS support for capabilities: - // Transfer any capability in your permitted set to any pid, - // remove any capability in your permitted set from any pid - // With VFS support for capabilities (neither of above, but) - // Add any capability from current's capability bounding set - // to the current process' inheritable set - // Allow taking bits out of capability bounding set - // Allow modification of the securebits for a process - CAP_SETPCAP = Cap(8) - - // Allow modification of S_IMMUTABLE and S_APPEND file attributes - CAP_LINUX_IMMUTABLE = Cap(9) - - // Allows binding to TCP/UDP sockets below 1024 - // Allows binding to ATM VCIs below 32 - CAP_NET_BIND_SERVICE = Cap(10) - - // Allow broadcasting, listen to multicast - CAP_NET_BROADCAST = Cap(11) - - // Allow interface configuration - // Allow administration of IP firewall, masquerading and accounting - // Allow setting debug option on sockets - // Allow modification of routing tables - // Allow setting arbitrary process / process group ownership on - // sockets - // Allow binding to any address for transparent proxying (also via NET_RAW) - // Allow setting TOS (type of service) - // Allow setting promiscuous mode - // Allow clearing driver statistics - // Allow multicasting - // Allow read/write of device-specific registers - // Allow activation of ATM control sockets - CAP_NET_ADMIN = Cap(12) - - // Allow use of RAW sockets - // Allow use of PACKET sockets - // Allow binding to any address for transparent proxying (also via NET_ADMIN) - CAP_NET_RAW = Cap(13) - - // Allow locking of shared memory segments - // Allow mlock and mlockall (which doesn't really have anything to do - // with IPC) - CAP_IPC_LOCK = Cap(14) - - // Override IPC ownership checks - CAP_IPC_OWNER = Cap(15) - - // Insert and remove kernel modules - modify kernel without limit - CAP_SYS_MODULE = Cap(16) - - // Allow ioperm/iopl access - // Allow sending USB messages to any device via /proc/bus/usb - CAP_SYS_RAWIO = Cap(17) - - // Allow use of chroot() - CAP_SYS_CHROOT = Cap(18) - - // Allow ptrace() of any process - CAP_SYS_PTRACE = Cap(19) - - // Allow configuration of process accounting - CAP_SYS_PACCT = Cap(20) - - // Allow configuration of the secure attention key - // Allow administration of the random device - // Allow examination and configuration of disk quotas - // Allow setting the domainname - // Allow setting the hostname - // Allow calling bdflush() - // Allow mount() and umount(), setting up new smb connection - // Allow some autofs root ioctls - // Allow nfsservctl - // Allow VM86_REQUEST_IRQ - // Allow to read/write pci config on alpha - // Allow irix_prctl on mips (setstacksize) - // Allow flushing all cache on m68k (sys_cacheflush) - // Allow removing semaphores - // Used instead of CAP_CHOWN to "chown" IPC message queues, semaphores - // and shared memory - // Allow locking/unlocking of shared memory segment - // Allow turning swap on/off - // Allow forged pids on socket credentials passing - // Allow setting readahead and flushing buffers on block devices - // Allow setting geometry in floppy driver - // Allow turning DMA on/off in xd driver - // Allow administration of md devices (mostly the above, but some - // extra ioctls) - // Allow tuning the ide driver - // Allow access to the nvram device - // Allow administration of apm_bios, serial and bttv (TV) device - // Allow manufacturer commands in isdn CAPI support driver - // Allow reading non-standardized portions of pci configuration space - // Allow DDI debug ioctl on sbpcd driver - // Allow setting up serial ports - // Allow sending raw qic-117 commands - // Allow enabling/disabling tagged queuing on SCSI controllers and sending - // arbitrary SCSI commands - // Allow setting encryption key on loopback filesystem - // Allow setting zone reclaim policy - CAP_SYS_ADMIN = Cap(21) - - // Allow use of reboot() - CAP_SYS_BOOT = Cap(22) - - // Allow raising priority and setting priority on other (different - // UID) processes - // Allow use of FIFO and round-robin (realtime) scheduling on own - // processes and setting the scheduling algorithm used by another - // process. - // Allow setting cpu affinity on other processes - CAP_SYS_NICE = Cap(23) - - // Override resource limits. Set resource limits. - // Override quota limits. - // Override reserved space on ext2 filesystem - // Modify data journaling mode on ext3 filesystem (uses journaling - // resources) - // NOTE: ext2 honors fsuid when checking for resource overrides, so - // you can override using fsuid too - // Override size restrictions on IPC message queues - // Allow more than 64hz interrupts from the real-time clock - // Override max number of consoles on console allocation - // Override max number of keymaps - CAP_SYS_RESOURCE = Cap(24) - - // Allow manipulation of system clock - // Allow irix_stime on mips - // Allow setting the real-time clock - CAP_SYS_TIME = Cap(25) - - // Allow configuration of tty devices - // Allow vhangup() of tty - CAP_SYS_TTY_CONFIG = Cap(26) - - // Allow the privileged aspects of mknod() - CAP_MKNOD = Cap(27) - - // Allow taking of leases on files - CAP_LEASE = Cap(28) - - CAP_AUDIT_WRITE = Cap(29) - CAP_AUDIT_CONTROL = Cap(30) - CAP_SETFCAP = Cap(31) - - // Override MAC access. - // The base kernel enforces no MAC policy. - // An LSM may enforce a MAC policy, and if it does and it chooses - // to implement capability based overrides of that policy, this is - // the capability it should use to do so. - CAP_MAC_OVERRIDE = Cap(32) - - // Allow MAC configuration or state changes. - // The base kernel requires no MAC configuration. - // An LSM may enforce a MAC policy, and if it does and it chooses - // to implement capability based checks on modifications to that - // policy or the data required to maintain it, this is the - // capability it should use to do so. - CAP_MAC_ADMIN = Cap(33) - - // Allow configuring the kernel's syslog (printk behaviour) - CAP_SYSLOG = Cap(34) - - // Allow triggering something that will wake the system - CAP_WAKE_ALARM = Cap(35) - - // Allow preventing system suspends - CAP_BLOCK_SUSPEND = Cap(36) - - // Allow reading audit messages from the kernel - CAP_AUDIT_READ = Cap(37) -) - -var ( - // Highest valid capability of the running kernel. - CAP_LAST_CAP = Cap(63) - - capUpperMask = ^uint32(0) -) diff --git a/vendor/github.com/syndtr/gocapability/capability/enum_gen.go b/vendor/github.com/syndtr/gocapability/capability/enum_gen.go deleted file mode 100644 index b9e6d2d5..00000000 --- a/vendor/github.com/syndtr/gocapability/capability/enum_gen.go +++ /dev/null @@ -1,129 +0,0 @@ -// generated file; DO NOT EDIT - use go generate in directory with source - -package capability - -func (c Cap) String() string { - switch c { - case CAP_CHOWN: - return "chown" - case CAP_DAC_OVERRIDE: - return "dac_override" - case CAP_DAC_READ_SEARCH: - return "dac_read_search" - case CAP_FOWNER: - return "fowner" - case CAP_FSETID: - return "fsetid" - case CAP_KILL: - return "kill" - case CAP_SETGID: - return "setgid" - case CAP_SETUID: - return "setuid" - case CAP_SETPCAP: - return "setpcap" - case CAP_LINUX_IMMUTABLE: - return "linux_immutable" - case CAP_NET_BIND_SERVICE: - return "net_bind_service" - case CAP_NET_BROADCAST: - return "net_broadcast" - case CAP_NET_ADMIN: - return "net_admin" - case CAP_NET_RAW: - return "net_raw" - case CAP_IPC_LOCK: - return "ipc_lock" - case CAP_IPC_OWNER: - return "ipc_owner" - case CAP_SYS_MODULE: - return "sys_module" - case CAP_SYS_RAWIO: - return "sys_rawio" - case CAP_SYS_CHROOT: - return "sys_chroot" - case CAP_SYS_PTRACE: - return "sys_ptrace" - case CAP_SYS_PACCT: - return "sys_pacct" - case CAP_SYS_ADMIN: - return "sys_admin" - case CAP_SYS_BOOT: - return "sys_boot" - case CAP_SYS_NICE: - return "sys_nice" - case CAP_SYS_RESOURCE: - return "sys_resource" - case CAP_SYS_TIME: - return "sys_time" - case CAP_SYS_TTY_CONFIG: - return "sys_tty_config" - case CAP_MKNOD: - return "mknod" - case CAP_LEASE: - return "lease" - case CAP_AUDIT_WRITE: - return "audit_write" - case CAP_AUDIT_CONTROL: - return "audit_control" - case CAP_SETFCAP: - return "setfcap" - case CAP_MAC_OVERRIDE: - return "mac_override" - case CAP_MAC_ADMIN: - return "mac_admin" - case CAP_SYSLOG: - return "syslog" - case CAP_WAKE_ALARM: - return "wake_alarm" - case CAP_BLOCK_SUSPEND: - return "block_suspend" - case CAP_AUDIT_READ: - return "audit_read" - } - return "unknown" -} - -// List returns list of all supported capabilities -func List() []Cap { - return []Cap{ - CAP_CHOWN, - CAP_DAC_OVERRIDE, - CAP_DAC_READ_SEARCH, - CAP_FOWNER, - CAP_FSETID, - CAP_KILL, - CAP_SETGID, - CAP_SETUID, - CAP_SETPCAP, - CAP_LINUX_IMMUTABLE, - CAP_NET_BIND_SERVICE, - CAP_NET_BROADCAST, - CAP_NET_ADMIN, - CAP_NET_RAW, - CAP_IPC_LOCK, - CAP_IPC_OWNER, - CAP_SYS_MODULE, - CAP_SYS_RAWIO, - CAP_SYS_CHROOT, - CAP_SYS_PTRACE, - CAP_SYS_PACCT, - CAP_SYS_ADMIN, - CAP_SYS_BOOT, - CAP_SYS_NICE, - CAP_SYS_RESOURCE, - CAP_SYS_TIME, - CAP_SYS_TTY_CONFIG, - CAP_MKNOD, - CAP_LEASE, - CAP_AUDIT_WRITE, - CAP_AUDIT_CONTROL, - CAP_SETFCAP, - CAP_MAC_OVERRIDE, - CAP_MAC_ADMIN, - CAP_SYSLOG, - CAP_WAKE_ALARM, - CAP_BLOCK_SUSPEND, - CAP_AUDIT_READ, - } -} diff --git a/vendor/github.com/syndtr/gocapability/capability/syscall_linux.go b/vendor/github.com/syndtr/gocapability/capability/syscall_linux.go deleted file mode 100644 index eb717008..00000000 --- a/vendor/github.com/syndtr/gocapability/capability/syscall_linux.go +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (c) 2013, Suryandaru Triandana -// All rights reserved. -// -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package capability - -import ( - "syscall" - "unsafe" -) - -type capHeader struct { - version uint32 - pid int -} - -type capData struct { - effective uint32 - permitted uint32 - inheritable uint32 -} - -func capget(hdr *capHeader, data *capData) (err error) { - _, _, e1 := syscall.Syscall(syscall.SYS_CAPGET, uintptr(unsafe.Pointer(hdr)), uintptr(unsafe.Pointer(data)), 0) - if e1 != 0 { - err = e1 - } - return -} - -func capset(hdr *capHeader, data *capData) (err error) { - _, _, e1 := syscall.Syscall(syscall.SYS_CAPSET, uintptr(unsafe.Pointer(hdr)), uintptr(unsafe.Pointer(data)), 0) - if e1 != 0 { - err = e1 - } - return -} - -// not yet in syscall -const ( - pr_CAP_AMBIENT = 47 - pr_CAP_AMBIENT_IS_SET = uintptr(1) - pr_CAP_AMBIENT_RAISE = uintptr(2) - pr_CAP_AMBIENT_LOWER = uintptr(3) - pr_CAP_AMBIENT_CLEAR_ALL = uintptr(4) -) - -func prctl(option int, arg2, arg3, arg4, arg5 uintptr) (err error) { - _, _, e1 := syscall.Syscall6(syscall.SYS_PRCTL, uintptr(option), arg2, arg3, arg4, arg5, 0) - if e1 != 0 { - err = e1 - } - return -} - -const ( - vfsXattrName = "security.capability" - - vfsCapVerMask = 0xff000000 - vfsCapVer1 = 0x01000000 - vfsCapVer2 = 0x02000000 - - vfsCapFlagMask = ^vfsCapVerMask - vfsCapFlageffective = 0x000001 - - vfscapDataSizeV1 = 4 * (1 + 2*1) - vfscapDataSizeV2 = 4 * (1 + 2*2) -) - -type vfscapData struct { - magic uint32 - data [2]struct { - permitted uint32 - inheritable uint32 - } - effective [2]uint32 - version int8 -} - -var ( - _vfsXattrName *byte -) - -func init() { - _vfsXattrName, _ = syscall.BytePtrFromString(vfsXattrName) -} - -func getVfsCap(path string, dest *vfscapData) (err error) { - var _p0 *byte - _p0, err = syscall.BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := syscall.Syscall6(syscall.SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_vfsXattrName)), uintptr(unsafe.Pointer(dest)), vfscapDataSizeV2, 0, 0) - if e1 != 0 { - if e1 == syscall.ENODATA { - dest.version = 2 - return - } - err = e1 - } - switch dest.magic & vfsCapVerMask { - case vfsCapVer1: - dest.version = 1 - if r0 != vfscapDataSizeV1 { - return syscall.EINVAL - } - dest.data[1].permitted = 0 - dest.data[1].inheritable = 0 - case vfsCapVer2: - dest.version = 2 - if r0 != vfscapDataSizeV2 { - return syscall.EINVAL - } - default: - return syscall.EINVAL - } - if dest.magic&vfsCapFlageffective != 0 { - dest.effective[0] = dest.data[0].permitted | dest.data[0].inheritable - dest.effective[1] = dest.data[1].permitted | dest.data[1].inheritable - } else { - dest.effective[0] = 0 - dest.effective[1] = 0 - } - return -} - -func setVfsCap(path string, data *vfscapData) (err error) { - var _p0 *byte - _p0, err = syscall.BytePtrFromString(path) - if err != nil { - return - } - var size uintptr - if data.version == 1 { - data.magic = vfsCapVer1 - size = vfscapDataSizeV1 - } else if data.version == 2 { - data.magic = vfsCapVer2 - if data.effective[0] != 0 || data.effective[1] != 0 { - data.magic |= vfsCapFlageffective - } - size = vfscapDataSizeV2 - } else { - return syscall.EINVAL - } - _, _, e1 := syscall.Syscall6(syscall.SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_vfsXattrName)), uintptr(unsafe.Pointer(data)), size, 0, 0) - if e1 != 0 { - err = e1 - } - return -}