Skip to content
This repository has been archived by the owner on Dec 7, 2023. It is now read-only.

Detect available containerd-shim versions defaulting to legacy linux runtime #411

Merged
merged 3 commits into from
Sep 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (
github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02 // indirect
github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c // indirect
github.com/containerd/go-cni v0.0.0-20190813230227-49fbd9b210f3
github.com/containerd/go-runc v0.0.0-20190603165425-9007c2405372 // indirect
github.com/containerd/ttrpc v0.0.0-20190613183316-1fb3814edf44 // indirect
github.com/containerd/typeurl v0.0.0-20190515163108-7312978f2987 // indirect
github.com/containernetworking/cni v0.7.1 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c h1:KFbqHhDeaHM7IfF
github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
github.com/containerd/go-cni v0.0.0-20190813230227-49fbd9b210f3 h1:owkX+hC6Inv1XUep/pAjF7qJpnZWjbtETw5r1DVYFPo=
github.com/containerd/go-cni v0.0.0-20190813230227-49fbd9b210f3/go.mod h1:2wlRxCQdiBY+OcjNg5x8kI+5mEL1fGt25L4IzQHYJsM=
github.com/containerd/go-runc v0.0.0-20190603165425-9007c2405372 h1:+D2NrQLJCRXEZ/V1XH1OW7wZIWjgsrfnH8yd+dZgq9A=
github.com/containerd/go-runc v0.0.0-20190603165425-9007c2405372/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
github.com/containerd/ttrpc v0.0.0-20190613183316-1fb3814edf44 h1:vG5QXCUakUhR2CRI44aD3joCWcvb5mfZRxcwVqBVGeU=
github.com/containerd/ttrpc v0.0.0-20190613183316-1fb3814edf44/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
github.com/containerd/typeurl v0.0.0-20190515163108-7312978f2987 h1:Qaux2AYCIF3t3gxqjFHDJbxWPhMphgBruE8ygIRHtBA=
Expand Down
86 changes: 80 additions & 6 deletions pkg/runtime/containerd/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ import (
"github.com/containerd/containerd"
"github.com/containerd/containerd/cio"
"github.com/containerd/containerd/containers"
"github.com/containerd/containerd/defaults"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/oci"
"github.com/containerd/containerd/plugin"
v2shim "github.com/containerd/containerd/runtime/v2/shim"
"github.com/containerd/containerd/snapshots"
"github.com/opencontainers/go-digest"
"github.com/opencontainers/image-spec/identity"
Expand All @@ -28,19 +30,32 @@ import (
log "github.com/sirupsen/logrus"
meta "github.com/weaveworks/ignite/pkg/apis/meta/v1alpha1"
"github.com/weaveworks/ignite/pkg/preflight"
"github.com/weaveworks/ignite/pkg/preflight/checkers"
"github.com/weaveworks/ignite/pkg/runtime"
"github.com/weaveworks/ignite/pkg/util"
"golang.org/x/sys/unix"
)

const (
ctdSocket = "/run/containerd/containerd.sock"
ctdNamespace = "firecracker"
stopTimeoutLabel = "IgniteStopTimeout"
logPathTemplate = "/tmp/%s.log"
)

var (
// containerdSocketLocations is a list of socket locations to stat for
containerdSocketLocations = []string{
chanwit marked this conversation as resolved.
Show resolved Hide resolved
defaults.DefaultAddress, // "/run/containerd/containerd.sock"
"/run/docker/containerd/containerd.sock",
}
// v2ShimRuntimes is a list of containerd runtimes we support.
// Note that we only list `runc` runtimes -- containerd plugin runtimes are omitted.
// This package also supports a fallback to the legacy runtime: `plugin.RuntimeLinuxV1`.
v2ShimRuntimes = []string{
plugin.RuntimeRuncV2,
plugin.RuntimeRuncV1,
}
)

// ctdClient is a runtime.Interface
// implementation serving the containerd client
type ctdClient struct {
Expand All @@ -50,9 +65,58 @@ type ctdClient struct {

var _ runtime.Interface = &ctdClient{}

// statContainerdSocket returns the first existing file in the containerdSocketLocations list
func statContainerdSocket() (string, error) {
for _, socket := range containerdSocketLocations {
if _, err := os.Stat(socket); err == nil {
return socket, nil
}
}
return "", fmt.Errorf("Could not stat a containerd socket: %v", containerdSocketLocations)
}

// getNewestAvailableContainerdRuntime returns the newest possible runtime for the shims available in the PATH.
// If no shim is found, the legacy Linux V1 runtime is returned along with an error.
// Use of this function couples ignite to the PATH and mount namespace of containerd which is undesireable.
//
// TODO(stealthybox): PR CheckRuntime() to containerd libraries instead of using exec.LookPath()
func getNewestAvailableContainerdRuntime() (string, error) {
for _, rt := range v2ShimRuntimes {
binary := v2shim.BinaryName(rt)
if binary == "" {
// this shouldn't happen if the matching test is passing, but it's not fatal -- just log and continue
log.Errorf("shim binary could not be found -- %q is an invalid runtime/v2/shim", rt)
} else if _, err := exec.LookPath(binary); err == nil {
return rt, nil
}
}

// legacy fallback needs hard-coded binary name -- it's not exported by containerd/runtime/v1/shim
if _, err := exec.LookPath("containerd-shim"); err == nil {
return plugin.RuntimeLinuxV1, nil
}

// default to the legacy runtime and return an error so the caller can decide what to do
return plugin.RuntimeLinuxV1, fmt.Errorf("a containerd-shim could not be found for runtimes %v, %s", v2ShimRuntimes, plugin.RuntimeLinuxV1)
}

// GetContainerdClient builds a client for talking to containerd
func GetContainerdClient() (*ctdClient, error) {
cli, err := containerd.New(ctdSocket)
ctdSocket, err := statContainerdSocket()
if err != nil {
return nil, err
}

runtime, err := getNewestAvailableContainerdRuntime()
if err != nil {
// proceed with the default runtime -- our PATH can't see a shim binary, but containerd might be able to
log.Warningf("Proceeding with default runtime %q: %v", runtime, err)
}

cli, err := containerd.New(
ctdSocket,
containerd.WithDefaultRuntime(runtime),
)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -350,8 +414,6 @@ func (cc *ctdClient) RunContainer(image meta.OCIImageRef, config *runtime.Contai
snapshotOpt,
//containerd.WithImageStopSignal(img, "SIGTERM"),
containerd.WithNewSpec(opts...),
// TODO: Upgrade to v2
containerd.WithRuntime(plugin.RuntimeRuncV1, nil),
containerd.WithContainerLabels(config.Labels),
}

Expand Down Expand Up @@ -634,8 +696,20 @@ func (cc *ctdClient) RawClient() interface{} {
return cc.client
}

type containerdSocketChecker struct{}

func (ctdsc containerdSocketChecker) Check() error {
_, err := statContainerdSocket()
return err
}
func (ctdsc containerdSocketChecker) Name() string {
return "containerdSocketChecker"
}
func (ctdsc containerdSocketChecker) Type() string {
return "containerdSocketChecker"
}
func (cc *ctdClient) PreflightChecker() preflight.Checker {
return checkers.NewExistingFileChecker(ctdSocket)
return containerdSocketChecker{}
}

// imageUsage returns the size/inode usage of the given image by
Expand Down
10 changes: 10 additions & 0 deletions pkg/runtime/containerd/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (

meta "github.com/weaveworks/ignite/pkg/apis/meta/v1alpha1"
"github.com/weaveworks/ignite/pkg/runtime"

v2shim "github.com/containerd/containerd/runtime/v2/shim"
)

var client runtime.Interface
Expand Down Expand Up @@ -72,3 +74,11 @@ func TestRun(t *testing.T) {
}
t.Error(client.RunContainer(imageName, cfg, "foo2"))
}

func TestV2ShimRuntimesHaveBinaryNames(t *testing.T) {
for _, runtime := range v2ShimRuntimes {
if v2shim.BinaryName(runtime) == "" {
t.Errorf("shim binary could not be found -- %q is an invalid runtime/v2/shim", runtime)
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading