Merge pull request #45620 from thaJeztah/24.0_backport_update_go_runc_v1.1.0
[24.0 backport] vendor: github.com/containerd/go-runc v1.1.0
diff --git a/vendor.mod b/vendor.mod
index 44d53f8..1885aee 100644
--- a/vendor.mod
+++ b/vendor.mod
@@ -118,7 +118,7 @@
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
diff --git a/vendor.sum b/vendor.sum
index 2d78b13..43c80d2 100644
--- a/vendor.sum
+++ b/vendor.sum
@@ -397,8 +397,9 @@
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=
diff --git a/vendor/github.com/containerd/go-runc/.golangci.yml b/vendor/github.com/containerd/go-runc/.golangci.yml
new file mode 100644
index 0000000..240eaed
--- /dev/null
+++ b/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
diff --git a/vendor/github.com/containerd/go-runc/.travis.yml b/vendor/github.com/containerd/go-runc/.travis.yml
deleted file mode 100644
index 724ee09..0000000
--- a/vendor/github.com/containerd/go-runc/.travis.yml
+++ /dev/null
@@ -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)
diff --git a/vendor/github.com/containerd/go-runc/README.md b/vendor/github.com/containerd/go-runc/README.md
index c899bdd..4262c62 100644
--- a/vendor/github.com/containerd/go-runc/README.md
+++ b/vendor/github.com/containerd/go-runc/README.md
@@ -1,7 +1,7 @@
# go-runc
-[](https://travis-ci.org/containerd/go-runc)
-[](https://codecov.io/gh/containerd/go-runc)
+[](https://github.com/containerd/go-runc/actions?query=workflow%3ACI)
+[](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 @@
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.
diff --git a/vendor/github.com/containerd/go-runc/command_other.go b/vendor/github.com/containerd/go-runc/command_other.go
index b8fd4b8..a4adbe1 100644
--- a/vendor/github.com/containerd/go-runc/command_other.go
+++ b/vendor/github.com/containerd/go-runc/command_other.go
@@ -1,4 +1,4 @@
-// +build !linux
+//go:build !linux
/*
Copyright The containerd Authors.
diff --git a/vendor/github.com/containerd/go-runc/console.go b/vendor/github.com/containerd/go-runc/console.go
index ff223e4..e8dc862 100644
--- a/vendor/github.com/containerd/go-runc/console.go
+++ b/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 @@
import (
"fmt"
- "io/ioutil"
"net"
"os"
"path/filepath"
@@ -53,7 +52,7 @@
// 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 @@
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 @@
// 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)
diff --git a/vendor/github.com/containerd/go-runc/events.go b/vendor/github.com/containerd/go-runc/events.go
index d610aeb..6584c49 100644
--- a/vendor/github.com/containerd/go-runc/events.go
+++ b/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 @@
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 @@
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 @@
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 @@
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 @@
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"`
diff --git a/vendor/github.com/containerd/go-runc/io.go b/vendor/github.com/containerd/go-runc/io.go
index 6cf0410..3560c69 100644
--- a/vendor/github.com/containerd/go-runc/io.go
+++ b/vendor/github.com/containerd/go-runc/io.go
@@ -22,6 +22,7 @@
"os/exec"
)
+// IO is the terminal IO interface
type IO interface {
io.Closer
Stdin() io.WriteCloser
@@ -30,6 +31,7 @@
Set(*exec.Cmd)
}
+// StartCloser is an interface to handle IO closure after start
type StartCloser interface {
CloseAfterStart() error
}
@@ -76,6 +78,12 @@
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 @@
}
}
+// 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
diff --git a/vendor/github.com/containerd/go-runc/io_unix.go b/vendor/github.com/containerd/go-runc/io_unix.go
index ccf1dd4..83e3667 100644
--- a/vendor/github.com/containerd/go-runc/io_unix.go
+++ b/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 @@
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 @@
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 @@
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)
}
}
}
diff --git a/vendor/github.com/containerd/go-runc/io_windows.go b/vendor/github.com/containerd/go-runc/io_windows.go
index fc56ac4..a433f40 100644
--- a/vendor/github.com/containerd/go-runc/io_windows.go
+++ b/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")
}
diff --git a/vendor/github.com/containerd/go-runc/monitor.go b/vendor/github.com/containerd/go-runc/monitor.go
index ff06a3f..b9938ad 100644
--- a/vendor/github.com/containerd/go-runc/monitor.go
+++ b/vendor/github.com/containerd/go-runc/monitor.go
@@ -18,32 +18,37 @@
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 @@
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
diff --git a/vendor/github.com/containerd/go-runc/runc.go b/vendor/github.com/containerd/go-runc/runc.go
index f5f03ae..61646df 100644
--- a/vendor/github.com/containerd/go-runc/runc.go
+++ b/vendor/github.com/containerd/go-runc/runc.go
@@ -23,21 +23,22 @@
"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 @@
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 @@
// 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 @@
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 @@
NoNewKeyring bool
ExtraFiles []*os.File
Started chan<- int
+ ExtraArgs []string
}
func (o *CreateOpts) args() (out []string, err error) {
@@ -121,38 +163,50 @@
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 @@
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 @@
}
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 @@
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 @@
// 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 @@
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 @@
// 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 @@
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 @@
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 @@
// 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 @@
// 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 @@
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 @@
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 @@
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 @@
return r.runOrError(cmd)
}
+// RestoreOpts holds the options for performing a criu restore using runc
type RestoreOpts struct {
CheckpointOpts
IO
@@ -544,6 +626,7 @@
NoSubreaper bool
NoPivot bool
ConsoleSocket ConsoleSocket
+ ExtraArgs []string
}
func (o *RestoreOpts) args() ([]string, error) {
@@ -567,6 +650,9 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
// 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 @@
// <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 @@
}
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 @@
// 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 @@
return b, err
}
+// ExitError holds the status return code when a process exits with an error code
type ExitError struct {
Status int
}
diff --git a/vendor/github.com/containerd/go-runc/runc_unix.go b/vendor/github.com/containerd/go-runc/runc_unix.go
deleted file mode 100644
index 548ffd6..0000000
--- a/vendor/github.com/containerd/go-runc/runc_unix.go
+++ /dev/null
@@ -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"
-}
diff --git a/vendor/github.com/containerd/go-runc/runc_windows.go b/vendor/github.com/containerd/go-runc/runc_windows.go
deleted file mode 100644
index c5873de..0000000
--- a/vendor/github.com/containerd/go-runc/runc_windows.go
+++ /dev/null
@@ -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"
-}
diff --git a/vendor/github.com/containerd/go-runc/utils.go b/vendor/github.com/containerd/go-runc/utils.go
index 948b633..4f39f6e 100644
--- a/vendor/github.com/containerd/go-runc/utils.go
+++ b/vendor/github.com/containerd/go-runc/utils.go
@@ -18,34 +18,22 @@
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)
diff --git a/vendor/github.com/opencontainers/runtime-spec/specs-go/features/features.go b/vendor/github.com/opencontainers/runtime-spec/specs-go/features/features.go
new file mode 100644
index 0000000..230e88f
--- /dev/null
+++ b/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"`
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index d8e17fb..e5e1446 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -311,8 +311,8 @@
# 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
@@ -849,6 +849,7 @@
# 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/selinux v1.11.0
## explicit; go 1.19
github.com/opencontainers/selinux/go-selinux