Upgrade containerd to v1.3.3-k3s1

pull/1323/head
Erik Wilson 2020-01-20 16:17:03 -07:00
parent d8cf1edf65
commit 39d146bb90
25 changed files with 242 additions and 113 deletions

2
go.mod
View File

@ -7,7 +7,7 @@ replace (
github.com/containerd/btrfs => github.com/containerd/btrfs v0.0.0-20181101203652-af5082808c83
github.com/containerd/cgroups => github.com/containerd/cgroups v0.0.0-20190717030353-c4b9ac5c7601
github.com/containerd/console => github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50
github.com/containerd/containerd => github.com/rancher/containerd v1.3.0-k3s.5
github.com/containerd/containerd => github.com/rancher/containerd v1.3.3-k3s1
github.com/containerd/continuity => github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02
github.com/containerd/cri => github.com/rancher/cri v1.3.0-k3s.3
github.com/containerd/fifo => github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c

4
go.sum
View File

@ -705,8 +705,8 @@ github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:
github.com/quobyte/api v0.1.2/go.mod h1:jL7lIHrmqQ7yh05OJ+eEEdHr0u/kmT1Ff9iHd+4H6VI=
github.com/rakelkar/gonetsh v0.0.0-20190719023240-501daadcadf8 h1:83l9gPhYtgxODlZKU0Odq4pQuDcMZEVgAh364+PV3OU=
github.com/rakelkar/gonetsh v0.0.0-20190719023240-501daadcadf8/go.mod h1:4XHkfaUj+URzGO9sohoAgt2V9Y8nIW7fugpu0E6gShk=
github.com/rancher/containerd v1.3.0-k3s.5 h1:r5GheXz59KQpEdYPxRd53vfFhipnQG/g3MI5NkNPDQI=
github.com/rancher/containerd v1.3.0-k3s.5/go.mod h1:ZMfzmqce2Z+QSEqdHMfeJs1TZ/UeJ1aDrazjpQT4ehM=
github.com/rancher/containerd v1.3.3-k3s1 h1:j8NGZdXKsZd2ne0XQg6OBfMJ/NkY/Qri6QhscGrJp2M=
github.com/rancher/containerd v1.3.3-k3s1/go.mod h1:ZMfzmqce2Z+QSEqdHMfeJs1TZ/UeJ1aDrazjpQT4ehM=
github.com/rancher/cri v1.3.0-k3s.3 h1:j/Sq2LMyg6gBn2MS1j5dEudpdL+UYVH7ubbewUCXkS0=
github.com/rancher/cri v1.3.0-k3s.3/go.mod h1:Ht5T1dIKzm+4NExmb7wDVG6qR+j0xeXIjjhCv1d9geY=
github.com/rancher/cri-tools v1.16.1-k3s.1 h1:iporgQ46noE6dtLzq6fWcIO2qjyPZy2m42d2P+UnGJg=

View File

@ -7,12 +7,13 @@ clone_folder: c:\gopath\src\github.com\containerd\containerd
branches:
only:
- master
- /release\/.*/
environment:
GOPATH: C:\gopath
CGO_ENABLED: 1
matrix:
- GO_VERSION: 1.12.12
- GO_VERSION: 1.12.15
before_build:
- choco install -y mingw --version 5.3.0

View File

@ -10,11 +10,11 @@ os:
- linux
go:
- "1.12.12"
- "1.12.15"
env:
- TRAVIS_GOOS=linux TEST_RUNTIME=io.containerd.runc.v1 TRAVIS_CGO_ENABLED=1 TRAVIS_DISTRO=bionic
- TRAVIS_GOOS=linux TEST_RUNTIME=io.containerd.runc.v2 TRAVIS_CGO_ENABLED=1 TRAVIS_DISTRO=bionic
- TRAVIS_GOOS=linux TEST_RUNTIME=io.containerd.runc.v2 TRAVIS_CGO_ENABLED=1 TRAVIS_DISTRO=bionic TRAVIS_RELEASE=yes
- TRAVIS_GOOS=linux TEST_RUNTIME=io.containerd.runtime.v1.linux TRAVIS_CGO_ENABLED=1 TRAVIS_DISTRO=bionic
- TRAVIS_GOOS=darwin TRAVIS_CGO_ENABLED=0
@ -59,9 +59,9 @@ install:
- if [ "$TRAVIS_GOOS" = "linux" ]; then sudo PATH=$PATH GOPATH=$GOPATH script/setup/install-runc ; fi
- if [ "$TRAVIS_GOOS" = "linux" ]; then sudo PATH=$PATH GOPATH=$GOPATH script/setup/install-cni ; fi
- if [ "$TRAVIS_GOOS" = "linux" ]; then sudo PATH=$PATH GOPATH=$GOPATH script/setup/install-critools ; fi
- if [ "$TRAVIS_GOOS" = "linux" ]; then wget https://github.com/checkpoint-restore/criu/archive/v3.12.tar.gz -O /tmp/criu.tar.gz ; fi
- if [ "$TRAVIS_GOOS" = "linux" ]; then wget https://github.com/checkpoint-restore/criu/archive/v3.13.tar.gz -O /tmp/criu.tar.gz ; fi
- if [ "$TRAVIS_GOOS" = "linux" ]; then tar -C /tmp/ -zxf /tmp/criu.tar.gz ; fi
- if [ "$TRAVIS_GOOS" = "linux" ]; then cd /tmp/criu-3.12 && sudo make install-criu ; fi
- if [ "$TRAVIS_GOOS" = "linux" ]; then cd /tmp/criu-3.13 && sudo make install-criu ; fi
- cd $TRAVIS_BUILD_DIR
before_script:
@ -83,9 +83,9 @@ script:
- if [ "$TRAVIS_GOOS" = "linux" ]; then sudo make install ; fi
- if [ "$TRAVIS_GOOS" = "linux" ]; then make coverage ; fi
- if [ "$TRAVIS_GOOS" = "linux" ]; then sudo PATH=$PATH GOPATH=$GOPATH make root-coverage ; fi
- if [ "$TRAVIS_GOOS" = "linux" ]; then sudo PATH=$PATH GOPATH=$GOPATH make integration ; fi
- if [ "$TRAVIS_GOOS" = "linux" ]; then sudo PATH=$PATH GOPATH=$GOPATH make integration EXTRA_TESTFLAGS=-no-criu ; fi
# Run the integration suite a second time. See discussion in github.com/containerd/containerd/pull/1759
- if [ "$TRAVIS_GOOS" = "linux" ]; then sudo PATH=$PATH GOPATH=$GOPATH TESTFLAGS_PARALLEL=1 make integration ; fi
- if [ "$TRAVIS_GOOS" = "linux" ]; then sudo PATH=$PATH GOPATH=$GOPATH TESTFLAGS_PARALLEL=1 make integration EXTRA_TESTFLAGS=-no-criu ; fi
- |
if [ "$TRAVIS_GOOS" = "linux" ]; then
sudo mkdir -p /etc/containerd
@ -107,8 +107,7 @@ after_success:
- bash <(curl -s https://codecov.io/bash) -F linux
before_deploy:
- make release
- if [ "$TRAVIS_GOOS" = "linux" ]; then make cri-release; fi
- if [ "$TRAVIS_RELEASE" = "yes" ]; then make release cri-release; fi
deploy:
- provider: releases

View File

@ -80,6 +80,11 @@ TEST_REQUIRES_ROOT_PACKAGES=$(filter \
done | sort -u) \
)
ifdef SKIPTESTS
PACKAGES:=$(filter-out ${SKIPTESTS},${PACKAGES})
TEST_REQUIRES_ROOT_PACKAGES:=$(filter-out ${SKIPTESTS},${TEST_REQUIRES_ROOT_PACKAGES})
endif
# Project binaries.
COMMANDS=ctr containerd containerd-stress
MANPAGES=ctr.1 containerd.1 containerd-config.1 containerd-config.toml.5
@ -111,7 +116,7 @@ GO_GCFLAGS=$(shell \
BINARIES=$(addprefix bin/,$(COMMANDS))
# Flags passed to `go test`
TESTFLAGS ?= $(TESTFLAGS_RACE)
TESTFLAGS ?= $(TESTFLAGS_RACE) $(EXTRA_TESTFLAGS)
TESTFLAGS_PARALLEL ?= 8
.PHONY: clean all AUTHORS build binaries test integration generate protos checkprotos coverage ci check help install uninstall vendor release mandir install-man genman

View File

@ -42,6 +42,7 @@ var (
registerServiceFlag bool
unregisterServiceFlag bool
runServiceFlag bool
logFileFlag string
kernel32 = windows.NewLazySystemDLL("kernel32.dll")
setStdHandle = kernel32.NewProc("SetStdHandle")
@ -52,6 +53,8 @@ var (
service *handler
)
const defaultServiceName = "containerd"
// serviceFlags returns an array of flags for configuring containerd to run
// as a Windows service under control of SCM.
func serviceFlags() []cli.Flag {
@ -59,7 +62,7 @@ func serviceFlags() []cli.Flag {
cli.StringFlag{
Name: "service-name",
Usage: "Set the Windows service name",
Value: "containerd",
Value: defaultServiceName,
},
cli.BoolFlag{
Name: "register-service",
@ -74,14 +77,18 @@ func serviceFlags() []cli.Flag {
Usage: "",
Hidden: true,
},
cli.StringFlag{
Name: "log-file",
Usage: "Path to the containerd log file",
},
}
}
// applyPlatformFlags applies platform-specific flags.
func applyPlatformFlags(context *cli.Context) {
if s := context.GlobalString("service-name"); s != "" {
serviceNameFlag = s
serviceNameFlag = context.GlobalString("service-name")
if serviceNameFlag == "" {
serviceNameFlag = defaultServiceName
}
for _, v := range []struct {
name string
@ -102,6 +109,7 @@ func applyPlatformFlags(context *cli.Context) {
} {
*v.d = context.GlobalBool(v.name)
}
logFileFlag = context.GlobalString("log-file")
}
type handler struct {
@ -243,7 +251,15 @@ func registerUnregisterService(root string) (bool, error) {
return true, err
}
logrus.SetOutput(ioutil.Discard)
logOutput := ioutil.Discard
if logFileFlag != "" {
f, err := os.OpenFile(logFileFlag, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return true, errors.Wrapf(err, "open log file %q", logFileFlag)
}
logOutput = f
}
logrus.SetOutput(logOutput)
}
return false, nil
}

View File

@ -209,6 +209,8 @@ func (p *parser) field() (string, error) {
return s, nil
case tokenQuoted:
return p.unquote(pos, s, false)
case tokenIllegal:
return "", p.mkerr(pos, p.scanner.err)
}
return "", p.mkerr(pos, "expected field or quoted")
@ -228,6 +230,8 @@ func (p *parser) operator() (operator, error) {
default:
return 0, p.mkerr(pos, "unsupported operator %q", s)
}
case tokenIllegal:
return 0, p.mkerr(pos, p.scanner.err)
}
return 0, p.mkerr(pos, `expected an operator ("=="|"!="|"~=")`)
@ -241,6 +245,8 @@ func (p *parser) value(allowAltQuotes bool) (string, error) {
return s, nil
case tokenQuoted:
return p.unquote(pos, s, allowAltQuotes)
case tokenIllegal:
return "", p.mkerr(pos, p.scanner.err)
}
return "", p.mkerr(pos, "expected value or quoted")

View File

@ -17,7 +17,6 @@
package filters
import (
"fmt"
"unicode"
"unicode/utf8"
)
@ -64,6 +63,7 @@ type scanner struct {
pos int
ppos int // bounds the current rune in the string
value bool
err string
}
func (s *scanner) init(input string) {
@ -82,12 +82,14 @@ func (s *scanner) next() rune {
s.ppos += w
if r == utf8.RuneError {
if w > 0 {
s.error("rune error")
return tokenIllegal
}
return tokenEOF
}
if r == 0 {
s.error("unexpected null")
return tokenIllegal
}
@ -114,7 +116,9 @@ chomp:
case ch == tokenEOF:
case ch == tokenIllegal:
case isQuoteRune(ch):
s.scanQuoted(ch)
if !s.scanQuoted(ch) {
return pos, tokenIllegal, s.input[pos:s.ppos]
}
return pos, tokenQuoted, s.input[pos:s.ppos]
case isSeparatorRune(ch):
s.value = false
@ -172,54 +176,64 @@ func (s *scanner) scanValue() {
}
}
func (s *scanner) scanQuoted(quote rune) {
func (s *scanner) scanQuoted(quote rune) bool {
var illegal bool
ch := s.next() // read character after quote
for ch != quote {
if ch == '\n' || ch < 0 {
s.error("literal not terminated")
return
s.error("quoted literal not terminated")
return false
}
if ch == '\\' {
ch = s.scanEscape(quote)
var legal bool
ch, legal = s.scanEscape(quote)
if !legal {
illegal = true
}
} else {
ch = s.next()
}
}
return !illegal
}
func (s *scanner) scanEscape(quote rune) rune {
ch := s.next() // read character after '/'
func (s *scanner) scanEscape(quote rune) (ch rune, legal bool) {
ch = s.next() // read character after '/'
switch ch {
case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', quote:
// nothing to do
ch = s.next()
legal = true
case '0', '1', '2', '3', '4', '5', '6', '7':
ch = s.scanDigits(ch, 8, 3)
ch, legal = s.scanDigits(ch, 8, 3)
case 'x':
ch = s.scanDigits(s.next(), 16, 2)
ch, legal = s.scanDigits(s.next(), 16, 2)
case 'u':
ch = s.scanDigits(s.next(), 16, 4)
ch, legal = s.scanDigits(s.next(), 16, 4)
case 'U':
ch = s.scanDigits(s.next(), 16, 8)
ch, legal = s.scanDigits(s.next(), 16, 8)
default:
s.error("illegal char escape")
s.error("illegal escape sequence")
}
return ch
return
}
func (s *scanner) scanDigits(ch rune, base, n int) rune {
func (s *scanner) scanDigits(ch rune, base, n int) (rune, bool) {
for n > 0 && digitVal(ch) < base {
ch = s.next()
n--
}
if n > 0 {
s.error("illegal char escape")
s.error("illegal numeric escape sequence")
return ch, false
}
return ch
return ch, true
}
func (s *scanner) error(msg string) {
fmt.Println("error fixme", msg)
if s.err == "" {
s.err = msg
}
}
func digitVal(ch rune) int {

View File

@ -21,6 +21,8 @@ import (
"context"
"os"
"path/filepath"
"runtime"
"strings"
introspectionapi "github.com/containerd/containerd/api/services/introspection/v1"
"github.com/containerd/containerd/archive"
@ -48,6 +50,15 @@ func (c *Client) Install(ctx context.Context, image Image, opts ...InstallOpts)
if err != nil {
return err
}
var binDir, libDir string
if runtime.GOOS == "windows" {
binDir = "Files\\bin"
libDir = "Files\\lib"
} else {
binDir = "bin"
libDir = "lib"
}
for _, layer := range manifest.Layers {
ra, err := cs.ReaderAt(ctx, layer)
if err != nil {
@ -60,9 +71,14 @@ func (c *Client) Install(ctx context.Context, image Image, opts ...InstallOpts)
}
if _, err := archive.Apply(ctx, path, r, archive.WithFilter(func(hdr *tar.Header) (bool, error) {
d := filepath.Dir(hdr.Name)
result := d == "bin"
result := d == binDir
if config.Libs {
result = result || d == "lib"
result = result || d == libDir
}
if runtime.GOOS == "windows" {
hdr.Name = strings.Replace(hdr.Name, "Files", "", 1)
}
if result && !config.Replace {
if _, err := os.Lstat(filepath.Join(path, hdr.Name)); err == nil {

View File

@ -69,3 +69,7 @@ func (s *deletedState) SetExited(status int) {
func (s *deletedState) Exec(ctx context.Context, path string, r *ExecConfig) (Process, error) {
return nil, errors.Errorf("cannot exec in a deleted state")
}
func (s *deletedState) Status(ctx context.Context) (string, error) {
return "stopped", nil
}

View File

@ -96,7 +96,6 @@ func (e *execProcess) setExited(status int) {
e.status = status
e.exited = time.Now()
e.parent.Platform.ShutdownConsole(context.Background(), e.console)
e.pid.set(StoppedPID)
close(e.waitBlock)
}
@ -147,7 +146,7 @@ func (e *execProcess) kill(ctx context.Context, sig uint32, _ bool) error {
switch {
case pid == 0:
return errors.Wrap(errdefs.ErrFailedPrecondition, "process not created")
case pid < 0:
case !e.exited.IsZero():
return errors.Wrapf(errdefs.ErrNotFound, "process already finished")
default:
if err := unix.Kill(pid, syscall.Signal(sig)); err != nil {
@ -261,17 +260,5 @@ func (e *execProcess) Status(ctx context.Context) (string, error) {
}
e.mu.Lock()
defer e.mu.Unlock()
// if we don't have a pid(pid=0) then the exec process has just been created
if e.pid.get() == 0 {
return "created", nil
}
if e.pid.get() == StoppedPID {
return "stopped", nil
}
// if we have a pid and it can be signaled, the process is running
if err := unix.Kill(e.pid.get(), 0); err == nil {
return "running", nil
}
// else if we have a pid but it can nolonger be signaled, it has stopped
return "stopped", nil
return e.execState.Status(ctx)
}

View File

@ -31,6 +31,7 @@ type execState interface {
Delete(context.Context) error
Kill(context.Context, uint32, bool) error
SetExited(int)
Status(context.Context) (string, error)
}
type execCreatedState struct {
@ -82,6 +83,10 @@ func (s *execCreatedState) SetExited(status int) {
}
}
func (s *execCreatedState) Status(ctx context.Context) (string, error) {
return "created", nil
}
type execRunningState struct {
p *execProcess
}
@ -120,6 +125,10 @@ func (s *execRunningState) SetExited(status int) {
}
}
func (s *execRunningState) Status(ctx context.Context) (string, error) {
return "running", nil
}
type execStoppedState struct {
p *execProcess
}
@ -157,3 +166,7 @@ func (s *execStoppedState) Kill(ctx context.Context, sig uint32, all bool) error
func (s *execStoppedState) SetExited(status int) {
// no op
}
func (s *execStoppedState) Status(ctx context.Context) (string, error) {
return "stopped", nil
}

View File

@ -62,9 +62,11 @@ type Init struct {
Platform stdio.Platform
io *processIO
runtime *runc.Runc
// pausing preserves the pausing state.
pausing *atomicBool
status int
exited time.Time
pid safePid
pid int
closers []io.Closer
stdin io.Closer
stdio stdio.Stdio
@ -97,6 +99,7 @@ func New(id string, runtime *runc.Runc, stdio stdio.Stdio) *Init {
p := &Init{
id: id,
runtime: runtime,
pausing: new(atomicBool),
stdio: stdio,
status: 0,
waitBlock: make(chan struct{}),
@ -113,8 +116,6 @@ func (p *Init) Create(ctx context.Context, r *CreateConfig) error {
pio *processIO
pidFile = newPidFile(p.Bundle)
)
p.pid.Lock()
defer p.pid.Unlock()
if r.Terminal {
if socket, err = runc.NewTempConsoleSocket(); err != nil {
@ -170,7 +171,7 @@ func (p *Init) Create(ctx context.Context, r *CreateConfig) error {
if err != nil {
return errors.Wrap(err, "failed to retrieve OCI runtime container pid")
}
p.pid.pid = pid
p.pid = pid
return nil
}
@ -216,7 +217,7 @@ func (p *Init) ID() string {
// Pid of the process
func (p *Init) Pid() int {
return p.pid.get()
return p.pid
}
// ExitStatus of the process
@ -237,17 +238,14 @@ func (p *Init) ExitedAt() time.Time {
// Status of the process
func (p *Init) Status(ctx context.Context) (string, error) {
if p.pausing.get() {
return "pausing", nil
}
p.mu.Lock()
defer p.mu.Unlock()
c, err := p.runtime.State(ctx, p.id)
if err != nil {
if strings.Contains(err.Error(), "does not exist") {
return "stopped", nil
}
return "", p.runtimeError(err, "OCI runtime state failed")
}
return c.Status, nil
return p.initState.Status(ctx)
}
// Start the init process
@ -275,7 +273,6 @@ func (p *Init) setExited(status int) {
p.exited = time.Now()
p.status = status
p.Platform.ShutdownConsole(context.Background(), p.console)
p.pid.set(StoppedPID)
close(p.waitBlock)
}

View File

@ -37,6 +37,7 @@ type initState interface {
Exec(context.Context, string, *ExecConfig) (Process, error)
Kill(context.Context, uint32, bool) error
SetExited(int)
Status(context.Context) (string, error)
}
type createdState struct {
@ -103,6 +104,10 @@ func (s *createdState) Exec(ctx context.Context, path string, r *ExecConfig) (Pr
return s.p.exec(ctx, path, r)
}
func (s *createdState) Status(ctx context.Context) (string, error) {
return "created", nil
}
type createdCheckpointState struct {
p *Init
opts *runc.RestoreOpts
@ -142,9 +147,6 @@ func (s *createdCheckpointState) Start(ctx context.Context) error {
p := s.p
sio := p.stdio
p.pid.Lock()
defer p.pid.Unlock()
var (
err error
socket *runc.Socket
@ -184,7 +186,7 @@ func (s *createdCheckpointState) Start(ctx context.Context) error {
if err != nil {
return errors.Wrap(err, "failed to retrieve OCI runtime container pid")
}
p.pid.pid = pid
p.pid = pid
return s.transition("running")
}
@ -211,6 +213,10 @@ func (s *createdCheckpointState) Exec(ctx context.Context, path string, r *ExecC
return nil, errors.Errorf("cannot exec in a created state")
}
func (s *createdCheckpointState) Status(ctx context.Context) (string, error) {
return "created", nil
}
type runningState struct {
p *Init
}
@ -228,6 +234,13 @@ func (s *runningState) transition(name string) error {
}
func (s *runningState) Pause(ctx context.Context) error {
s.p.pausing.set(true)
// NOTE "pausing" will be returned in the short window
// after `transition("paused")`, before `pausing` is reset
// to false. That doesn't break the state machine, just
// delays the "paused" state a little bit.
defer s.p.pausing.set(false)
if err := s.p.runtime.Pause(ctx, s.p.id); err != nil {
return s.p.runtimeError(err, "OCI runtime pause failed")
}
@ -271,6 +284,10 @@ func (s *runningState) Exec(ctx context.Context, path string, r *ExecConfig) (Pr
return s.p.exec(ctx, path, r)
}
func (s *runningState) Status(ctx context.Context) (string, error) {
return "running", nil
}
type pausedState struct {
p *Init
}
@ -335,6 +352,10 @@ func (s *pausedState) Exec(ctx context.Context, path string, r *ExecConfig) (Pro
return nil, errors.Errorf("cannot exec in a paused state")
}
func (s *pausedState) Status(ctx context.Context) (string, error) {
return "paused", nil
}
type stoppedState struct {
p *Init
}
@ -387,3 +408,7 @@ func (s *stoppedState) SetExited(status int) {
func (s *stoppedState) Exec(ctx context.Context, path string, r *ExecConfig) (Process, error) {
return nil, errors.Errorf("cannot exec in a stopped state")
}
func (s *stoppedState) Status(ctx context.Context) (string, error) {
return "stopped", nil
}

View File

@ -27,6 +27,7 @@ import (
"path/filepath"
"strings"
"sync"
"sync/atomic"
"time"
"github.com/containerd/containerd/errdefs"
@ -38,8 +39,6 @@ import (
const (
// RuncRoot is the path to the root runc state directory
RuncRoot = "/run/containerd/runc"
// StoppedPID is the pid assigned after a container has run and stopped
StoppedPID = -1
// InitPidFile name of the file that contains the init pid
InitPidFile = "init.pid"
)
@ -56,10 +55,18 @@ func (s *safePid) get() int {
return s.pid
}
func (s *safePid) set(pid int) {
s.Lock()
s.pid = pid
s.Unlock()
type atomicBool int32
func (ab *atomicBool) set(b bool) {
if b {
atomic.StoreInt32((*int32)(ab), 1)
} else {
atomic.StoreInt32((*int32)(ab), 0)
}
}
func (ab *atomicBool) get() bool {
return atomic.LoadInt32((*int32)(ab)) == 1
}
// TODO(mlaventure): move to runc package?

View File

@ -189,9 +189,8 @@ func Parse(specifier string) (specs.Platform, error) {
if isKnownOS(p.OS) {
// picks a default architecture
p.Architecture = runtime.GOARCH
if p.Architecture == "arm" {
// TODO(stevvooe): Resolve arm variant, if not v6 (default)
return specs.Platform{}, errors.Wrapf(errdefs.ErrNotImplemented, "arm support not fully implemented")
if p.Architecture == "arm" && cpuVariant != "v7" {
p.Variant = cpuVariant
}
return p, nil

View File

@ -70,6 +70,11 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (_ Ima
}
unpackWrapper, eg := u.handlerWrapper(ctx, &unpacks)
defer func() {
if retErr != nil {
// Forcibly stop the unpacker if there is
// an error.
eg.Cancel()
}
if err := eg.Wait(); err != nil {
if retErr == nil {
retErr = errors.Wrap(err, "unpack")

View File

@ -316,11 +316,12 @@ func (s *service) Start(ctx context.Context, r *taskAPI.StartRequest) (*taskAPI.
s.eventSendMu.Unlock()
return nil, errdefs.ToGRPC(err)
}
switch r.ExecID {
case "":
if err := s.ep.Add(container.ID, container.Cgroup()); err != nil {
logrus.WithError(err).Error("add cg to OOM monitor")
}
switch r.ExecID {
case "":
s.send(&eventstypes.TaskStart{
ContainerID: container.ID,
Pid: uint32(p.Pid()),
@ -348,15 +349,11 @@ func (s *service) Delete(ctx context.Context, r *taskAPI.DeleteRequest) (*taskAP
if err != nil {
return nil, errdefs.ToGRPC(err)
}
// if we deleted our init task, close the platform and send the task delete event
// if we deleted an init task, send the task delete event
if r.ExecID == "" {
s.mu.Lock()
delete(s.containers, r.ID)
hasContainers := len(s.containers) > 0
s.mu.Unlock()
if s.platform != nil && !hasContainers {
s.platform.Close()
}
s.send(&eventstypes.TaskDelete{
ContainerID: container.ID,
Pid: uint32(p.Pid()),
@ -600,6 +597,11 @@ func (s *service) Shutdown(ctx context.Context, r *taskAPI.ShutdownRequest) (*pt
}
s.cancel()
close(s.events)
if s.platform != nil {
s.platform.Close()
}
return empty, nil
}

View File

@ -115,7 +115,7 @@ func (s *service) List(req *api.ListContentRequest, session api.Content_ListServ
return nil
}, req.Filters...); err != nil {
return err
return errdefs.ToGRPC(err)
}
if len(buffer) > 0 {

View File

@ -20,7 +20,6 @@ import (
"fmt"
"os"
"path/filepath"
"runtime"
"github.com/containerd/containerd/plugin"
"github.com/pkg/errors"
@ -42,23 +41,21 @@ func init() {
InitFn: func(ic *plugin.InitContext) (interface{}, error) {
path := ic.Config.(*Config).Path
ic.Meta.Exports["path"] = path
bin := filepath.Join(path, "bin")
if err := os.MkdirAll(bin, 0711); err != nil {
return nil, err
}
if err := os.Setenv("PATH", fmt.Sprintf("%s:%s", bin, os.Getenv("PATH"))); err != nil {
if err := os.Setenv("PATH", fmt.Sprintf("%s%c%s", bin, os.PathListSeparator, os.Getenv("PATH"))); err != nil {
return nil, errors.Wrapf(err, "set binary image directory in path %s", bin)
}
if runtime.GOOS != "windows" {
lib := filepath.Join(path, "lib")
if err := os.MkdirAll(lib, 0711); err != nil {
return nil, err
}
if err := os.Setenv("LD_LIBRARY_PATH", fmt.Sprintf("%s:%s", os.Getenv("LD_LIBRARY_PATH"), lib)); err != nil {
if err := os.Setenv("LD_LIBRARY_PATH", fmt.Sprintf("%s%c%s", lib, os.PathListSeparator, os.Getenv("LD_LIBRARY_PATH"))); err != nil {
return nil, errors.Wrapf(err, "set binary lib directory in path %s", lib)
}
}
return &manager{}, nil
},
})

View File

@ -297,7 +297,7 @@ func Remove(ctx context.Context, key string) (string, snapshots.Kind, error) {
}
if err := readSnapshot(sbkt, &id, &si); err != nil {
errors.Wrapf(err, "failed to read snapshot %s", key)
return errors.Wrapf(err, "failed to read snapshot %s", key)
}
if pbkt != nil {

View File

@ -186,8 +186,32 @@ func (u *unpacker) unpack(ctx context.Context, config ocispec.Descriptor, layers
return nil
}
func (u *unpacker) handlerWrapper(uctx context.Context, unpacks *int32) (func(images.Handler) images.Handler, *errgroup.Group) {
eg, uctx := errgroup.WithContext(uctx)
type errGroup struct {
*errgroup.Group
cancel context.CancelFunc
}
func newErrGroup(ctx context.Context) (*errGroup, context.Context) {
ctx, cancel := context.WithCancel(ctx)
eg, ctx := errgroup.WithContext(ctx)
return &errGroup{
Group: eg,
cancel: cancel,
}, ctx
}
func (e *errGroup) Cancel() {
e.cancel()
}
func (e *errGroup) Wait() error {
err := e.Group.Wait()
e.cancel()
return err
}
func (u *unpacker) handlerWrapper(uctx context.Context, unpacks *int32) (func(images.Handler) images.Handler, *errGroup) {
eg, uctx := newErrGroup(uctx)
return func(f images.Handler) images.Handler {
var (
lock sync.Mutex
@ -234,7 +258,19 @@ func (u *unpacker) handlerWrapper(uctx context.Context, unpacks *int32) (func(im
update := !schema1
lock.Unlock()
if update {
u.updateCh <- desc
select {
case <-uctx.Done():
// Do not send update if unpacker is not running.
default:
select {
case u.updateCh <- desc:
case <-uctx.Done():
// Do not send update if unpacker is not running.
}
}
// Checking ctx.Done() prevents the case that unpacker
// exits unexpectedly, but update continues to be generated,
// and eventually fills up updateCh and blocks forever.
}
}
return children, nil

View File

@ -51,7 +51,7 @@ github.com/cpuguy83/go-md2man v1.0.10
github.com/russross/blackfriday v1.5.2
# cri dependencies
github.com/containerd/cri 5d49e7e51b43e36a6b9c4386257c7d08c602237f # release/1.3
github.com/containerd/cri b1bef15fbeb6c6f0569b67322acfa74ca3597755 # release/1.3
github.com/containerd/go-cni 49fbd9b210f3c8ee3b7fd3cd797aabaf364627c1
github.com/containernetworking/cni v0.7.1
github.com/containernetworking/plugins v0.7.6

View File

@ -21,7 +21,7 @@ var (
Package = "github.com/containerd/containerd"
// Version holds the complete version number. Filled in at linking time.
Version = "1.3.0+unknown"
Version = "1.3.2+unknown"
// Revision is filled with the VCS (e.g. git) revision being used to build
// the program at linking time.

2
vendor/modules.txt vendored
View File

@ -151,7 +151,7 @@ github.com/container-storage-interface/spec/lib/go/csi
github.com/containerd/cgroups
# github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1 => github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50
github.com/containerd/console
# github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69 => github.com/rancher/containerd v1.3.0-k3s.5
# github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69 => github.com/rancher/containerd v1.3.3-k3s1
github.com/containerd/containerd
github.com/containerd/containerd/api/events
github.com/containerd/containerd/api/services/containers/v1