Merge pull request #1741 from coryb/runc-exiterror

update go-runc  module, use runc.ExitError for container exec status
v0.8
Akihiro Suda 2020-10-20 17:14:34 +09:00 committed by GitHub
commit 48991bf6c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 205 additions and 104 deletions

View File

@ -271,9 +271,8 @@ func testClientGatewayContainerCancelOnRelease(t *testing.T, sb integration.Sand
// We are mimicing: `echo testing | cat | cat > /tmp/foo && cat /tmp/foo`
func testClientGatewayContainerExecPipe(t *testing.T, sb integration.Sandbox) {
if sb.Rootless() {
// TODO fix this
// We get `panic: cannot statfs cgroup root` from runc when when running
// this test with runc-rootless, no idea why.
// TODO remove when https://github.com/opencontainers/runc/pull/2634
// is merged and released
t.Skip("Skipping oci-rootless for cgroup error")
}
requiresLinux(t)
@ -467,9 +466,8 @@ func testClientGatewayContainerPID1Fail(t *testing.T, sb integration.Sandbox) {
// via `Exec` are shutdown when the primary pid1 process exits
func testClientGatewayContainerPID1Exit(t *testing.T, sb integration.Sandbox) {
if sb.Rootless() {
// TODO fix this
// We get `panic: cannot statfs cgroup root` when running this test
// with runc-rootless
// TODO remove when https://github.com/opencontainers/runc/pull/2634
// is merged and released
t.Skip("Skipping runc-rootless for cgroup error")
}
requiresLinux(t)
@ -535,10 +533,9 @@ func testClientGatewayContainerPID1Exit(t *testing.T, sb integration.Sandbox) {
}
_, err = c.Build(ctx, SolveOpt{}, product, b, nil)
// pid2 should error with `buildkit-runc did not terminate successfully` on runc or
// `exit code: 137` (ie sigkill) on containerd
require.Error(t, err)
require.Regexp(t, "exit code: 137|buildkit-runc did not terminate successfully", err.Error())
// `exit code: 137` (ie sigkill)
require.Regexp(t, "exit code: 137", err.Error())
checkAllReleasable(t, c, sb, true)
}
@ -547,9 +544,8 @@ func testClientGatewayContainerPID1Exit(t *testing.T, sb integration.Sandbox) {
// llb.States
func testClientGatewayContainerMounts(t *testing.T, sb integration.Sandbox) {
if sb.Rootless() {
// TODO fix this
// We get `panic: cannot statfs cgroup root` when running this test
// with runc-rootless
// TODO remove when https://github.com/opencontainers/runc/pull/2634
// is merged and released
t.Skip("Skipping runc-rootless for cgroup error")
}
requiresLinux(t)
@ -864,9 +860,8 @@ func (p *testPrompt) wait(msg string) string {
// executor.Exec (secondary process)
func testClientGatewayContainerExecTty(t *testing.T, sb integration.Sandbox) {
if sb.Rootless() {
// TODO fix this
// We get `panic: cannot statfs cgroup root` when running this test
// with runc-rootless
// TODO remove when https://github.com/opencontainers/runc/pull/2634
// is merged and released
t.Skip("Skipping runc-rootless for cgroup error")
}
requiresLinux(t)
@ -937,12 +932,17 @@ func testClientGatewayContainerExecTty(t *testing.T, sb integration.Sandbox) {
prompt.SendExpect("ttysize", "100 60")
prompt.SendExit(99)
return &client.Result{}, pid2.Wait()
err = pid2.Wait()
var exitError *errdefs.ExitError
require.True(t, errors.As(err, &exitError))
require.Equal(t, uint32(99), exitError.ExitCode)
return &client.Result{}, err
}
_, err = c.Build(ctx, SolveOpt{}, product, b, nil)
require.Error(t, err)
require.Regexp(t, "exit code: 99|runc did not terminate successfully", err.Error())
require.Regexp(t, "exit code: 99", err.Error())
inputW.Close()
inputR.Close()

View File

@ -12,6 +12,7 @@ import (
"syscall"
"time"
"github.com/containerd/containerd"
"github.com/containerd/containerd/mount"
containerdoci "github.com/containerd/containerd/oci"
"github.com/containerd/continuity/fs"
@ -103,15 +104,16 @@ func New(opt Opt, networkProviders map[pb.NetMode]network.Provider) (executor.Ex
os.RemoveAll(filepath.Join(root, "resolv.conf"))
runtime := &runc.Runc{
Command: cmd,
Log: filepath.Join(root, "runc-log.json"),
LogFormat: runc.JSON,
PdeathSignal: syscall.SIGKILL, // this can still leak the process
Setpgid: true,
Command: cmd,
Log: filepath.Join(root, "runc-log.json"),
LogFormat: runc.JSON,
Setpgid: true,
// we don't execute runc with --rootless=(true|false) explicitly,
// so as to support non-runc runtimes
}
updateRuncFieldsForHostOS(runtime)
w := &runcExecutor{
runc: runtime,
root: root,
@ -324,21 +326,29 @@ func (w *runcExecutor) Run(ctx context.Context, id string, root cache.Mountable,
})
}
status, err := w.run(runCtx, id, bundle, process)
err = w.run(runCtx, id, bundle, process)
close(ended)
return exitError(ctx, err)
}
if status != 0 || err != nil {
func exitError(ctx context.Context, err error) error {
if err != nil {
exitErr := &errdefs.ExitError{
ExitCode: uint32(status),
ExitCode: containerd.UnknownExitStatus,
Err: err,
}
err = exitErr
var runcExitError *runc.ExitError
if errors.As(err, &runcExitError) {
exitErr = &errdefs.ExitError{
ExitCode: uint32(runcExitError.Status),
}
}
select {
case <-ctx.Done():
exitErr.Err = errors.Wrapf(ctx.Err(), exitErr.Error())
return exitErr
default:
return stack.Enable(err)
return stack.Enable(exitErr)
}
}
@ -408,14 +418,8 @@ func (w *runcExecutor) Exec(ctx context.Context, id string, process executor.Pro
spec.Process.Env = process.Meta.Env
}
status, err := w.exec(ctx, id, state.Bundle, spec.Process, process)
if status == 0 && err == nil {
return nil
}
return &errdefs.ExitError{
ExitCode: uint32(status),
Err: err,
}
err = w.exec(ctx, id, state.Bundle, spec.Process, process)
return exitError(ctx, err)
}
type forwardIO struct {

View File

@ -4,9 +4,7 @@ package runcexecutor
import (
"context"
"os/exec"
"github.com/containerd/containerd"
runc "github.com/containerd/go-runc"
"github.com/moby/buildkit/executor"
"github.com/opencontainers/runtime-spec/specs-go"
@ -15,30 +13,24 @@ import (
var unsupportedConsoleError = errors.New("tty for runc is only supported on linux")
func (w *runcExecutor) run(ctx context.Context, id, bundle string, process executor.ProcessInfo) (int, error) {
func updateRuncFieldsForHostOS(runtime *runc.Runc) {}
func (w *runcExecutor) run(ctx context.Context, id, bundle string, process executor.ProcessInfo) error {
if process.Meta.Tty {
return 0, unsupportedConsoleError
return unsupportedConsoleError
}
return w.runc.Run(ctx, id, bundle, &runc.CreateOpts{
_, err := w.runc.Run(ctx, id, bundle, &runc.CreateOpts{
IO: &forwardIO{stdin: process.Stdin, stdout: process.Stdout, stderr: process.Stderr},
NoPivot: w.noPivot,
})
return err
}
func (w *runcExecutor) exec(ctx context.Context, id, bundle string, specsProcess *specs.Process, process executor.ProcessInfo) (int, error) {
func (w *runcExecutor) exec(ctx context.Context, id, bundle string, specsProcess *specs.Process, process executor.ProcessInfo) error {
if process.Meta.Tty {
return 0, unsupportedConsoleError
return unsupportedConsoleError
}
err := w.runc.Exec(ctx, id, *specsProcess, &runc.ExecOpts{
return w.runc.Exec(ctx, id, *specsProcess, &runc.ExecOpts{
IO: &forwardIO{stdin: process.Stdin, stdout: process.Stdout, stderr: process.Stderr},
})
var exitError *exec.ExitError
if errors.As(err, &exitError) {
return exitError.ExitCode(), err
}
if err != nil {
return containerd.UnknownExitStatus, err
}
return 0, nil
}

View File

@ -7,14 +7,12 @@ import (
"io"
"io/ioutil"
"os"
"os/exec"
"strconv"
"strings"
"syscall"
"time"
"github.com/containerd/console"
"github.com/containerd/containerd"
runc "github.com/containerd/go-runc"
"github.com/docker/docker/pkg/signal"
"github.com/moby/buildkit/executor"
@ -24,42 +22,40 @@ import (
"golang.org/x/sync/errgroup"
)
func (w *runcExecutor) run(ctx context.Context, id, bundle string, process executor.ProcessInfo) (int, error) {
return w.callWithIO(ctx, id, bundle, process, func(ctx context.Context, pidfile string, io runc.IO) (int, error) {
return w.runc.Run(ctx, id, bundle, &runc.CreateOpts{
func updateRuncFieldsForHostOS(runtime *runc.Runc) {
// PdeathSignal only supported on unix platforms
runtime.PdeathSignal = syscall.SIGKILL // this can still leak the process
}
func (w *runcExecutor) run(ctx context.Context, id, bundle string, process executor.ProcessInfo) error {
return w.callWithIO(ctx, id, bundle, process, func(ctx context.Context, pidfile string, io runc.IO) error {
_, err := w.runc.Run(ctx, id, bundle, &runc.CreateOpts{
NoPivot: w.noPivot,
PidFile: pidfile,
IO: io,
})
return err
})
}
func (w *runcExecutor) exec(ctx context.Context, id, bundle string, specsProcess *specs.Process, process executor.ProcessInfo) (int, error) {
return w.callWithIO(ctx, id, bundle, process, func(ctx context.Context, pidfile string, io runc.IO) (int, error) {
err := w.runc.Exec(ctx, id, *specsProcess, &runc.ExecOpts{
func (w *runcExecutor) exec(ctx context.Context, id, bundle string, specsProcess *specs.Process, process executor.ProcessInfo) error {
return w.callWithIO(ctx, id, bundle, process, func(ctx context.Context, pidfile string, io runc.IO) error {
return w.runc.Exec(ctx, id, *specsProcess, &runc.ExecOpts{
PidFile: pidfile,
IO: io,
})
var exitError *exec.ExitError
if errors.As(err, &exitError) {
return exitError.ExitCode(), err
}
if err != nil {
return containerd.UnknownExitStatus, err
}
return 0, nil
})
}
type runcCall func(ctx context.Context, pidfile string, io runc.IO) (int, error)
type runcCall func(ctx context.Context, pidfile string, io runc.IO) error
func (w *runcExecutor) callWithIO(ctx context.Context, id, bundle string, process executor.ProcessInfo, call runcCall) (int, error) {
func (w *runcExecutor) callWithIO(ctx context.Context, id, bundle string, process executor.ProcessInfo, call runcCall) error {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
pidfile, err := ioutil.TempFile(bundle, "*.pid")
if err != nil {
return containerd.UnknownExitStatus, errors.Wrap(err, "failed to create pidfile")
return errors.Wrap(err, "failed to create pidfile")
}
defer os.Remove(pidfile.Name())
pidfile.Close()
@ -70,13 +66,13 @@ func (w *runcExecutor) callWithIO(ctx context.Context, id, bundle string, proces
ptm, ptsName, err := console.NewPty()
if err != nil {
return containerd.UnknownExitStatus, err
return err
}
pts, err := os.OpenFile(ptsName, os.O_RDWR|syscall.O_NOCTTY, 0)
if err != nil {
ptm.Close()
return containerd.UnknownExitStatus, err
return err
}
eg, ctx := errgroup.WithContext(ctx)

2
go.mod
View File

@ -12,7 +12,7 @@ require (
github.com/containerd/containerd v1.4.1-0.20200903181227-d4e78200d6da
github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe
github.com/containerd/go-cni v1.0.1
github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328
github.com/containerd/go-runc v0.0.0-20201017060547-8c4be61c2e34
github.com/containerd/stargz-snapshotter v0.0.0-20200903042824-2ee75e91f8f9
github.com/containerd/typeurl v1.0.1
github.com/coreos/go-systemd/v22 v22.1.0

2
go.sum
View File

@ -127,6 +127,8 @@ github.com/containerd/go-cni v1.0.1/go.mod h1:+vUpYxKvAF72G9i1WoDOiPGRtQpqsNW/ZH
github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328 h1:PRTagVMbJcCezLcHXe8UJvR1oBzp2lG3CEumeFOLOds=
github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g=
github.com/containerd/go-runc v0.0.0-20201017060547-8c4be61c2e34 h1:jFRg/hwx0DPpcg23MNusAppCDJa5nndN3/RAxSblN58=
github.com/containerd/go-runc v0.0.0-20201017060547-8c4be61c2e34/go.mod h1:1CDPys/h0SMZoki7dv3bPQ1wJWnmaeZIO026WPts2xM=
github.com/containerd/stargz-snapshotter v0.0.0-20200903042824-2ee75e91f8f9 h1:JEcj3rNCg0Ho5t9kiOa4LV/vaNXbRQ9l2PIRzz2LWCQ=
github.com/containerd/stargz-snapshotter v0.0.0-20200903042824-2ee75e91f8f9/go.mod h1:f+gZLtYcuNQWxucWyfVEQXSBoGbXNpQ76+XWVMgp+34=
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=

View File

@ -1,7 +1,8 @@
language: go
go:
- 1.12.x
- 1.13.x
- 1.14.x
- 1.15.x
install:
- go get -t ./...

View File

@ -6,5 +6,6 @@ require (
github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e
github.com/opencontainers/runtime-spec v1.0.1
github.com/pkg/errors v0.8.1
github.com/sirupsen/logrus v1.6.0
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449
)

View File

@ -1,9 +1,16 @@
github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e h1:GdiIYd8ZDOrT++e1NjhSD4rGt9zaJukHm4rt5F4mRQc=
github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/opencontainers/runtime-spec v1.0.1 h1:wY4pOY8fBdSIvs9+IDHC55thBuEulhzfSgKeC1yFvzQ=
github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449 h1:gSbV7h1NRL2G1xTg/owz62CST1oJBmxy4QpMMregXVQ=
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

View File

@ -20,7 +20,9 @@ package runc
import (
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
"runtime"
)
// NewPipeIO creates pipe pairs to be used with runc
@ -47,7 +49,13 @@ func NewPipeIO(uid, gid int, opts ...IOOpt) (i IO, err error) {
}
pipes = append(pipes, stdin)
if err = unix.Fchown(int(stdin.r.Fd()), uid, gid); err != nil {
return nil, errors.Wrap(err, "failed to chown stdin")
// TODO: revert with proper darwin solution, skipping for now
// as darwin chown is returning EINVAL on anonymous pipe
if runtime.GOOS == "darwin" {
logrus.WithError(err).Debug("failed to chown stdin, ignored")
} else {
return nil, errors.Wrap(err, "failed to chown stdin")
}
}
}
if option.OpenStdout {
@ -56,7 +64,13 @@ func NewPipeIO(uid, gid int, opts ...IOOpt) (i IO, err error) {
}
pipes = append(pipes, stdout)
if err = unix.Fchown(int(stdout.w.Fd()), uid, gid); err != nil {
return nil, errors.Wrap(err, "failed to chown stdout")
// TODO: revert with proper darwin solution, skipping for now
// as darwin chown is returning EINVAL on anonymous pipe
if runtime.GOOS == "darwin" {
logrus.WithError(err).Debug("failed to chown stdout, ignored")
} else {
return nil, errors.Wrap(err, "failed to chown stdout")
}
}
}
if option.OpenStderr {
@ -65,7 +79,13 @@ func NewPipeIO(uid, gid int, opts ...IOOpt) (i IO, err error) {
}
pipes = append(pipes, stderr)
if err = unix.Fchown(int(stderr.w.Fd()), uid, gid); err != nil {
return nil, errors.Wrap(err, "failed to chown stderr")
// TODO: revert with proper darwin solution, skipping for now
// as darwin chown is returning EINVAL on anonymous pipe
if runtime.GOOS == "darwin" {
logrus.WithError(err).Debug("failed to chown stderr, ignored")
} else {
return nil, errors.Wrap(err, "failed to chown stderr")
}
}
}
return &pipeIO{

View File

@ -29,7 +29,6 @@ import (
"path/filepath"
"strconv"
"strings"
"syscall"
"time"
specs "github.com/opencontainers/runtime-spec/specs-go"
@ -55,21 +54,6 @@ const (
DefaultCommand = "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
PdeathSignal syscall.Signal
Setpgid bool
Criu string
SystemdCgroup bool
Rootless *bool // nil stands for "auto"
}
// 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)
@ -176,7 +160,7 @@ func (r *Runc) Create(context context.Context, id, bundle string, opts *CreateOp
}
status, err := Monitor.Wait(cmd, ec)
if err == nil && status != 0 {
err = fmt.Errorf("%s did not terminate successfully", cmd.Args[0])
err = fmt.Errorf("%s did not terminate successfully: %w", cmd.Args[0], &ExitError{status})
}
return err
}
@ -210,7 +194,7 @@ func (o *ExecOpts) args() (out []string, err error) {
return out, nil
}
// Exec executres and additional process inside the container based on a full
// 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 {
f, err := ioutil.TempFile(os.Getenv("XDG_RUNTIME_DIR"), "runc-process")
@ -239,7 +223,7 @@ func (r *Runc) Exec(context context.Context, id string, spec specs.Process, opts
data, err := cmdOutput(cmd, true)
defer putBuf(data)
if err != nil {
return fmt.Errorf("%s: %s", err, data.String())
return fmt.Errorf("%w: %s", err, data.String())
}
return nil
}
@ -256,7 +240,7 @@ func (r *Runc) Exec(context context.Context, id string, spec specs.Process, opts
}
status, err := Monitor.Wait(cmd, ec)
if err == nil && status != 0 {
err = fmt.Errorf("%s did not terminate successfully", cmd.Args[0])
err = fmt.Errorf("%s did not terminate successfully: %w", cmd.Args[0], &ExitError{status})
}
return err
}
@ -282,7 +266,7 @@ func (r *Runc) Run(context context.Context, id, bundle string, opts *CreateOpts)
}
status, err := Monitor.Wait(cmd, ec)
if err == nil && status != 0 {
err = fmt.Errorf("%s did not terminate successfully", cmd.Args[0])
err = fmt.Errorf("%s did not terminate successfully: %w", cmd.Args[0], &ExitError{status})
}
return status, err
}
@ -452,6 +436,10 @@ type CheckpointOpts struct {
// EmptyNamespaces creates a namespace for the container but does not save its properties
// Provide the namespaces you wish to be checkpointed without their settings on restore
EmptyNamespaces []string
// LazyPages uses userfaultfd to lazily restore memory pages
LazyPages bool
// StatusFile is the file criu writes \0 to once lazy-pages is ready
StatusFile *os.File
}
type CgroupMode string
@ -493,6 +481,9 @@ func (o *CheckpointOpts) args() (out []string) {
for _, ns := range o.EmptyNamespaces {
out = append(out, "--empty-ns", ns)
}
if o.LazyPages {
out = append(out, "--lazy-pages")
}
return out
}
@ -511,13 +502,23 @@ func PreDump(args []string) []string {
// Checkpoint allows you to checkpoint a container using criu
func (r *Runc) Checkpoint(context context.Context, id string, opts *CheckpointOpts, actions ...CheckpointAction) error {
args := []string{"checkpoint"}
extraFiles := []*os.File{}
if opts != nil {
args = append(args, opts.args()...)
if opts.StatusFile != nil {
// pass the status file to the child process
extraFiles = []*os.File{opts.StatusFile}
// set status-fd to 3 as this will be the file descriptor
// of the first file passed with cmd.ExtraFiles
args = append(args, "--status-fd", "3")
}
}
for _, a := range actions {
args = a(args)
}
return r.runOrError(r.command(context, append(args, id)...))
cmd := r.command(context, append(args, id)...)
cmd.ExtraFiles = extraFiles
return r.runOrError(cmd)
}
type RestoreOpts struct {
@ -583,7 +584,7 @@ func (r *Runc) Restore(context context.Context, id, bundle string, opts *Restore
}
status, err := Monitor.Wait(cmd, ec)
if err == nil && status != 0 {
err = fmt.Errorf("%s did not terminate successfully", cmd.Args[0])
err = fmt.Errorf("%s did not terminate successfully: %w", cmd.Args[0], &ExitError{status})
}
return status, err
}
@ -680,7 +681,7 @@ func (r *Runc) runOrError(cmd *exec.Cmd) error {
}
status, err := Monitor.Wait(cmd, ec)
if err == nil && status != 0 {
err = fmt.Errorf("%s did not terminate successfully", cmd.Args[0])
err = fmt.Errorf("%s did not terminate successfully: %w", cmd.Args[0], &ExitError{status})
}
return err
}
@ -708,8 +709,16 @@ func cmdOutput(cmd *exec.Cmd, combined bool) (*bytes.Buffer, error) {
status, err := Monitor.Wait(cmd, ec)
if err == nil && status != 0 {
err = fmt.Errorf("%s did not terminate successfully", cmd.Args[0])
err = fmt.Errorf("%s did not terminate successfully: %w", cmd.Args[0], &ExitError{status})
}
return b, err
}
type ExitError struct {
Status int
}
func (e *ExitError) Error() string {
return fmt.Sprintf("exit status %d", e.Status)
}

38
vendor/github.com/containerd/go-runc/runc_unix.go generated vendored Normal file
View File

@ -0,0 +1,38 @@
//+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"
}

31
vendor/github.com/containerd/go-runc/runc_windows.go generated vendored Normal file
View File

@ -0,0 +1,31 @@
/*
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
vendor/modules.txt vendored
View File

@ -117,7 +117,7 @@ github.com/containerd/continuity/sysx
github.com/containerd/fifo
# github.com/containerd/go-cni v1.0.1
github.com/containerd/go-cni
# github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328
# github.com/containerd/go-runc v0.0.0-20201017060547-8c4be61c2e34
github.com/containerd/go-runc
# github.com/containerd/stargz-snapshotter v0.0.0-20200903042824-2ee75e91f8f9
github.com/containerd/stargz-snapshotter/cache