Bladeren bron

vendor: github.com/containerd/go-runc v1.1.0

full diff: https://github.com/containerd/go-runc/compare/v1.0.0...v1.1.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Sebastiaan van Stijn 2 jaren geleden
bovenliggende
commit
3512b04093

+ 1 - 1
vendor.mod

@@ -120,7 +120,7 @@ require (
 	github.com/containerd/cgroups v1.0.4 // indirect
 	github.com/containerd/console v1.0.3 // indirect
 	github.com/containerd/go-cni v1.1.6 // indirect
-	github.com/containerd/go-runc v1.0.0 // indirect
+	github.com/containerd/go-runc v1.1.0 // indirect
 	github.com/containerd/nydus-snapshotter v0.3.1 // indirect
 	github.com/containerd/stargz-snapshotter/estargz v0.13.0 // indirect
 	github.com/containerd/ttrpc v1.1.1 // indirect

+ 2 - 1
vendor.sum

@@ -402,8 +402,9 @@ github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH
 github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
 github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g=
 github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=
-github.com/containerd/go-runc v1.0.0 h1:oU+lLv1ULm5taqgV/CJivypVODI4SUz1znWjv3nNYS0=
 github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=
+github.com/containerd/go-runc v1.1.0 h1:OX4f+/i2y5sUT7LhmcJH7GYrjjhHa1QI4e8yO0gGleA=
+github.com/containerd/go-runc v1.1.0/go.mod h1:xJv2hFF7GvHtTJd9JqTS2UVxMkULUYw4JN5XAUZqH5U=
 github.com/containerd/imgcrypt v1.0.1/go.mod h1:mdd8cEPW7TPgNG4FpuP3sGBiQ7Yi/zak9TYCG3juvb0=
 github.com/containerd/imgcrypt v1.0.4-0.20210301171431-0ae5c75f59ba/go.mod h1:6TNsg0ctmizkrOgXRNQjAPFWpMYRWuiB6dSF4Pfa5SA=
 github.com/containerd/imgcrypt v1.1.1-0.20210312161619-7ed62a527887/go.mod h1:5AZJNI6sLHJljKuI9IHnw1pWqo/F0nGDOuR9zgTs7ow=

+ 20 - 0
vendor/github.com/containerd/go-runc/.golangci.yml

@@ -0,0 +1,20 @@
+linters:
+  enable:
+    - gofmt
+    - goimports
+    - ineffassign
+    - misspell
+    - revive
+    - staticcheck
+    - unconvert
+    - unused
+    - vet
+  disable:
+    - errcheck
+
+issues:
+  include:
+    - EXC0002
+
+run:
+  timeout: 2m

+ 0 - 21
vendor/github.com/containerd/go-runc/.travis.yml

@@ -1,21 +0,0 @@
-language: go
-go:
-    - 1.13.x
-    - 1.14.x
-    - 1.15.x
-
-install:
-  - go get -t ./...
-  - go get -u github.com/vbatts/git-validation
-  - go get -u github.com/kunalkushwaha/ltag
-
-before_script:
-  - pushd ..; git clone https://github.com/containerd/project; popd
-
-script:
-  - DCO_VERBOSITY=-q ../project/script/validate/dco
-  - ../project/script/validate/fileheader ../project/
-  - go test -v -race -covermode=atomic -coverprofile=coverage.txt ./...
-
-after_success:
-    - bash <(curl -s https://codecov.io/bash)

+ 5 - 5
vendor/github.com/containerd/go-runc/README.md

@@ -1,7 +1,7 @@
 # go-runc
 
-[![Build Status](https://travis-ci.org/containerd/go-runc.svg?branch=master)](https://travis-ci.org/containerd/go-runc)
-[![codecov](https://codecov.io/gh/containerd/go-runc/branch/master/graph/badge.svg)](https://codecov.io/gh/containerd/go-runc)
+[![Build Status](https://github.com/containerd/go-runc/workflows/CI/badge.svg)](https://github.com/containerd/go-runc/actions?query=workflow%3ACI)
+[![codecov](https://codecov.io/gh/containerd/go-runc/branch/main/graph/badge.svg)](https://codecov.io/gh/containerd/go-runc)
 
 This is a package for consuming the [runc](https://github.com/opencontainers/runc) binary in your Go applications.
 It tries to expose all the settings and features of the runc CLI.  If there is something missing then add it, its opensource!
@@ -18,8 +18,8 @@ Docs can be found at [godoc.org](https://godoc.org/github.com/containerd/go-runc
 The go-runc is a containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE).
 As a containerd sub-project, you will find the:
 
- * [Project governance](https://github.com/containerd/project/blob/master/GOVERNANCE.md),
- * [Maintainers](https://github.com/containerd/project/blob/master/MAINTAINERS),
- * and [Contributing guidelines](https://github.com/containerd/project/blob/master/CONTRIBUTING.md)
+ * [Project governance](https://github.com/containerd/project/blob/main/GOVERNANCE.md),
+ * [Maintainers](https://github.com/containerd/project/blob/main/MAINTAINERS),
+ * and [Contributing guidelines](https://github.com/containerd/project/blob/main/CONTRIBUTING.md)
 
 information in our [`containerd/project`](https://github.com/containerd/project) repository.

+ 1 - 1
vendor/github.com/containerd/go-runc/command_other.go

@@ -1,4 +1,4 @@
-// +build !linux
+//go:build !linux
 
 /*
    Copyright The containerd Authors.

+ 4 - 5
vendor/github.com/containerd/go-runc/console.go

@@ -1,4 +1,4 @@
-// +build !windows
+//go:build !windows
 
 /*
    Copyright The containerd Authors.
@@ -20,7 +20,6 @@ package runc
 
 import (
 	"fmt"
-	"io/ioutil"
 	"net"
 	"os"
 	"path/filepath"
@@ -53,7 +52,7 @@ func NewConsoleSocket(path string) (*Socket, error) {
 // On Close(), the socket is deleted
 func NewTempConsoleSocket() (*Socket, error) {
 	runtimeDir := os.Getenv("XDG_RUNTIME_DIR")
-	dir, err := ioutil.TempDir(runtimeDir, "pty")
+	dir, err := os.MkdirTemp(runtimeDir, "pty")
 	if err != nil {
 		return nil, err
 	}
@@ -70,7 +69,7 @@ func NewTempConsoleSocket() (*Socket, error) {
 		return nil, err
 	}
 	if runtimeDir != "" {
-		if err := os.Chmod(abs, 0755|os.ModeSticky); err != nil {
+		if err := os.Chmod(abs, 0o755|os.ModeSticky); err != nil {
 			return nil, err
 		}
 	}
@@ -96,7 +95,7 @@ func (c *Socket) Path() string {
 // locally (it is sent as non-auxiliary data in the same payload).
 func recvFd(socket *net.UnixConn) (*os.File, error) {
 	const MaxNameLen = 4096
-	var oobSpace = unix.CmsgSpace(4)
+	oobSpace := unix.CmsgSpace(4)
 
 	name := make([]byte, MaxNameLen)
 	oob := make([]byte, oobSpace)

+ 16 - 1
vendor/github.com/containerd/go-runc/events.go

@@ -16,6 +16,7 @@
 
 package runc
 
+// Event is a struct to pass runc event information
 type Event struct {
 	// Type are the event type generated by runc
 	// If the type is "error" then check the Err field on the event for
@@ -27,20 +28,23 @@ type Event struct {
 	Err error `json:"-"`
 }
 
+// Stats is statistical information from the runc process
 type Stats struct {
-	Cpu     Cpu                `json:"cpu"`
+	Cpu     Cpu                `json:"cpu"` //revive:disable
 	Memory  Memory             `json:"memory"`
 	Pids    Pids               `json:"pids"`
 	Blkio   Blkio              `json:"blkio"`
 	Hugetlb map[string]Hugetlb `json:"hugetlb"`
 }
 
+// Hugetlb represents the detailed hugetlb component of the statistics data
 type Hugetlb struct {
 	Usage   uint64 `json:"usage,omitempty"`
 	Max     uint64 `json:"max,omitempty"`
 	Failcnt uint64 `json:"failcnt"`
 }
 
+// BlkioEntry represents a block IO entry in the IO stats
 type BlkioEntry struct {
 	Major uint64 `json:"major,omitempty"`
 	Minor uint64 `json:"minor,omitempty"`
@@ -48,6 +52,7 @@ type BlkioEntry struct {
 	Value uint64 `json:"value,omitempty"`
 }
 
+// Blkio represents the statistical information from block IO devices
 type Blkio struct {
 	IoServiceBytesRecursive []BlkioEntry `json:"ioServiceBytesRecursive,omitempty"`
 	IoServicedRecursive     []BlkioEntry `json:"ioServicedRecursive,omitempty"`
@@ -59,17 +64,22 @@ type Blkio struct {
 	SectorsRecursive        []BlkioEntry `json:"sectorsRecursive,omitempty"`
 }
 
+// Pids represents the process ID information
 type Pids struct {
 	Current uint64 `json:"current,omitempty"`
 	Limit   uint64 `json:"limit,omitempty"`
 }
 
+// Throttling represents the throttling statistics
 type Throttling struct {
 	Periods          uint64 `json:"periods,omitempty"`
 	ThrottledPeriods uint64 `json:"throttledPeriods,omitempty"`
 	ThrottledTime    uint64 `json:"throttledTime,omitempty"`
 }
 
+// CpuUsage represents the CPU usage statistics
+//
+//revive:disable-next-line
 type CpuUsage struct {
 	// Units: nanoseconds.
 	Total  uint64   `json:"total,omitempty"`
@@ -78,11 +88,15 @@ type CpuUsage struct {
 	User   uint64   `json:"user"`
 }
 
+// Cpu represents the CPU usage and throttling statistics
+//
+//revive:disable-next-line
 type Cpu struct {
 	Usage      CpuUsage   `json:"usage,omitempty"`
 	Throttling Throttling `json:"throttling,omitempty"`
 }
 
+// MemoryEntry represents an item in the memory use/statistics
 type MemoryEntry struct {
 	Limit   uint64 `json:"limit"`
 	Usage   uint64 `json:"usage,omitempty"`
@@ -90,6 +104,7 @@ type MemoryEntry struct {
 	Failcnt uint64 `json:"failcnt"`
 }
 
+// Memory represents the collection of memory statistics from the process
 type Memory struct {
 	Cache     uint64            `json:"cache,omitempty"`
 	Usage     MemoryEntry       `json:"usage,omitempty"`

+ 10 - 2
vendor/github.com/containerd/go-runc/io.go

@@ -22,6 +22,7 @@ import (
 	"os/exec"
 )
 
+// IO is the terminal IO interface
 type IO interface {
 	io.Closer
 	Stdin() io.WriteCloser
@@ -30,6 +31,7 @@ type IO interface {
 	Set(*exec.Cmd)
 }
 
+// StartCloser is an interface to handle IO closure after start
 type StartCloser interface {
 	CloseAfterStart() error
 }
@@ -76,6 +78,12 @@ func (p *pipe) Close() error {
 	return err
 }
 
+// NewPipeIO creates pipe pairs to be used with runc. It is not implemented
+// on Windows.
+func NewPipeIO(uid, gid int, opts ...IOOpt) (i IO, err error) {
+	return newPipeIO(uid, gid, opts...)
+}
+
 type pipeIO struct {
 	in  *pipe
 	out *pipe
@@ -144,12 +152,12 @@ func (i *pipeIO) Set(cmd *exec.Cmd) {
 	}
 }
 
+// NewSTDIO returns I/O setup for standard OS in/out/err usage
 func NewSTDIO() (IO, error) {
 	return &stdio{}, nil
 }
 
-type stdio struct {
-}
+type stdio struct{}
 
 func (s *stdio) Close() error {
 	return nil

+ 9 - 8
vendor/github.com/containerd/go-runc/io_unix.go

@@ -1,4 +1,4 @@
-// +build !windows
+//go:build !windows
 
 /*
    Copyright The containerd Authors.
@@ -19,14 +19,15 @@
 package runc
 
 import (
-	"github.com/pkg/errors"
+	"fmt"
+	"runtime"
+
 	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/unix"
-	"runtime"
 )
 
-// NewPipeIO creates pipe pairs to be used with runc
-func NewPipeIO(uid, gid int, opts ...IOOpt) (i IO, err error) {
+// newPipeIO creates pipe pairs to be used with runc
+func newPipeIO(uid, gid int, opts ...IOOpt) (i IO, err error) {
 	option := defaultIOOption()
 	for _, o := range opts {
 		o(option)
@@ -54,7 +55,7 @@ func NewPipeIO(uid, gid int, opts ...IOOpt) (i IO, err error) {
 			if runtime.GOOS == "darwin" {
 				logrus.WithError(err).Debug("failed to chown stdin, ignored")
 			} else {
-				return nil, errors.Wrap(err, "failed to chown stdin")
+				return nil, fmt.Errorf("failed to chown stdin: %w", err)
 			}
 		}
 	}
@@ -69,7 +70,7 @@ func NewPipeIO(uid, gid int, opts ...IOOpt) (i IO, err error) {
 			if runtime.GOOS == "darwin" {
 				logrus.WithError(err).Debug("failed to chown stdout, ignored")
 			} else {
-				return nil, errors.Wrap(err, "failed to chown stdout")
+				return nil, fmt.Errorf("failed to chown stdout: %w", err)
 			}
 		}
 	}
@@ -84,7 +85,7 @@ func NewPipeIO(uid, gid int, opts ...IOOpt) (i IO, err error) {
 			if runtime.GOOS == "darwin" {
 				logrus.WithError(err).Debug("failed to chown stderr, ignored")
 			} else {
-				return nil, errors.Wrap(err, "failed to chown stderr")
+				return nil, fmt.Errorf("failed to chown stderr: %w", err)
 			}
 		}
 	}

+ 5 - 42
vendor/github.com/containerd/go-runc/io_windows.go

@@ -1,4 +1,4 @@
-// +build windows
+//go:build windows
 
 /*
    Copyright The containerd Authors.
@@ -18,45 +18,8 @@
 
 package runc
 
-// NewPipeIO creates pipe pairs to be used with runc
-func NewPipeIO(opts ...IOOpt) (i IO, err error) {
-	option := defaultIOOption()
-	for _, o := range opts {
-		o(option)
-	}
-	var (
-		pipes                 []*pipe
-		stdin, stdout, stderr *pipe
-	)
-	// cleanup in case of an error
-	defer func() {
-		if err != nil {
-			for _, p := range pipes {
-				p.Close()
-			}
-		}
-	}()
-	if option.OpenStdin {
-		if stdin, err = newPipe(); err != nil {
-			return nil, err
-		}
-		pipes = append(pipes, stdin)
-	}
-	if option.OpenStdout {
-		if stdout, err = newPipe(); err != nil {
-			return nil, err
-		}
-		pipes = append(pipes, stdout)
-	}
-	if option.OpenStderr {
-		if stderr, err = newPipe(); err != nil {
-			return nil, err
-		}
-		pipes = append(pipes, stderr)
-	}
-	return &pipeIO{
-		in:  stdin,
-		out: stdout,
-		err: stderr,
-	}, nil
+import "errors"
+
+func newPipeIO(uid, gid int, opts ...IOOpt) (i IO, err error) {
+	return nil, errors.New("not implemented on Windows")
 }

+ 48 - 6
vendor/github.com/containerd/go-runc/monitor.go

@@ -18,32 +18,37 @@ package runc
 
 import (
 	"os/exec"
+	"runtime"
 	"syscall"
 	"time"
 )
 
+// Monitor is the default ProcessMonitor for handling runc process exit
 var Monitor ProcessMonitor = &defaultMonitor{}
 
+// Exit holds the exit information from a process
 type Exit struct {
 	Timestamp time.Time
 	Pid       int
 	Status    int
 }
 
-// ProcessMonitor is an interface for process monitoring
+// ProcessMonitor is an interface for process monitoring.
 //
 // It allows daemons using go-runc to have a SIGCHLD handler
 // to handle exits without introducing races between the handler
-// and go's exec.Cmd
-// These methods should match the methods exposed by exec.Cmd to provide
-// a consistent experience for the caller
+// and go's exec.Cmd.
+//
+// ProcessMonitor also provides a StartLocked method which is similar to
+// Start, but locks the goroutine used to start the process to an OS thread
+// (for example: when Pdeathsig is set).
 type ProcessMonitor interface {
 	Start(*exec.Cmd) (chan Exit, error)
+	StartLocked(*exec.Cmd) (chan Exit, error)
 	Wait(*exec.Cmd, chan Exit) (int, error)
 }
 
-type defaultMonitor struct {
-}
+type defaultMonitor struct{}
 
 func (m *defaultMonitor) Start(c *exec.Cmd) (chan Exit, error) {
 	if err := c.Start(); err != nil {
@@ -70,6 +75,43 @@ func (m *defaultMonitor) Start(c *exec.Cmd) (chan Exit, error) {
 	return ec, nil
 }
 
+// StartLocked is like Start, but locks the goroutine used to start the process to
+// the OS thread for use-cases where the parent thread matters to the child process
+// (for example: when Pdeathsig is set).
+func (m *defaultMonitor) StartLocked(c *exec.Cmd) (chan Exit, error) {
+	started := make(chan error)
+	ec := make(chan Exit, 1)
+	go func() {
+		runtime.LockOSThread()
+		defer runtime.UnlockOSThread()
+
+		if err := c.Start(); err != nil {
+			started <- err
+			return
+		}
+		close(started)
+		var status int
+		if err := c.Wait(); err != nil {
+			status = 255
+			if exitErr, ok := err.(*exec.ExitError); ok {
+				if ws, ok := exitErr.Sys().(syscall.WaitStatus); ok {
+					status = ws.ExitStatus()
+				}
+			}
+		}
+		ec <- Exit{
+			Timestamp: time.Now(),
+			Pid:       c.Process.Pid,
+			Status:    status,
+		}
+		close(ec)
+	}()
+	if err := <-started; err != nil {
+		return nil, err
+	}
+	return ec, nil
+}
+
 func (m *defaultMonitor) Wait(c *exec.Cmd, ec chan Exit) (int, error) {
 	e := <-ec
 	return e.Status, nil

+ 163 - 54
vendor/github.com/containerd/go-runc/runc.go

@@ -23,21 +23,22 @@ import (
 	"errors"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"os"
 	"os/exec"
 	"path/filepath"
 	"strconv"
 	"strings"
+	"syscall"
 	"time"
 
 	specs "github.com/opencontainers/runtime-spec/specs-go"
+	"github.com/opencontainers/runtime-spec/specs-go/features"
 )
 
-// Format is the type of log formatting options avaliable
+// Format is the type of log formatting options available
 type Format string
 
-// TopBody represents the structured data of the full ps output
+// TopResults represents the structured data of the full ps output
 type TopResults struct {
 	// Processes running in the container, where each is process is an array of values corresponding to the headers
 	Processes [][]string `json:"Processes"`
@@ -48,15 +49,53 @@ type TopResults struct {
 
 const (
 	none Format = ""
+	// JSON represents the JSON format
 	JSON Format = "json"
+	// Text represents plain text format
 	Text Format = "text"
-	// DefaultCommand is the default command for Runc
-	DefaultCommand = "runc"
 )
 
+// DefaultCommand is the default command for Runc
+var DefaultCommand = "runc"
+
+// Runc is the client to the runc cli
+type Runc struct {
+	// Command overrides the name of the runc binary. If empty, DefaultCommand
+	// is used.
+	Command   string
+	Root      string
+	Debug     bool
+	Log       string
+	LogFormat Format
+	// PdeathSignal sets a signal the child process will receive when the
+	// parent dies.
+	//
+	// When Pdeathsig is set, command invocations will call runtime.LockOSThread
+	// to prevent OS thread termination from spuriously triggering the
+	// signal. See https://github.com/golang/go/issues/27505 and
+	// https://github.com/golang/go/blob/126c22a09824a7b52c019ed9a1d198b4e7781676/src/syscall/exec_linux.go#L48-L51
+	//
+	// A program with GOMAXPROCS=1 might hang because of the use of
+	// runtime.LockOSThread. Callers should ensure they retain at least one
+	// unlocked thread.
+	PdeathSignal syscall.Signal // using syscall.Signal to allow compilation on non-unix (unix.Syscall is an alias for syscall.Signal)
+	Setpgid      bool
+
+	// Criu sets the path to the criu binary used for checkpoint and restore.
+	//
+	// Deprecated: runc option --criu is now ignored (with a warning), and the
+	// option will be removed entirely in a future release. Users who need a non-
+	// standard criu binary should rely on the standard way of looking up binaries
+	// in $PATH.
+	Criu          string
+	SystemdCgroup bool
+	Rootless      *bool // nil stands for "auto"
+	ExtraArgs     []string
+}
+
 // List returns all containers created inside the provided runc root directory
 func (r *Runc) List(context context.Context) ([]*Container, error) {
-	data, err := cmdOutput(r.command(context, "list", "--format=json"), false, nil)
+	data, err := r.cmdOutput(r.command(context, "list", "--format=json"), false, nil)
 	defer putBuf(data)
 	if err != nil {
 		return nil, err
@@ -70,7 +109,7 @@ func (r *Runc) List(context context.Context) ([]*Container, error) {
 
 // State returns the state for the container provided by id
 func (r *Runc) State(context context.Context, id string) (*Container, error) {
-	data, err := cmdOutput(r.command(context, "state", id), true, nil)
+	data, err := r.cmdOutput(r.command(context, "state", id), true, nil)
 	defer putBuf(data)
 	if err != nil {
 		return nil, fmt.Errorf("%s: %s", err, data.String())
@@ -82,10 +121,12 @@ func (r *Runc) State(context context.Context, id string) (*Container, error) {
 	return &c, nil
 }
 
+// ConsoleSocket handles the path of the socket for console access
 type ConsoleSocket interface {
 	Path() string
 }
 
+// CreateOpts holds all the options information for calling runc with supported options
 type CreateOpts struct {
 	IO
 	// PidFile is a path to where a pid file should be created
@@ -96,6 +137,7 @@ type CreateOpts struct {
 	NoNewKeyring  bool
 	ExtraFiles    []*os.File
 	Started       chan<- int
+	ExtraArgs     []string
 }
 
 func (o *CreateOpts) args() (out []string, err error) {
@@ -121,38 +163,50 @@ func (o *CreateOpts) args() (out []string, err error) {
 	if o.ExtraFiles != nil {
 		out = append(out, "--preserve-fds", strconv.Itoa(len(o.ExtraFiles)))
 	}
+	if len(o.ExtraArgs) > 0 {
+		out = append(out, o.ExtraArgs...)
+	}
 	return out, nil
 }
 
+func (r *Runc) startCommand(cmd *exec.Cmd) (chan Exit, error) {
+	if r.PdeathSignal != 0 {
+		return Monitor.StartLocked(cmd)
+	}
+	return Monitor.Start(cmd)
+}
+
 // Create creates a new container and returns its pid if it was created successfully
 func (r *Runc) Create(context context.Context, id, bundle string, opts *CreateOpts) error {
 	args := []string{"create", "--bundle", bundle}
-	if opts != nil {
-		oargs, err := opts.args()
-		if err != nil {
-			return err
-		}
-		args = append(args, oargs...)
+	if opts == nil {
+		opts = &CreateOpts{}
+	}
+
+	oargs, err := opts.args()
+	if err != nil {
+		return err
 	}
+	args = append(args, oargs...)
 	cmd := r.command(context, append(args, id)...)
-	if opts != nil && opts.IO != nil {
+	if opts.IO != nil {
 		opts.Set(cmd)
 	}
 	cmd.ExtraFiles = opts.ExtraFiles
 
 	if cmd.Stdout == nil && cmd.Stderr == nil {
-		data, err := cmdOutput(cmd, true, nil)
+		data, err := r.cmdOutput(cmd, true, nil)
 		defer putBuf(data)
 		if err != nil {
 			return fmt.Errorf("%s: %s", err, data.String())
 		}
 		return nil
 	}
-	ec, err := Monitor.Start(cmd)
+	ec, err := r.startCommand(cmd)
 	if err != nil {
 		return err
 	}
-	if opts != nil && opts.IO != nil {
+	if opts.IO != nil {
 		if c, ok := opts.IO.(StartCloser); ok {
 			if err := c.CloseAfterStart(); err != nil {
 				return err
@@ -171,12 +225,14 @@ func (r *Runc) Start(context context.Context, id string) error {
 	return r.runOrError(r.command(context, "start", id))
 }
 
+// ExecOpts holds optional settings when starting an exec process with runc
 type ExecOpts struct {
 	IO
 	PidFile       string
 	ConsoleSocket ConsoleSocket
 	Detach        bool
 	Started       chan<- int
+	ExtraArgs     []string
 }
 
 func (o *ExecOpts) args() (out []string, err error) {
@@ -193,16 +249,22 @@ func (o *ExecOpts) args() (out []string, err error) {
 		}
 		out = append(out, "--pid-file", abs)
 	}
+	if len(o.ExtraArgs) > 0 {
+		out = append(out, o.ExtraArgs...)
+	}
 	return out, nil
 }
 
 // Exec executes an additional process inside the container based on a full
 // OCI Process specification
 func (r *Runc) Exec(context context.Context, id string, spec specs.Process, opts *ExecOpts) error {
+	if opts == nil {
+		opts = &ExecOpts{}
+	}
 	if opts.Started != nil {
 		defer close(opts.Started)
 	}
-	f, err := ioutil.TempFile(os.Getenv("XDG_RUNTIME_DIR"), "runc-process")
+	f, err := os.CreateTemp(os.Getenv("XDG_RUNTIME_DIR"), "runc-process")
 	if err != nil {
 		return err
 	}
@@ -213,33 +275,31 @@ func (r *Runc) Exec(context context.Context, id string, spec specs.Process, opts
 		return err
 	}
 	args := []string{"exec", "--process", f.Name()}
-	if opts != nil {
-		oargs, err := opts.args()
-		if err != nil {
-			return err
-		}
-		args = append(args, oargs...)
+	oargs, err := opts.args()
+	if err != nil {
+		return err
 	}
+	args = append(args, oargs...)
 	cmd := r.command(context, append(args, id)...)
-	if opts != nil && opts.IO != nil {
+	if opts.IO != nil {
 		opts.Set(cmd)
 	}
 	if cmd.Stdout == nil && cmd.Stderr == nil {
-		data, err := cmdOutput(cmd, true, opts.Started)
+		data, err := r.cmdOutput(cmd, true, opts.Started)
 		defer putBuf(data)
 		if err != nil {
 			return fmt.Errorf("%w: %s", err, data.String())
 		}
 		return nil
 	}
-	ec, err := Monitor.Start(cmd)
+	ec, err := r.startCommand(cmd)
 	if err != nil {
 		return err
 	}
 	if opts.Started != nil {
 		opts.Started <- cmd.Process.Pid
 	}
-	if opts != nil && opts.IO != nil {
+	if opts.IO != nil {
 		if c, ok := opts.IO.(StartCloser); ok {
 			if err := c.CloseAfterStart(); err != nil {
 				return err
@@ -256,22 +316,24 @@ func (r *Runc) Exec(context context.Context, id string, spec specs.Process, opts
 // Run runs the create, start, delete lifecycle of the container
 // and returns its exit status after it has exited
 func (r *Runc) Run(context context.Context, id, bundle string, opts *CreateOpts) (int, error) {
+	if opts == nil {
+		opts = &CreateOpts{}
+	}
 	if opts.Started != nil {
 		defer close(opts.Started)
 	}
 	args := []string{"run", "--bundle", bundle}
-	if opts != nil {
-		oargs, err := opts.args()
-		if err != nil {
-			return -1, err
-		}
-		args = append(args, oargs...)
+	oargs, err := opts.args()
+	if err != nil {
+		return -1, err
 	}
+	args = append(args, oargs...)
 	cmd := r.command(context, append(args, id)...)
-	if opts != nil && opts.IO != nil {
+	if opts.IO != nil {
 		opts.Set(cmd)
 	}
-	ec, err := Monitor.Start(cmd)
+	cmd.ExtraFiles = opts.ExtraFiles
+	ec, err := r.startCommand(cmd)
 	if err != nil {
 		return -1, err
 	}
@@ -285,14 +347,19 @@ func (r *Runc) Run(context context.Context, id, bundle string, opts *CreateOpts)
 	return status, err
 }
 
+// DeleteOpts holds the deletion options for calling `runc delete`
 type DeleteOpts struct {
-	Force bool
+	Force     bool
+	ExtraArgs []string
 }
 
 func (o *DeleteOpts) args() (out []string) {
 	if o.Force {
 		out = append(out, "--force")
 	}
+	if len(o.ExtraArgs) > 0 {
+		out = append(out, o.ExtraArgs...)
+	}
 	return out
 }
 
@@ -307,13 +374,17 @@ func (r *Runc) Delete(context context.Context, id string, opts *DeleteOpts) erro
 
 // KillOpts specifies options for killing a container and its processes
 type KillOpts struct {
-	All bool
+	All       bool
+	ExtraArgs []string
 }
 
 func (o *KillOpts) args() (out []string) {
 	if o.All {
 		out = append(out, "--all")
 	}
+	if len(o.ExtraArgs) > 0 {
+		out = append(out, o.ExtraArgs...)
+	}
 	return out
 }
 
@@ -335,7 +406,7 @@ func (r *Runc) Stats(context context.Context, id string) (*Stats, error) {
 	if err != nil {
 		return nil, err
 	}
-	ec, err := Monitor.Start(cmd)
+	ec, err := r.startCommand(cmd)
 	if err != nil {
 		return nil, err
 	}
@@ -357,7 +428,7 @@ func (r *Runc) Events(context context.Context, id string, interval time.Duration
 	if err != nil {
 		return nil, err
 	}
-	ec, err := Monitor.Start(cmd)
+	ec, err := r.startCommand(cmd)
 	if err != nil {
 		rd.Close()
 		return nil, err
@@ -401,7 +472,7 @@ func (r *Runc) Resume(context context.Context, id string) error {
 
 // Ps lists all the processes inside the container returning their pids
 func (r *Runc) Ps(context context.Context, id string) ([]int, error) {
-	data, err := cmdOutput(r.command(context, "ps", "--format", "json", id), true, nil)
+	data, err := r.cmdOutput(r.command(context, "ps", "--format", "json", id), true, nil)
 	defer putBuf(data)
 	if err != nil {
 		return nil, fmt.Errorf("%s: %s", err, data.String())
@@ -415,7 +486,7 @@ func (r *Runc) Ps(context context.Context, id string) ([]int, error) {
 
 // Top lists all the processes inside the container returning the full ps data
 func (r *Runc) Top(context context.Context, id string, psOptions string) (*TopResults, error) {
-	data, err := cmdOutput(r.command(context, "ps", "--format", "table", id, psOptions), true, nil)
+	data, err := r.cmdOutput(r.command(context, "ps", "--format", "table", id, psOptions), true, nil)
 	defer putBuf(data)
 	if err != nil {
 		return nil, fmt.Errorf("%s: %s", err, data.String())
@@ -428,6 +499,7 @@ func (r *Runc) Top(context context.Context, id string, psOptions string) (*TopRe
 	return topResults, nil
 }
 
+// CheckpointOpts holds the options for performing a criu checkpoint using runc
 type CheckpointOpts struct {
 	// ImagePath is the path for saving the criu image file
 	ImagePath string
@@ -454,13 +526,18 @@ type CheckpointOpts struct {
 	LazyPages bool
 	// StatusFile is the file criu writes \0 to once lazy-pages is ready
 	StatusFile *os.File
+	ExtraArgs  []string
 }
 
+// CgroupMode defines the cgroup mode used for checkpointing
 type CgroupMode string
 
 const (
-	Soft   CgroupMode = "soft"
-	Full   CgroupMode = "full"
+	// Soft is the "soft" cgroup mode
+	Soft CgroupMode = "soft"
+	// Full is the "full" cgroup mode
+	Full CgroupMode = "full"
+	// Strict is the "strict" cgroup mode
 	Strict CgroupMode = "strict"
 )
 
@@ -498,9 +575,13 @@ func (o *CheckpointOpts) args() (out []string) {
 	if o.LazyPages {
 		out = append(out, "--lazy-pages")
 	}
+	if len(o.ExtraArgs) > 0 {
+		out = append(out, o.ExtraArgs...)
+	}
 	return out
 }
 
+// CheckpointAction represents specific actions executed during checkpoint/restore
 type CheckpointAction func([]string) []string
 
 // LeaveRunning keeps the container running after the checkpoint has been completed
@@ -535,6 +616,7 @@ func (r *Runc) Checkpoint(context context.Context, id string, opts *CheckpointOp
 	return r.runOrError(cmd)
 }
 
+// RestoreOpts holds the options for performing a criu restore using runc
 type RestoreOpts struct {
 	CheckpointOpts
 	IO
@@ -544,6 +626,7 @@ type RestoreOpts struct {
 	NoSubreaper   bool
 	NoPivot       bool
 	ConsoleSocket ConsoleSocket
+	ExtraArgs     []string
 }
 
 func (o *RestoreOpts) args() ([]string, error) {
@@ -567,6 +650,9 @@ func (o *RestoreOpts) args() ([]string, error) {
 	if o.NoSubreaper {
 		out = append(out, "-no-subreaper")
 	}
+	if len(o.ExtraArgs) > 0 {
+		out = append(out, o.ExtraArgs...)
+	}
 	return out, nil
 }
 
@@ -585,7 +671,7 @@ func (r *Runc) Restore(context context.Context, id, bundle string, opts *Restore
 	if opts != nil && opts.IO != nil {
 		opts.Set(cmd)
 	}
-	ec, err := Monitor.Start(cmd)
+	ec, err := r.startCommand(cmd)
 	if err != nil {
 		return -1, err
 	}
@@ -611,14 +697,16 @@ func (r *Runc) Update(context context.Context, id string, resources *specs.Linux
 	if err := json.NewEncoder(buf).Encode(resources); err != nil {
 		return err
 	}
-	args := []string{"update", "--resources", "-", id}
+	args := []string{"update", "--resources=-", id}
 	cmd := r.command(context, args...)
 	cmd.Stdin = buf
 	return r.runOrError(cmd)
 }
 
+// ErrParseRuncVersion is used when the runc version can't be parsed
 var ErrParseRuncVersion = errors.New("unable to parse runc version")
 
+// Version represents the runc version information
 type Version struct {
 	Runc   string
 	Commit string
@@ -627,7 +715,7 @@ type Version struct {
 
 // Version returns the runc and runtime-spec versions
 func (r *Runc) Version(context context.Context) (Version, error) {
-	data, err := cmdOutput(r.command(context, "--version"), false, nil)
+	data, err := r.cmdOutput(r.command(context, "--version"), false, nil)
 	defer putBuf(data)
 	if err != nil {
 		return Version{}, err
@@ -657,6 +745,26 @@ func parseVersion(data []byte) (Version, error) {
 	return v, nil
 }
 
+// Features shows the features implemented by the runtime.
+//
+// Availability:
+//
+//   - runc:  supported since runc v1.1.0
+//   - crun:  https://github.com/containers/crun/issues/1177
+//   - youki: https://github.com/containers/youki/issues/815
+func (r *Runc) Features(context context.Context) (*features.Features, error) {
+	data, err := r.cmdOutput(r.command(context, "features"), false, nil)
+	defer putBuf(data)
+	if err != nil {
+		return nil, err
+	}
+	var feat features.Features
+	if err := json.Unmarshal(data.Bytes(), &feat); err != nil {
+		return nil, err
+	}
+	return &feat, nil
+}
+
 func (r *Runc) args() (out []string) {
 	if r.Root != "" {
 		out = append(out, "--root", r.Root)
@@ -670,9 +778,6 @@ func (r *Runc) args() (out []string) {
 	if r.LogFormat != none {
 		out = append(out, "--log-format", string(r.LogFormat))
 	}
-	if r.Criu != "" {
-		out = append(out, "--criu", r.Criu)
-	}
 	if r.SystemdCgroup {
 		out = append(out, "--systemd-cgroup")
 	}
@@ -680,6 +785,9 @@ func (r *Runc) args() (out []string) {
 		// nil stands for "auto" (differs from explicit "false")
 		out = append(out, "--rootless="+strconv.FormatBool(*r.Rootless))
 	}
+	if len(r.ExtraArgs) > 0 {
+		out = append(out, r.ExtraArgs...)
+	}
 	return out
 }
 
@@ -689,7 +797,7 @@ func (r *Runc) args() (out []string) {
 // <stderr>
 func (r *Runc) runOrError(cmd *exec.Cmd) error {
 	if cmd.Stdout != nil || cmd.Stderr != nil {
-		ec, err := Monitor.Start(cmd)
+		ec, err := r.startCommand(cmd)
 		if err != nil {
 			return err
 		}
@@ -699,7 +807,7 @@ func (r *Runc) runOrError(cmd *exec.Cmd) error {
 		}
 		return err
 	}
-	data, err := cmdOutput(cmd, true, nil)
+	data, err := r.cmdOutput(cmd, true, nil)
 	defer putBuf(data)
 	if err != nil {
 		return fmt.Errorf("%s: %s", err, data.String())
@@ -709,14 +817,14 @@ func (r *Runc) runOrError(cmd *exec.Cmd) error {
 
 // callers of cmdOutput are expected to call putBuf on the returned Buffer
 // to ensure it is released back to the shared pool after use.
-func cmdOutput(cmd *exec.Cmd, combined bool, started chan<- int) (*bytes.Buffer, error) {
+func (r *Runc) cmdOutput(cmd *exec.Cmd, combined bool, started chan<- int) (*bytes.Buffer, error) {
 	b := getBuf()
 
 	cmd.Stdout = b
 	if combined {
 		cmd.Stderr = b
 	}
-	ec, err := Monitor.Start(cmd)
+	ec, err := r.startCommand(cmd)
 	if err != nil {
 		return nil, err
 	}
@@ -732,6 +840,7 @@ func cmdOutput(cmd *exec.Cmd, combined bool, started chan<- int) (*bytes.Buffer,
 	return b, err
 }
 
+// ExitError holds the status return code when a process exits with an error code
 type ExitError struct {
 	Status int
 }

+ 0 - 38
vendor/github.com/containerd/go-runc/runc_unix.go

@@ -1,38 +0,0 @@
-//+build !windows
-
-/*
-   Copyright The containerd Authors.
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-*/
-
-package runc
-
-import (
-	"golang.org/x/sys/unix"
-)
-
-// Runc is the client to the runc cli
-type Runc struct {
-	//If command is empty, DefaultCommand is used
-	Command       string
-	Root          string
-	Debug         bool
-	Log           string
-	LogFormat     Format
-	PdeathSignal  unix.Signal
-	Setpgid       bool
-	Criu          string
-	SystemdCgroup bool
-	Rootless      *bool // nil stands for "auto"
-}

+ 0 - 31
vendor/github.com/containerd/go-runc/runc_windows.go

@@ -1,31 +0,0 @@
-/*
-   Copyright The containerd Authors.
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-*/
-
-package runc
-
-// Runc is the client to the runc cli
-type Runc struct {
-	//If command is empty, DefaultCommand is used
-	Command       string
-	Root          string
-	Debug         bool
-	Log           string
-	LogFormat     Format
-	Setpgid       bool
-	Criu          string
-	SystemdCgroup bool
-	Rootless      *bool // nil stands for "auto"
-}

+ 2 - 14
vendor/github.com/containerd/go-runc/utils.go

@@ -18,34 +18,22 @@ package runc
 
 import (
 	"bytes"
-	"io/ioutil"
+	"os"
 	"strconv"
 	"strings"
 	"sync"
-	"syscall"
 )
 
 // ReadPidFile reads the pid file at the provided path and returns
 // the pid or an error if the read and conversion is unsuccessful
 func ReadPidFile(path string) (int, error) {
-	data, err := ioutil.ReadFile(path)
+	data, err := os.ReadFile(path)
 	if err != nil {
 		return -1, err
 	}
 	return strconv.Atoi(string(data))
 }
 
-const exitSignalOffset = 128
-
-// exitStatus returns the correct exit status for a process based on if it
-// was signaled or exited cleanly
-func exitStatus(status syscall.WaitStatus) int {
-	if status.Signaled() {
-		return exitSignalOffset + int(status.Signal())
-	}
-	return status.ExitStatus()
-}
-
 var bytesBufferPool = sync.Pool{
 	New: func() interface{} {
 		return bytes.NewBuffer(nil)

+ 125 - 0
vendor/github.com/opencontainers/runtime-spec/specs-go/features/features.go

@@ -0,0 +1,125 @@
+// Package features provides the Features struct.
+package features
+
+// Features represents the supported features of the runtime.
+type Features struct {
+	// OCIVersionMin is the minimum OCI Runtime Spec version recognized by the runtime, e.g., "1.0.0".
+	OCIVersionMin string `json:"ociVersionMin,omitempty"`
+
+	// OCIVersionMax is the maximum OCI Runtime Spec version recognized by the runtime, e.g., "1.0.2-dev".
+	OCIVersionMax string `json:"ociVersionMax,omitempty"`
+
+	// Hooks is the list of the recognized hook names, e.g., "createRuntime".
+	// Nil value means "unknown", not "no support for any hook".
+	Hooks []string `json:"hooks,omitempty"`
+
+	// MountOptions is the list of the recognized mount options, e.g., "ro".
+	// Nil value means "unknown", not "no support for any mount option".
+	// This list does not contain filesystem-specific options passed to mount(2) syscall as (const void *).
+	MountOptions []string `json:"mountOptions,omitempty"`
+
+	// Linux is specific to Linux.
+	Linux *Linux `json:"linux,omitempty"`
+
+	// Annotations contains implementation-specific annotation strings,
+	// such as the implementation version, and third-party extensions.
+	Annotations map[string]string `json:"annotations,omitempty"`
+}
+
+// Linux is specific to Linux.
+type Linux struct {
+	// Namespaces is the list of the recognized namespaces, e.g., "mount".
+	// Nil value means "unknown", not "no support for any namespace".
+	Namespaces []string `json:"namespaces,omitempty"`
+
+	// Capabilities is the list of the recognized capabilities , e.g., "CAP_SYS_ADMIN".
+	// Nil value means "unknown", not "no support for any capability".
+	Capabilities []string `json:"capabilities,omitempty"`
+
+	Cgroup   *Cgroup   `json:"cgroup,omitempty"`
+	Seccomp  *Seccomp  `json:"seccomp,omitempty"`
+	Apparmor *Apparmor `json:"apparmor,omitempty"`
+	Selinux  *Selinux  `json:"selinux,omitempty"`
+	IntelRdt *IntelRdt `json:"intelRdt,omitempty"`
+}
+
+// Cgroup represents the "cgroup" field.
+type Cgroup struct {
+	// V1 represents whether Cgroup v1 support is compiled in.
+	// Unrelated to whether the host uses cgroup v1 or not.
+	// Nil value means "unknown", not "false".
+	V1 *bool `json:"v1,omitempty"`
+
+	// V2 represents whether Cgroup v2 support is compiled in.
+	// Unrelated to whether the host uses cgroup v2 or not.
+	// Nil value means "unknown", not "false".
+	V2 *bool `json:"v2,omitempty"`
+
+	// Systemd represents whether systemd-cgroup support is compiled in.
+	// Unrelated to whether the host uses systemd or not.
+	// Nil value means "unknown", not "false".
+	Systemd *bool `json:"systemd,omitempty"`
+
+	// SystemdUser represents whether user-scoped systemd-cgroup support is compiled in.
+	// Unrelated to whether the host uses systemd or not.
+	// Nil value means "unknown", not "false".
+	SystemdUser *bool `json:"systemdUser,omitempty"`
+
+	// Rdma represents whether RDMA cgroup support is compiled in.
+	// Unrelated to whether the host supports RDMA or not.
+	// Nil value means "unknown", not "false".
+	Rdma *bool `json:"rdma,omitempty"`
+}
+
+// Seccomp represents the "seccomp" field.
+type Seccomp struct {
+	// Enabled is true if seccomp support is compiled in.
+	// Nil value means "unknown", not "false".
+	Enabled *bool `json:"enabled,omitempty"`
+
+	// Actions is the list of the recognized actions, e.g., "SCMP_ACT_NOTIFY".
+	// Nil value means "unknown", not "no support for any action".
+	Actions []string `json:"actions,omitempty"`
+
+	// Operators is the list of the recognized operators, e.g., "SCMP_CMP_NE".
+	// Nil value means "unknown", not "no support for any operator".
+	Operators []string `json:"operators,omitempty"`
+
+	// Archs is the list of the recognized archs, e.g., "SCMP_ARCH_X86_64".
+	// Nil value means "unknown", not "no support for any arch".
+	Archs []string `json:"archs,omitempty"`
+
+	// KnownFlags is the list of the recognized filter flags, e.g., "SECCOMP_FILTER_FLAG_LOG".
+	// Nil value means "unknown", not "no flags are recognized".
+	KnownFlags []string `json:"knownFlags,omitempty"`
+
+	// SupportedFlags is the list of the supported filter flags, e.g., "SECCOMP_FILTER_FLAG_LOG".
+	// This list may be a subset of KnownFlags due to some flags
+	// not supported by the current kernel and/or libseccomp.
+	// Nil value means "unknown", not "no flags are supported".
+	SupportedFlags []string `json:"supportedFlags,omitempty"`
+}
+
+// Apparmor represents the "apparmor" field.
+type Apparmor struct {
+	// Enabled is true if AppArmor support is compiled in.
+	// Unrelated to whether the host supports AppArmor or not.
+	// Nil value means "unknown", not "false".
+	Enabled *bool `json:"enabled,omitempty"`
+}
+
+// Selinux represents the "selinux" field.
+type Selinux struct {
+	// Enabled is true if SELinux support is compiled in.
+	// Unrelated to whether the host supports SELinux or not.
+	// Nil value means "unknown", not "false".
+	Enabled *bool `json:"enabled,omitempty"`
+}
+
+// IntelRdt represents the "intelRdt" field.
+type IntelRdt struct {
+	// Enabled is true if Intel RDT support is compiled in.
+	// Unrelated to whether the host supports Intel RDT or not.
+	// Nil value means "unknown", not "false".
+	Enabled *bool `json:"enabled,omitempty"`
+}

+ 3 - 2
vendor/modules.txt

@@ -319,8 +319,8 @@ github.com/containerd/fifo
 # github.com/containerd/go-cni v1.1.6
 ## explicit; go 1.17
 github.com/containerd/go-cni
-# github.com/containerd/go-runc v1.0.0
-## explicit; go 1.13
+# github.com/containerd/go-runc v1.1.0
+## explicit; go 1.18
 github.com/containerd/go-runc
 # github.com/containerd/nydus-snapshotter v0.3.1
 ## explicit; go 1.17
@@ -860,6 +860,7 @@ github.com/opencontainers/runc/libcontainer/userns
 # github.com/opencontainers/runtime-spec v1.1.0-rc.2
 ## explicit
 github.com/opencontainers/runtime-spec/specs-go
+github.com/opencontainers/runtime-spec/specs-go/features
 # github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626
 ## explicit; go 1.16
 github.com/opencontainers/runtime-tools/generate