diff options
author | Fabricio Voznika <fvoznika@google.com> | 2021-01-12 17:50:33 -0800 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-01-12 17:54:10 -0800 |
commit | 8b0f0b4d11e0938eec8da411323b2ce35976ab56 (patch) | |
tree | aab8e37ca51133da5bfa4a055ea0dfa0bda514cf | |
parent | be2b9d75d75e0e7371cd868589d57f4ddee44781 (diff) |
Delete shim v1
gvisor-containerd-shim is not compatible with containerd 1.1 or earlier.
Starting from containerd 1.2, shim v2 is the preferred interface.
PiperOrigin-RevId: 351485556
-rw-r--r-- | BUILD | 3 | ||||
-rw-r--r-- | Makefile | 11 | ||||
-rw-r--r-- | README.md | 5 | ||||
-rw-r--r-- | debian/BUILD | 3 | ||||
-rw-r--r-- | g3doc/user_guide/containerd/BUILD | 2 | ||||
-rw-r--r-- | g3doc/user_guide/containerd/configuration.md | 2 | ||||
-rw-r--r-- | g3doc/user_guide/containerd/containerd_11.md | 4 | ||||
-rw-r--r-- | g3doc/user_guide/install.md | 6 | ||||
-rw-r--r-- | go.mod | 1 | ||||
-rw-r--r-- | go.sum | 3 | ||||
-rw-r--r-- | nogo.yaml | 2 | ||||
-rw-r--r-- | pkg/shim/BUILD (renamed from pkg/shim/v2/BUILD) | 8 | ||||
-rw-r--r-- | pkg/shim/api.go (renamed from pkg/shim/v2/api.go) | 2 | ||||
-rw-r--r-- | pkg/shim/epoll.go (renamed from pkg/shim/v2/epoll.go) | 2 | ||||
-rw-r--r-- | pkg/shim/options.go (renamed from pkg/shim/v2/options.go) | 2 | ||||
-rw-r--r-- | pkg/shim/proc/BUILD (renamed from pkg/shim/v1/proc/BUILD) | 2 | ||||
-rw-r--r-- | pkg/shim/proc/deleted_state.go (renamed from pkg/shim/v1/proc/deleted_state.go) | 0 | ||||
-rw-r--r-- | pkg/shim/proc/exec.go (renamed from pkg/shim/v1/proc/exec.go) | 0 | ||||
-rw-r--r-- | pkg/shim/proc/exec_state.go (renamed from pkg/shim/v1/proc/exec_state.go) | 0 | ||||
-rw-r--r-- | pkg/shim/proc/init.go (renamed from pkg/shim/v1/proc/init.go) | 6 | ||||
-rw-r--r-- | pkg/shim/proc/init_state.go (renamed from pkg/shim/v1/proc/init_state.go) | 0 | ||||
-rw-r--r-- | pkg/shim/proc/io.go (renamed from pkg/shim/v1/proc/io.go) | 0 | ||||
-rw-r--r-- | pkg/shim/proc/proc.go (renamed from pkg/shim/v1/proc/process.go) | 3 | ||||
-rw-r--r-- | pkg/shim/proc/types.go (renamed from pkg/shim/v1/proc/types.go) | 0 | ||||
-rw-r--r-- | pkg/shim/proc/utils.go (renamed from pkg/shim/v1/proc/utils.go) | 0 | ||||
-rw-r--r-- | pkg/shim/runtimeoptions/BUILD (renamed from pkg/shim/v2/runtimeoptions/BUILD) | 2 | ||||
-rw-r--r-- | pkg/shim/runtimeoptions/runtimeoptions.go (renamed from pkg/shim/v2/runtimeoptions/runtimeoptions.go) | 0 | ||||
-rw-r--r-- | pkg/shim/runtimeoptions/runtimeoptions.proto (renamed from pkg/shim/v2/runtimeoptions/runtimeoptions.proto) | 0 | ||||
-rw-r--r-- | pkg/shim/runtimeoptions/runtimeoptions_cri.go (renamed from pkg/shim/v2/runtimeoptions/runtimeoptions_cri.go) | 0 | ||||
-rw-r--r-- | pkg/shim/runtimeoptions/runtimeoptions_test.go (renamed from pkg/shim/v2/runtimeoptions/runtimeoptions_test.go) | 0 | ||||
-rw-r--r-- | pkg/shim/service.go (renamed from pkg/shim/v2/service.go) | 10 | ||||
-rw-r--r-- | pkg/shim/service_linux.go (renamed from pkg/shim/v2/service_linux.go) | 2 | ||||
-rw-r--r-- | pkg/shim/state.go (renamed from pkg/shim/v2/state.go) | 2 | ||||
-rw-r--r-- | pkg/shim/utils/BUILD (renamed from pkg/shim/v1/utils/BUILD) | 0 | ||||
-rw-r--r-- | pkg/shim/utils/annotations.go (renamed from pkg/shim/v1/utils/annotations.go) | 0 | ||||
-rw-r--r-- | pkg/shim/utils/utils.go (renamed from pkg/shim/v1/utils/utils.go) | 2 | ||||
-rw-r--r-- | pkg/shim/utils/volumes.go (renamed from pkg/shim/v1/utils/volumes.go) | 0 | ||||
-rw-r--r-- | pkg/shim/utils/volumes_test.go (renamed from pkg/shim/v1/utils/volumes_test.go) | 0 | ||||
-rw-r--r-- | pkg/shim/v1/shim/BUILD | 41 | ||||
-rw-r--r-- | pkg/shim/v1/shim/api.go | 41 | ||||
-rw-r--r-- | pkg/shim/v1/shim/platform.go | 106 | ||||
-rw-r--r-- | pkg/shim/v1/shim/service.go | 572 | ||||
-rw-r--r-- | pkg/shim/v1/shim/shim.go | 17 | ||||
-rw-r--r-- | pkg/test/criutil/criutil.go | 4 | ||||
-rw-r--r-- | shim/BUILD | 12 | ||||
-rw-r--r-- | shim/README.md | 8 | ||||
-rw-r--r-- | shim/cli/BUILD (renamed from shim/v2/cli/BUILD) | 4 | ||||
-rw-r--r-- | shim/cli/cli.go (renamed from shim/v2/cli/cli.go) | 6 | ||||
-rw-r--r-- | shim/main.go (renamed from shim/v2/main.go) | 2 | ||||
-rw-r--r-- | shim/v1/BUILD | 13 | ||||
-rw-r--r-- | shim/v1/cli/BUILD | 30 | ||||
-rw-r--r-- | shim/v1/cli/api.go | 24 | ||||
-rw-r--r-- | shim/v1/cli/cli.go | 266 | ||||
-rw-r--r-- | shim/v1/cli/config.go | 40 | ||||
-rw-r--r-- | shim/v1/main.go | 24 | ||||
-rw-r--r-- | shim/v2/BUILD | 13 | ||||
-rw-r--r-- | test/root/crictl_test.go | 332 | ||||
-rwxr-xr-x | tools/go_branch.sh | 2 | ||||
-rw-r--r-- | tools/installers/BUILD | 3 | ||||
-rwxr-xr-x | tools/installers/containerd.sh | 14 | ||||
-rwxr-xr-x | tools/installers/shim.sh | 1 | ||||
-rw-r--r-- | website/_layouts/docs.html | 33 | ||||
-rw-r--r-- | website/defs.bzl | 10 |
63 files changed, 228 insertions, 1475 deletions
@@ -116,8 +116,7 @@ go_path( # binaries have been factored into a cli package, which is # a good practice in any case. "//runsc/cli", - "//shim/v1/cli", - "//shim/v2/cli", + "//shim/cli", "//webhook/pkg/cli", # Packages that are not dependencies of the above. @@ -298,13 +298,9 @@ containerd-test-%: load-basic_alpine load-basic_python load-basic_busybox load-b @$(call sudo,tools/installers:shim) @$(call sudo,test/root:root_test,--runtime=$(RUNTIME) -test.v) -# Note that we can't run containerd-test-1.1.8 tests here. -# -# Containerd 1.1.8 should work, but because of a bug in loading images locally -# (https://github.com/kubernetes-sigs/cri-tools/issues/421), we are unable to -# actually drive the tests. The v1 API is tested exclusively through 1.2.13. +# The shim builds with containerd 1.3.9 and it's not backward compatible. Test +# with 1.3.9 and newer versions. containerd-tests: ## Runs all supported containerd version tests. -containerd-tests: containerd-test-1.2.13 containerd-tests: containerd-test-1.3.9 containerd-tests: containerd-test-1.4.3 @@ -433,8 +429,7 @@ $(RELEASE_KEY): $(RELEASE_ARTIFACTS)/%: @mkdir -p $@ @$(call copy,//runsc:runsc,$@) - @$(call copy,//shim/v1:gvisor-containerd-shim,$@) - @$(call copy,//shim/v2:containerd-shim-runsc-v1,$@) + @$(call copy,//shim:containerd-shim-runsc-v1,$@) @$(call copy,//debian:debian,$@) release: $(RELEASE_KEY) $(RELEASE_ARTIFACTS)/$(ARCH) @@ -93,11 +93,10 @@ GO111MODULE=on go get gvisor.dev/gvisor/runsc@go CGO_ENABLED=0 GO111MODULE=on sudo -E go build -o /usr/local/bin/runsc gvisor.dev/gvisor/runsc ``` -Subsequently, you can build and install the shim binaries for `containerd`: +Subsequently, you can build and install the shim binary for `containerd`: ```sh -GO111MODULE=on sudo -E go build -o /usr/local/bin/gvisor-containerd-shim gvisor.dev/gvisor/shim/v1 -GO111MODULE=on sudo -E go build -o /usr/local/bin/containerd-shim-runsc-v1 gvisor.dev/gvisor/shim/v2 +GO111MODULE=on sudo -E go build -o /usr/local/bin/containerd-shim-runsc-v1 gvisor.dev/gvisor/shim ``` Note that this branch is supported in a best effort capacity, and direct diff --git a/debian/BUILD b/debian/BUILD index 1c379b08f..64aa2369a 100644 --- a/debian/BUILD +++ b/debian/BUILD @@ -6,8 +6,7 @@ pkg_tar( name = "debian-bin", srcs = [ "//runsc", - "//shim/v1:gvisor-containerd-shim", - "//shim/v2:containerd-shim-runsc-v1", + "//shim:containerd-shim-runsc-v1", ], mode = "0755", package_dir = "/usr/bin", diff --git a/g3doc/user_guide/containerd/BUILD b/g3doc/user_guide/containerd/BUILD index 979d46105..0ede4819c 100644 --- a/g3doc/user_guide/containerd/BUILD +++ b/g3doc/user_guide/containerd/BUILD @@ -27,7 +27,7 @@ doc( name = "containerd_11", src = "containerd_11.md", category = "User Guide", + include_in_menu = False, permalink = "/docs/user_guide/containerd/containerd_11/", subcategory = "Containerd", - weight = "99", ) diff --git a/g3doc/user_guide/containerd/configuration.md b/g3doc/user_guide/containerd/configuration.md index bb65aa514..4f5e721be 100644 --- a/g3doc/user_guide/containerd/configuration.md +++ b/g3doc/user_guide/containerd/configuration.md @@ -17,7 +17,7 @@ option = "value" ``` The set of options that can be configured can be found in -[options.go](https://github.com/google/gvisor/blob/master/pkg/shim/v2/options.go). +[options.go](https://cs.opensource.google/gvisor/gvisor/+/master:pkg/shim/options.go). Values under `[runsc_config]` can be used to set arbitrary flags to runsc. `flag = "value"` is converted to `--flag="value"` when runsc is invoked. Run `runsc flags` so see which flags are available diff --git a/g3doc/user_guide/containerd/containerd_11.md b/g3doc/user_guide/containerd/containerd_11.md index 50befbdf4..200d3da76 100644 --- a/g3doc/user_guide/containerd/containerd_11.md +++ b/g3doc/user_guide/containerd/containerd_11.md @@ -1,5 +1,9 @@ # Older Versions (containerd 1.1) +**WARNING: containerd 1.1 and shim v1 is no longer supported. The instructions +below is kept just for reference in case you're dealing with an old version. +It's highly recommended upgrading to the latest version.** + This document describes how to install and run the `gvisor-containerd-shim` using the untrusted workload CRI extension. This requires `containerd` 1.1 or later. diff --git a/g3doc/user_guide/install.md b/g3doc/user_guide/install.md index d190c27bf..ad0ab9923 100644 --- a/g3doc/user_guide/install.md +++ b/g3doc/user_guide/install.md @@ -15,14 +15,12 @@ To download and install the latest release manually follow these steps: ARCH=$(uname -m) URL=https://storage.googleapis.com/gvisor/releases/release/latest/${ARCH} wget ${URL}/runsc ${URL}/runsc.sha512 \ - ${URL}/gvisor-containerd-shim ${URL}/gvisor-containerd-shim.sha512 \ ${URL}/containerd-shim-runsc-v1 ${URL}/containerd-shim-runsc-v1.sha512 sha512sum -c runsc.sha512 \ - -c gvisor-containerd-shim.sha512 \ -c containerd-shim-runsc-v1.sha512 rm -f *.sha512 - chmod a+rx runsc gvisor-containerd-shim containerd-shim-runsc-v1 - sudo mv runsc gvisor-containerd-shim containerd-shim-runsc-v1 /usr/local/bin + chmod a+rx runsc containerd-shim-runsc-v1 + sudo mv runsc containerd-shim-runsc-v1 /usr/local/bin ) ``` @@ -15,7 +15,6 @@ require ( github.com/containerd/continuity v0.0.0-20200928162600-f2cc35102c2a // indirect github.com/containerd/fifo v0.0.0-20191213151349-ff969a566b00 // indirect github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328 // indirect - github.com/containerd/ttrpc v0.0.0-20200121165050-0be804eadb15 // indirect github.com/containerd/typeurl v0.0.0-20200205145503-b45ef1f1f737 // indirect github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect github.com/coreos/go-systemd/v22 v22.0.0 // indirect @@ -66,9 +66,6 @@ github.com/containerd/fifo v0.0.0-20191213151349-ff969a566b00/go.mod h1:jPQ2IAeZ 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/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= -github.com/containerd/ttrpc v0.0.0-20200121165050-0be804eadb15 h1:+jgiLE5QylzgADj0Yldb4id1NQNRrDOROj7KDvY9PEc= -github.com/containerd/ttrpc v0.0.0-20200121165050-0be804eadb15/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= github.com/containerd/typeurl v0.0.0-20200205145503-b45ef1f1f737 h1:HovfQDS/K3Mr7eyS0QJLxE1CbVUhjZCl6g3OhFJgP1o= github.com/containerd/typeurl v0.0.0-20200205145503-b45ef1f1f737/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg= @@ -57,7 +57,7 @@ global: - "should not use underscores in Go names" exclude: # Generated: exempt all. - - pkg/shim/v2/runtimeoptions/runtimeoptions_cri.go + - pkg/shim/runtimeoptions/runtimeoptions_cri.go analyzers: asmdecl: external: # Enabled. diff --git a/pkg/shim/v2/BUILD b/pkg/shim/BUILD index b0e8daa51..4f7c02f5d 100644 --- a/pkg/shim/v2/BUILD +++ b/pkg/shim/BUILD @@ -3,7 +3,7 @@ load("//tools:defs.bzl", "go_library") package(licenses = ["notice"]) go_library( - name = "v2", + name = "shim", srcs = [ "api.go", "epoll.go", @@ -15,10 +15,10 @@ go_library( visibility = ["//shim:__subpackages__"], deps = [ "//pkg/cleanup", + "//pkg/shim/proc", "//pkg/shim/runsc", - "//pkg/shim/v1/proc", - "//pkg/shim/v1/utils", - "//pkg/shim/v2/runtimeoptions", + "//pkg/shim/runtimeoptions", + "//pkg/shim/utils", "//runsc/specutils", "@com_github_burntsushi_toml//:go_default_library", "@com_github_containerd_cgroups//:go_default_library", diff --git a/pkg/shim/v2/api.go b/pkg/shim/api.go index 5a60a04db..6d1741f0c 100644 --- a/pkg/shim/v2/api.go +++ b/pkg/shim/api.go @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package v2 +package shim import ( "github.com/containerd/containerd/api/events" diff --git a/pkg/shim/v2/epoll.go b/pkg/shim/epoll.go index 41232cca8..737d2b781 100644 --- a/pkg/shim/v2/epoll.go +++ b/pkg/shim/epoll.go @@ -15,7 +15,7 @@ // +build linux -package v2 +package shim import ( "context" diff --git a/pkg/shim/v2/options.go b/pkg/shim/options.go index 9db33fd1f..e40a1a07d 100644 --- a/pkg/shim/v2/options.go +++ b/pkg/shim/options.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package v2 +package shim const optionsType = "io.containerd.runsc.v1.options" diff --git a/pkg/shim/v1/proc/BUILD b/pkg/shim/proc/BUILD index 4377306af..544bdc170 100644 --- a/pkg/shim/v1/proc/BUILD +++ b/pkg/shim/proc/BUILD @@ -11,7 +11,7 @@ go_library( "init.go", "init_state.go", "io.go", - "process.go", + "proc.go", "types.go", "utils.go", ], diff --git a/pkg/shim/v1/proc/deleted_state.go b/pkg/shim/proc/deleted_state.go index d9b970c4d..d9b970c4d 100644 --- a/pkg/shim/v1/proc/deleted_state.go +++ b/pkg/shim/proc/deleted_state.go diff --git a/pkg/shim/v1/proc/exec.go b/pkg/shim/proc/exec.go index 1d1d90488..1d1d90488 100644 --- a/pkg/shim/v1/proc/exec.go +++ b/pkg/shim/proc/exec.go diff --git a/pkg/shim/v1/proc/exec_state.go b/pkg/shim/proc/exec_state.go index 4dcda8b44..4dcda8b44 100644 --- a/pkg/shim/v1/proc/exec_state.go +++ b/pkg/shim/proc/exec_state.go diff --git a/pkg/shim/v1/proc/init.go b/pkg/shim/proc/init.go index 9fd7d978c..cacaade88 100644 --- a/pkg/shim/v1/proc/init.go +++ b/pkg/shim/proc/init.go @@ -39,9 +39,6 @@ import ( "gvisor.dev/gvisor/pkg/shim/runsc" ) -// InitPidFile name of the file that contains the init pid. -const InitPidFile = "init.pid" - // Init represents an initial process for a container. type Init struct { wg sync.WaitGroup @@ -122,7 +119,8 @@ func (p *Init) Create(ctx context.Context, r *CreateConfig) (err error) { return fmt.Errorf("failed to create OCI runtime io pipes: %w", err) } } - pidFile := filepath.Join(p.Bundle, InitPidFile) + // pidFile is the file that will contain the sandbox pid. + pidFile := filepath.Join(p.Bundle, "init.pid") opts := &runsc.CreateOpts{ PidFile: pidFile, } diff --git a/pkg/shim/v1/proc/init_state.go b/pkg/shim/proc/init_state.go index 0065fc385..0065fc385 100644 --- a/pkg/shim/v1/proc/init_state.go +++ b/pkg/shim/proc/init_state.go diff --git a/pkg/shim/v1/proc/io.go b/pkg/shim/proc/io.go index 34d825fb7..34d825fb7 100644 --- a/pkg/shim/v1/proc/io.go +++ b/pkg/shim/proc/io.go diff --git a/pkg/shim/v1/proc/process.go b/pkg/shim/proc/proc.go index e8315326d..edba3fca5 100644 --- a/pkg/shim/v1/proc/process.go +++ b/pkg/shim/proc/proc.go @@ -13,7 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package proc contains process-related utilities. +// Package proc is responsible to manage the communication between the shim and +// the sandbox process running the container. package proc import ( diff --git a/pkg/shim/v1/proc/types.go b/pkg/shim/proc/types.go index fc182cf5e..fc182cf5e 100644 --- a/pkg/shim/v1/proc/types.go +++ b/pkg/shim/proc/types.go diff --git a/pkg/shim/v1/proc/utils.go b/pkg/shim/proc/utils.go index 7c2c409af..7c2c409af 100644 --- a/pkg/shim/v1/proc/utils.go +++ b/pkg/shim/proc/utils.go diff --git a/pkg/shim/v2/runtimeoptions/BUILD b/pkg/shim/runtimeoptions/BUILD index abb8c3be3..029be7c09 100644 --- a/pkg/shim/v2/runtimeoptions/BUILD +++ b/pkg/shim/runtimeoptions/BUILD @@ -15,7 +15,7 @@ go_library( "runtimeoptions.go", "runtimeoptions_cri.go", ], - visibility = ["//pkg/shim/v2:__pkg__"], + visibility = ["//pkg/shim:__pkg__"], deps = ["@com_github_gogo_protobuf//proto:go_default_library"], ) diff --git a/pkg/shim/v2/runtimeoptions/runtimeoptions.go b/pkg/shim/runtimeoptions/runtimeoptions.go index 072dd87f0..072dd87f0 100644 --- a/pkg/shim/v2/runtimeoptions/runtimeoptions.go +++ b/pkg/shim/runtimeoptions/runtimeoptions.go diff --git a/pkg/shim/v2/runtimeoptions/runtimeoptions.proto b/pkg/shim/runtimeoptions/runtimeoptions.proto index 057032e34..057032e34 100644 --- a/pkg/shim/v2/runtimeoptions/runtimeoptions.proto +++ b/pkg/shim/runtimeoptions/runtimeoptions.proto diff --git a/pkg/shim/v2/runtimeoptions/runtimeoptions_cri.go b/pkg/shim/runtimeoptions/runtimeoptions_cri.go index e6102b4cf..e6102b4cf 100644 --- a/pkg/shim/v2/runtimeoptions/runtimeoptions_cri.go +++ b/pkg/shim/runtimeoptions/runtimeoptions_cri.go diff --git a/pkg/shim/v2/runtimeoptions/runtimeoptions_test.go b/pkg/shim/runtimeoptions/runtimeoptions_test.go index c59a2400e..c59a2400e 100644 --- a/pkg/shim/v2/runtimeoptions/runtimeoptions_test.go +++ b/pkg/shim/runtimeoptions/runtimeoptions_test.go diff --git a/pkg/shim/v2/service.go b/pkg/shim/service.go index 6aaf5fab8..9aba26ac7 100644 --- a/pkg/shim/v2/service.go +++ b/pkg/shim/service.go @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package v2 implements Containerd Shim v2 interface. -package v2 +// Package shim implements Containerd Shim v2 interface. +package shim import ( "context" @@ -49,10 +49,10 @@ import ( "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/cleanup" + "gvisor.dev/gvisor/pkg/shim/proc" "gvisor.dev/gvisor/pkg/shim/runsc" - "gvisor.dev/gvisor/pkg/shim/v1/proc" - "gvisor.dev/gvisor/pkg/shim/v1/utils" - "gvisor.dev/gvisor/pkg/shim/v2/runtimeoptions" + "gvisor.dev/gvisor/pkg/shim/runtimeoptions" + "gvisor.dev/gvisor/pkg/shim/utils" "gvisor.dev/gvisor/runsc/specutils" ) diff --git a/pkg/shim/v2/service_linux.go b/pkg/shim/service_linux.go index 1800ab90b..11622ed60 100644 --- a/pkg/shim/v2/service_linux.go +++ b/pkg/shim/service_linux.go @@ -15,7 +15,7 @@ // +build linux -package v2 +package shim import ( "context" diff --git a/pkg/shim/v2/state.go b/pkg/shim/state.go index 1f4be33d3..5e9e92ec3 100644 --- a/pkg/shim/v2/state.go +++ b/pkg/shim/state.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package v2 +package shim import ( "encoding/json" diff --git a/pkg/shim/v1/utils/BUILD b/pkg/shim/utils/BUILD index 54a0aabb7..54a0aabb7 100644 --- a/pkg/shim/v1/utils/BUILD +++ b/pkg/shim/utils/BUILD diff --git a/pkg/shim/v1/utils/annotations.go b/pkg/shim/utils/annotations.go index 1e9d3f365..1e9d3f365 100644 --- a/pkg/shim/v1/utils/annotations.go +++ b/pkg/shim/utils/annotations.go diff --git a/pkg/shim/v1/utils/utils.go b/pkg/shim/utils/utils.go index 21e75d16d..7b1cd983e 100644 --- a/pkg/shim/v1/utils/utils.go +++ b/pkg/shim/utils/utils.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package utils contains utility functions. +// Package utils container miscellaneous utility function used by the shim. package utils import ( diff --git a/pkg/shim/v1/utils/volumes.go b/pkg/shim/utils/volumes.go index 52a428179..52a428179 100644 --- a/pkg/shim/v1/utils/volumes.go +++ b/pkg/shim/utils/volumes.go diff --git a/pkg/shim/v1/utils/volumes_test.go b/pkg/shim/utils/volumes_test.go index 3e02c6151..3e02c6151 100644 --- a/pkg/shim/v1/utils/volumes_test.go +++ b/pkg/shim/utils/volumes_test.go diff --git a/pkg/shim/v1/shim/BUILD b/pkg/shim/v1/shim/BUILD deleted file mode 100644 index e5b6bf186..000000000 --- a/pkg/shim/v1/shim/BUILD +++ /dev/null @@ -1,41 +0,0 @@ -load("//tools:defs.bzl", "go_library") - -package(licenses = ["notice"]) - -go_library( - name = "shim", - srcs = [ - "api.go", - "platform.go", - "service.go", - "shim.go", - ], - visibility = [ - "//pkg/shim:__subpackages__", - "//shim:__subpackages__", - ], - deps = [ - "//pkg/shim/runsc", - "//pkg/shim/v1/proc", - "//pkg/shim/v1/utils", - "@com_github_containerd_console//:go_default_library", - "@com_github_containerd_containerd//api/events:go_default_library", - "@com_github_containerd_containerd//api/types/task:go_default_library", - "@com_github_containerd_containerd//errdefs:go_default_library", - "@com_github_containerd_containerd//events:go_default_library", - "@com_github_containerd_containerd//log:go_default_library", - "@com_github_containerd_containerd//mount:go_default_library", - "@com_github_containerd_containerd//namespaces:go_default_library", - "@com_github_containerd_containerd//pkg/process:go_default_library", - "@com_github_containerd_containerd//pkg/stdio:go_default_library", - "@com_github_containerd_containerd//runtime:go_default_library", - "@com_github_containerd_containerd//runtime/linux/runctypes:go_default_library", - "@com_github_containerd_containerd//runtime/v1/shim/v1:go_default_library", - "@com_github_containerd_containerd//sys/reaper:go_default_library", - "@com_github_containerd_fifo//:go_default_library", - "@com_github_containerd_typeurl//:go_default_library", - "@com_github_gogo_protobuf//types:go_default_library", - "@org_golang_google_grpc//codes:go_default_library", - "@org_golang_google_grpc//status:go_default_library", - ], -) diff --git a/pkg/shim/v1/shim/api.go b/pkg/shim/v1/shim/api.go deleted file mode 100644 index 8200eb012..000000000 --- a/pkg/shim/v1/shim/api.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2018 The containerd Authors. -// Copyright 2019 The gVisor 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 -// -// https://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 shim - -import ( - "github.com/containerd/containerd/api/events" -) - -// TaskCreate is an alias for events.TaskCreate. -type TaskCreate = events.TaskCreate - -// TaskStart is an alias for events.TaskStart. -type TaskStart = events.TaskStart - -// TaskOOM is an alias for events.TaskOOM. -type TaskOOM = events.TaskOOM - -// TaskExit is an alias for events.TaskExit. -type TaskExit = events.TaskExit - -// TaskDelete is an alias for events.TaskDelete. -type TaskDelete = events.TaskDelete - -// TaskExecAdded is an alias for events.TaskExecAdded. -type TaskExecAdded = events.TaskExecAdded - -// TaskExecStarted is an alias for events.TaskExecStarted. -type TaskExecStarted = events.TaskExecStarted diff --git a/pkg/shim/v1/shim/platform.go b/pkg/shim/v1/shim/platform.go deleted file mode 100644 index f590f80ef..000000000 --- a/pkg/shim/v1/shim/platform.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2018 The containerd Authors. -// Copyright 2019 The gVisor 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 -// -// https://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 shim - -import ( - "context" - "fmt" - "io" - "sync" - "syscall" - - "github.com/containerd/console" - "github.com/containerd/fifo" -) - -type linuxPlatform struct { - epoller *console.Epoller -} - -func (p *linuxPlatform) CopyConsole(ctx context.Context, console console.Console, stdin, stdout, stderr string, wg *sync.WaitGroup) (console.Console, error) { - if p.epoller == nil { - return nil, fmt.Errorf("uninitialized epoller") - } - - epollConsole, err := p.epoller.Add(console) - if err != nil { - return nil, err - } - - if stdin != "" { - in, err := fifo.OpenFifo(ctx, stdin, syscall.O_RDONLY, 0) - if err != nil { - return nil, err - } - go func() { - p := bufPool.Get().(*[]byte) - defer bufPool.Put(p) - io.CopyBuffer(epollConsole, in, *p) - }() - } - - outw, err := fifo.OpenFifo(ctx, stdout, syscall.O_WRONLY, 0) - if err != nil { - return nil, err - } - outr, err := fifo.OpenFifo(ctx, stdout, syscall.O_RDONLY, 0) - if err != nil { - return nil, err - } - wg.Add(1) - go func() { - p := bufPool.Get().(*[]byte) - defer bufPool.Put(p) - io.CopyBuffer(outw, epollConsole, *p) - epollConsole.Close() - outr.Close() - outw.Close() - wg.Done() - }() - return epollConsole, nil -} - -func (p *linuxPlatform) ShutdownConsole(ctx context.Context, cons console.Console) error { - if p.epoller == nil { - return fmt.Errorf("uninitialized epoller") - } - epollConsole, ok := cons.(*console.EpollConsole) - if !ok { - return fmt.Errorf("expected EpollConsole, got %#v", cons) - } - return epollConsole.Shutdown(p.epoller.CloseConsole) -} - -func (p *linuxPlatform) Close() error { - return p.epoller.Close() -} - -// initialize a single epoll fd to manage our consoles. `initPlatform` should -// only be called once. -func (s *Service) initPlatform() error { - if s.platform != nil { - return nil - } - epoller, err := console.NewEpoller() - if err != nil { - return fmt.Errorf("failed to initialize epoller: %w", err) - } - s.platform = &linuxPlatform{ - epoller: epoller, - } - go epoller.Wait() - return nil -} diff --git a/pkg/shim/v1/shim/service.go b/pkg/shim/v1/shim/service.go deleted file mode 100644 index 80aa59b33..000000000 --- a/pkg/shim/v1/shim/service.go +++ /dev/null @@ -1,572 +0,0 @@ -// Copyright 2018 The containerd Authors. -// Copyright 2019 The gVisor 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 -// -// https://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 shim - -import ( - "context" - "fmt" - "os" - "path/filepath" - "sync" - - "github.com/containerd/console" - "github.com/containerd/containerd/api/types/task" - "github.com/containerd/containerd/errdefs" - "github.com/containerd/containerd/events" - "github.com/containerd/containerd/log" - "github.com/containerd/containerd/mount" - "github.com/containerd/containerd/namespaces" - "github.com/containerd/containerd/pkg/process" - "github.com/containerd/containerd/pkg/stdio" - "github.com/containerd/containerd/runtime" - "github.com/containerd/containerd/runtime/linux/runctypes" - shim "github.com/containerd/containerd/runtime/v1/shim/v1" - "github.com/containerd/containerd/sys/reaper" - "github.com/containerd/typeurl" - "github.com/gogo/protobuf/types" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - - "gvisor.dev/gvisor/pkg/shim/runsc" - "gvisor.dev/gvisor/pkg/shim/v1/proc" - "gvisor.dev/gvisor/pkg/shim/v1/utils" -) - -var ( - empty = &types.Empty{} - bufPool = sync.Pool{ - New: func() interface{} { - buffer := make([]byte, 32<<10) - return &buffer - }, - } -) - -// Config contains shim specific configuration. -type Config struct { - Path string - Namespace string - WorkDir string - RuntimeRoot string - RunscConfig map[string]string -} - -// NewService returns a new shim service that can be used via GRPC. -func NewService(config Config, publisher events.Publisher) (*Service, error) { - if config.Namespace == "" { - return nil, fmt.Errorf("shim namespace cannot be empty") - } - ctx := namespaces.WithNamespace(context.Background(), config.Namespace) - s := &Service{ - config: config, - context: ctx, - processes: make(map[string]process.Process), - events: make(chan interface{}, 128), - ec: proc.ExitCh, - } - go s.processExits() - if err := s.initPlatform(); err != nil { - return nil, fmt.Errorf("failed to initialized platform behavior: %w", err) - } - go s.forward(publisher) - return s, nil -} - -// Service is the shim implementation of a remote shim over GRPC. -type Service struct { - mu sync.Mutex - - config Config - context context.Context - processes map[string]process.Process - events chan interface{} - platform stdio.Platform - ec chan proc.Exit - - // Filled by Create() - id string - bundle string -} - -// Create creates a new initial process and container with the underlying OCI runtime. -func (s *Service) Create(ctx context.Context, r *shim.CreateTaskRequest) (_ *shim.CreateTaskResponse, err error) { - s.mu.Lock() - defer s.mu.Unlock() - - var mounts []proc.Mount - for _, m := range r.Rootfs { - mounts = append(mounts, proc.Mount{ - Type: m.Type, - Source: m.Source, - Target: m.Target, - Options: m.Options, - }) - } - - rootfs := filepath.Join(r.Bundle, "rootfs") - if err := os.Mkdir(rootfs, 0711); err != nil && !os.IsExist(err) { - return nil, err - } - - config := &proc.CreateConfig{ - ID: r.ID, - Bundle: r.Bundle, - Runtime: r.Runtime, - Rootfs: mounts, - Terminal: r.Terminal, - Stdin: r.Stdin, - Stdout: r.Stdout, - Stderr: r.Stderr, - } - defer func() { - if err != nil { - if err2 := mount.UnmountAll(rootfs, 0); err2 != nil { - log.G(ctx).WithError(err2).Warn("Failed to cleanup rootfs mount") - } - } - }() - for _, rm := range mounts { - m := &mount.Mount{ - Type: rm.Type, - Source: rm.Source, - Options: rm.Options, - } - if err := m.Mount(rootfs); err != nil { - return nil, fmt.Errorf("failed to mount rootfs component %v: %w", m, err) - } - } - process, err := newInit( - s.config.Path, - s.config.WorkDir, - s.config.RuntimeRoot, - s.config.Namespace, - s.config.RunscConfig, - s.platform, - config, - r.Options, - ) - if err := process.Create(ctx, config); err != nil { - return nil, errdefs.ToGRPC(err) - } - // Save the main task id and bundle to the shim for additional - // requests. - s.id = r.ID - s.bundle = r.Bundle - pid := process.Pid() - s.processes[r.ID] = process - return &shim.CreateTaskResponse{ - Pid: uint32(pid), - }, nil -} - -// Start starts a process. -func (s *Service) Start(ctx context.Context, r *shim.StartRequest) (*shim.StartResponse, error) { - p, err := s.getExecProcess(r.ID) - if err != nil { - return nil, err - } - if err := p.Start(ctx); err != nil { - return nil, err - } - return &shim.StartResponse{ - ID: p.ID(), - Pid: uint32(p.Pid()), - }, nil -} - -// Delete deletes the initial process and container. -func (s *Service) Delete(ctx context.Context, r *types.Empty) (*shim.DeleteResponse, error) { - p, err := s.getInitProcess() - if err != nil { - return nil, err - } - if err := p.Delete(ctx); err != nil { - return nil, err - } - s.mu.Lock() - delete(s.processes, s.id) - s.mu.Unlock() - s.platform.Close() - return &shim.DeleteResponse{ - ExitStatus: uint32(p.ExitStatus()), - ExitedAt: p.ExitedAt(), - Pid: uint32(p.Pid()), - }, nil -} - -// DeleteProcess deletes an exec'd process. -func (s *Service) DeleteProcess(ctx context.Context, r *shim.DeleteProcessRequest) (*shim.DeleteResponse, error) { - if r.ID == s.id { - return nil, status.Errorf(codes.InvalidArgument, "cannot delete init process with DeleteProcess") - } - p, err := s.getExecProcess(r.ID) - if err != nil { - return nil, err - } - if err := p.Delete(ctx); err != nil { - return nil, err - } - s.mu.Lock() - delete(s.processes, r.ID) - s.mu.Unlock() - return &shim.DeleteResponse{ - ExitStatus: uint32(p.ExitStatus()), - ExitedAt: p.ExitedAt(), - Pid: uint32(p.Pid()), - }, nil -} - -// Exec spawns an additional process inside the container. -func (s *Service) Exec(ctx context.Context, r *shim.ExecProcessRequest) (*types.Empty, error) { - s.mu.Lock() - - if p := s.processes[r.ID]; p != nil { - s.mu.Unlock() - return nil, errdefs.ToGRPCf(errdefs.ErrAlreadyExists, "id %s", r.ID) - } - - p := s.processes[s.id] - s.mu.Unlock() - if p == nil { - return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created") - } - - process, err := p.(*proc.Init).Exec(ctx, s.config.Path, &proc.ExecConfig{ - ID: r.ID, - Terminal: r.Terminal, - Stdin: r.Stdin, - Stdout: r.Stdout, - Stderr: r.Stderr, - Spec: r.Spec, - }) - if err != nil { - return nil, errdefs.ToGRPC(err) - } - s.mu.Lock() - s.processes[r.ID] = process - s.mu.Unlock() - return empty, nil -} - -// ResizePty resises the terminal of a process. -func (s *Service) ResizePty(ctx context.Context, r *shim.ResizePtyRequest) (*types.Empty, error) { - if r.ID == "" { - return nil, errdefs.ToGRPCf(errdefs.ErrInvalidArgument, "id not provided") - } - ws := console.WinSize{ - Width: uint16(r.Width), - Height: uint16(r.Height), - } - p, err := s.getExecProcess(r.ID) - if err != nil { - return nil, err - } - if err := p.Resize(ws); err != nil { - return nil, errdefs.ToGRPC(err) - } - return empty, nil -} - -// State returns runtime state information for a process. -func (s *Service) State(ctx context.Context, r *shim.StateRequest) (*shim.StateResponse, error) { - p, err := s.getExecProcess(r.ID) - if err != nil { - return nil, err - } - st, err := p.Status(ctx) - if err != nil { - return nil, err - } - status := task.StatusUnknown - switch st { - case "created": - status = task.StatusCreated - case "running": - status = task.StatusRunning - case "stopped": - status = task.StatusStopped - } - sio := p.Stdio() - return &shim.StateResponse{ - ID: p.ID(), - Bundle: s.bundle, - Pid: uint32(p.Pid()), - Status: status, - Stdin: sio.Stdin, - Stdout: sio.Stdout, - Stderr: sio.Stderr, - Terminal: sio.Terminal, - ExitStatus: uint32(p.ExitStatus()), - ExitedAt: p.ExitedAt(), - }, nil -} - -// Pause pauses the container. -func (s *Service) Pause(ctx context.Context, r *types.Empty) (*types.Empty, error) { - return empty, errdefs.ToGRPC(errdefs.ErrNotImplemented) -} - -// Resume resumes the container. -func (s *Service) Resume(ctx context.Context, r *types.Empty) (*types.Empty, error) { - return empty, errdefs.ToGRPC(errdefs.ErrNotImplemented) -} - -// Kill kills a process with the provided signal. -func (s *Service) Kill(ctx context.Context, r *shim.KillRequest) (*types.Empty, error) { - if r.ID == "" { - p, err := s.getInitProcess() - if err != nil { - return nil, err - } - if err := p.Kill(ctx, r.Signal, r.All); err != nil { - return nil, errdefs.ToGRPC(err) - } - return empty, nil - } - - p, err := s.getExecProcess(r.ID) - if err != nil { - return nil, err - } - if err := p.Kill(ctx, r.Signal, r.All); err != nil { - return nil, errdefs.ToGRPC(err) - } - return empty, nil -} - -// ListPids returns all pids inside the container. -func (s *Service) ListPids(ctx context.Context, r *shim.ListPidsRequest) (*shim.ListPidsResponse, error) { - pids, err := s.getContainerPids(ctx, r.ID) - if err != nil { - return nil, errdefs.ToGRPC(err) - } - var processes []*task.ProcessInfo - for _, pid := range pids { - pInfo := task.ProcessInfo{ - Pid: pid, - } - for _, p := range s.processes { - if p.Pid() == int(pid) { - d := &runctypes.ProcessDetails{ - ExecID: p.ID(), - } - a, err := typeurl.MarshalAny(d) - if err != nil { - return nil, fmt.Errorf("failed to marshal process %d info: %w", pid, err) - } - pInfo.Info = a - break - } - } - processes = append(processes, &pInfo) - } - return &shim.ListPidsResponse{ - Processes: processes, - }, nil -} - -// CloseIO closes the I/O context of a process. -func (s *Service) CloseIO(ctx context.Context, r *shim.CloseIORequest) (*types.Empty, error) { - p, err := s.getExecProcess(r.ID) - if err != nil { - return nil, err - } - if stdin := p.Stdin(); stdin != nil { - if err := stdin.Close(); err != nil { - return nil, fmt.Errorf("close stdin: %w", err) - } - } - return empty, nil -} - -// Checkpoint checkpoints the container. -func (s *Service) Checkpoint(ctx context.Context, r *shim.CheckpointTaskRequest) (*types.Empty, error) { - return empty, errdefs.ToGRPC(errdefs.ErrNotImplemented) -} - -// ShimInfo returns shim information such as the shim's pid. -func (s *Service) ShimInfo(ctx context.Context, r *types.Empty) (*shim.ShimInfoResponse, error) { - return &shim.ShimInfoResponse{ - ShimPid: uint32(os.Getpid()), - }, nil -} - -// Update updates a running container. -func (s *Service) Update(ctx context.Context, r *shim.UpdateTaskRequest) (*types.Empty, error) { - return empty, errdefs.ToGRPC(errdefs.ErrNotImplemented) -} - -// Wait waits for a process to exit. -func (s *Service) Wait(ctx context.Context, r *shim.WaitRequest) (*shim.WaitResponse, error) { - p, err := s.getExecProcess(r.ID) - if err != nil { - return nil, err - } - p.Wait() - - return &shim.WaitResponse{ - ExitStatus: uint32(p.ExitStatus()), - ExitedAt: p.ExitedAt(), - }, nil -} - -func (s *Service) processExits() { - for e := range s.ec { - s.checkProcesses(e) - } -} - -func (s *Service) allProcesses() []process.Process { - s.mu.Lock() - defer s.mu.Unlock() - - res := make([]process.Process, 0, len(s.processes)) - for _, p := range s.processes { - res = append(res, p) - } - return res -} - -func (s *Service) checkProcesses(e proc.Exit) { - for _, p := range s.allProcesses() { - if p.ID() == e.ID { - if ip, ok := p.(*proc.Init); ok { - // Ensure all children are killed. - if err := ip.KillAll(s.context); err != nil { - log.G(s.context).WithError(err).WithField("id", ip.ID()). - Error("failed to kill init's children") - } - } - p.SetExited(e.Status) - s.events <- &TaskExit{ - ContainerID: s.id, - ID: p.ID(), - Pid: uint32(p.Pid()), - ExitStatus: uint32(e.Status), - ExitedAt: p.ExitedAt(), - } - return - } - } -} - -func (s *Service) getContainerPids(ctx context.Context, id string) ([]uint32, error) { - p, err := s.getInitProcess() - if err != nil { - return nil, err - } - - ps, err := p.(*proc.Init).Runtime().Ps(ctx, id) - if err != nil { - return nil, err - } - pids := make([]uint32, 0, len(ps)) - for _, pid := range ps { - pids = append(pids, uint32(pid)) - } - return pids, nil -} - -func (s *Service) forward(publisher events.Publisher) { - for e := range s.events { - if err := publisher.Publish(s.context, getTopic(s.context, e), e); err != nil { - log.G(s.context).WithError(err).Error("post event") - } - } -} - -// getInitProcess returns the init process. -func (s *Service) getInitProcess() (process.Process, error) { - s.mu.Lock() - defer s.mu.Unlock() - p := s.processes[s.id] - if p == nil { - return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created") - } - return p, nil -} - -// getExecProcess returns the given exec process. -func (s *Service) getExecProcess(id string) (process.Process, error) { - s.mu.Lock() - defer s.mu.Unlock() - p := s.processes[id] - if p == nil { - return nil, errdefs.ToGRPCf(errdefs.ErrNotFound, "process %s does not exist", id) - } - return p, nil -} - -func getTopic(ctx context.Context, e interface{}) string { - switch e.(type) { - case *TaskCreate: - return runtime.TaskCreateEventTopic - case *TaskStart: - return runtime.TaskStartEventTopic - case *TaskOOM: - return runtime.TaskOOMEventTopic - case *TaskExit: - return runtime.TaskExitEventTopic - case *TaskDelete: - return runtime.TaskDeleteEventTopic - case *TaskExecAdded: - return runtime.TaskExecAddedEventTopic - case *TaskExecStarted: - return runtime.TaskExecStartedEventTopic - default: - log.L.Printf("no topic for type %#v", e) - } - return runtime.TaskUnknownTopic -} - -func newInit(path, workDir, runtimeRoot, namespace string, config map[string]string, platform stdio.Platform, r *proc.CreateConfig, options *types.Any) (*proc.Init, error) { - var opts runctypes.CreateOptions - if options != nil { - v, err := typeurl.UnmarshalAny(options) - if err != nil { - return nil, err - } - opts = *v.(*runctypes.CreateOptions) - } - - spec, err := utils.ReadSpec(r.Bundle) - if err != nil { - return nil, fmt.Errorf("read oci spec: %w", err) - } - if err := utils.UpdateVolumeAnnotations(r.Bundle, spec); err != nil { - return nil, fmt.Errorf("update volume annotations: %w", err) - } - - runsc.FormatRunscLogPath(r.ID, config) - rootfs := filepath.Join(path, "rootfs") - runtime := proc.NewRunsc(runtimeRoot, path, namespace, r.Runtime, config) - p := proc.New(r.ID, runtime, stdio.Stdio{ - Stdin: r.Stdin, - Stdout: r.Stdout, - Stderr: r.Stderr, - Terminal: r.Terminal, - }) - p.Bundle = r.Bundle - p.Platform = platform - p.Rootfs = rootfs - p.WorkDir = workDir - p.IoUID = int(opts.IoUid) - p.IoGID = int(opts.IoGid) - p.Sandbox = utils.IsSandbox(spec) - p.UserLog = utils.UserLogPath(spec) - p.Monitor = reaper.Default - return p, nil -} diff --git a/pkg/shim/v1/shim/shim.go b/pkg/shim/v1/shim/shim.go deleted file mode 100644 index 1855a8769..000000000 --- a/pkg/shim/v1/shim/shim.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2018 The containerd Authors. -// Copyright 2019 The gVisor 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 -// -// https://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 shim contains the core containerd shim implementation. -package shim diff --git a/pkg/test/criutil/criutil.go b/pkg/test/criutil/criutil.go index e41769017..3b41a2824 100644 --- a/pkg/test/criutil/criutil.go +++ b/pkg/test/criutil/criutil.go @@ -36,7 +36,6 @@ import ( type Crictl struct { logger testutil.Logger endpoint string - runpArgs []string cleanup []func() } @@ -72,14 +71,13 @@ func ResolvePath(executable string) string { // NewCrictl returns a Crictl configured with a timeout and an endpoint over // which it will talk to containerd. -func NewCrictl(logger testutil.Logger, endpoint string, runpArgs []string) *Crictl { +func NewCrictl(logger testutil.Logger, endpoint string) *Crictl { // Attempt to find the executable, but don't bother propagating the // error at this point. The first command executed will return with a // binary not found error. return &Crictl{ logger: logger, endpoint: endpoint, - runpArgs: runpArgs, } } diff --git a/shim/BUILD b/shim/BUILD index 8d29c459b..434269d31 100644 --- a/shim/BUILD +++ b/shim/BUILD @@ -1,7 +1,17 @@ -load("//tools:defs.bzl", "pkg_tar") +load("//tools:defs.bzl", "go_binary", "pkg_tar") package(licenses = ["notice"]) +go_binary( + name = "containerd-shim-runsc-v1", + srcs = ["main.go"], + static = True, + visibility = [ + "//visibility:public", + ], + deps = ["//shim/cli"], +) + pkg_tar( name = "config", srcs = [ diff --git a/shim/README.md b/shim/README.md index 75daf00ac..8ae33a272 100644 --- a/shim/README.md +++ b/shim/README.md @@ -1,10 +1,8 @@ # Shim Overview -Integration with containerd is done via a [shim][shims]. There are various shims -supported for different versions of [containerd][containerd]. - -- [Containerd 1.2+ (shim v2)](https://gvisor.dev/docs/user_guide/containerd/quick_start/) -- [Containerd 1.1 (shim v1)](https://gvisor.dev/docs/user_guide/containerd/containerd_11/) +Integration with containerd is done via a [shim][shims]. The shim implements +[containerd][containerd] shim v2 and is supported with containerd 1.3 and newer. +[Here is how to get started](https://gvisor.dev/docs/user_guide/containerd/quick_start/) [containerd]: https://github.com/containerd/containerd [shims]: https://iximiuz.com/en/posts/implementing-container-runtime-shim/ diff --git a/shim/v2/cli/BUILD b/shim/cli/BUILD index 6681e0772..665dcc5a1 100644 --- a/shim/v2/cli/BUILD +++ b/shim/cli/BUILD @@ -7,10 +7,10 @@ go_library( srcs = ["cli.go"], visibility = [ "//:__pkg__", - "//shim/v2:__pkg__", + "//shim:__pkg__", ], deps = [ - "//pkg/shim/v2", + "//pkg/shim", "@com_github_containerd_containerd//runtime/v2/shim:go_default_library", ], ) diff --git a/shim/v2/cli/cli.go b/shim/cli/cli.go index 3d6644feb..068976c79 100644 --- a/shim/v2/cli/cli.go +++ b/shim/cli/cli.go @@ -17,12 +17,12 @@ package cli import ( - "github.com/containerd/containerd/runtime/v2/shim" + containerdshim "github.com/containerd/containerd/runtime/v2/shim" - "gvisor.dev/gvisor/pkg/shim/v2" + "gvisor.dev/gvisor/pkg/shim" ) // Main is the main entrypoint. func Main() { - shim.Run("io.containerd.runsc.v1", v2.New) + containerdshim.Run("io.containerd.runsc.v1", shim.New) } diff --git a/shim/v2/main.go b/shim/main.go index 3680cdf9c..b87a20d08 100644 --- a/shim/v2/main.go +++ b/shim/main.go @@ -16,7 +16,7 @@ package main import ( - "gvisor.dev/gvisor/shim/v2/cli" + "gvisor.dev/gvisor/shim/cli" ) func main() { diff --git a/shim/v1/BUILD b/shim/v1/BUILD deleted file mode 100644 index 3614a67d1..000000000 --- a/shim/v1/BUILD +++ /dev/null @@ -1,13 +0,0 @@ -load("//tools:defs.bzl", "go_binary") - -package(licenses = ["notice"]) - -go_binary( - name = "gvisor-containerd-shim", - srcs = ["main.go"], - static = True, - visibility = [ - "//visibility:public", - ], - deps = ["//shim/v1/cli"], -) diff --git a/shim/v1/cli/BUILD b/shim/v1/cli/BUILD deleted file mode 100644 index 0bbdc4add..000000000 --- a/shim/v1/cli/BUILD +++ /dev/null @@ -1,30 +0,0 @@ -load("//tools:defs.bzl", "go_library") - -package(licenses = ["notice"]) - -go_library( - name = "cli", - srcs = [ - "api.go", - "cli.go", - "config.go", - ], - visibility = [ - "//:__pkg__", - "//shim/v1:__pkg__", - ], - deps = [ - "//pkg/shim/runsc", - "//pkg/shim/v1/shim", - "@com_github_burntsushi_toml//:go_default_library", - "@com_github_containerd_containerd//events:go_default_library", - "@com_github_containerd_containerd//namespaces:go_default_library", - "@com_github_containerd_containerd//runtime/v1/shim/v1:go_default_library", - "@com_github_containerd_containerd//sys:go_default_library", - "@com_github_containerd_containerd//sys/reaper:go_default_library", - "@com_github_containerd_ttrpc//:go_default_library", - "@com_github_containerd_typeurl//:go_default_library", - "@com_github_gogo_protobuf//types:go_default_library", - "@org_golang_x_sys//unix:go_default_library", - ], -) diff --git a/shim/v1/cli/api.go b/shim/v1/cli/api.go deleted file mode 100644 index 050793094..000000000 --- a/shim/v1/cli/api.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2018 The containerd Authors. -// Copyright 2019 The gVisor 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 -// -// https://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 cli - -import ( - shim "github.com/containerd/containerd/runtime/v1/shim/v1" -) - -type KillRequest = shim.KillRequest - -var registerShimService = shim.RegisterShimService diff --git a/shim/v1/cli/cli.go b/shim/v1/cli/cli.go deleted file mode 100644 index cdf60cc2e..000000000 --- a/shim/v1/cli/cli.go +++ /dev/null @@ -1,266 +0,0 @@ -// Copyright 2018 The containerd Authors. -// Copyright 2019 The gVisor 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 -// -// https://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 cli defines the command line interface for the V1 shim. -package cli - -import ( - "bytes" - "context" - "flag" - "fmt" - "log" - "net" - "os" - "os/exec" - "os/signal" - "path/filepath" - "strings" - "sync" - "syscall" - - "github.com/containerd/containerd/events" - "github.com/containerd/containerd/namespaces" - "github.com/containerd/containerd/sys" - "github.com/containerd/containerd/sys/reaper" - "github.com/containerd/ttrpc" - "github.com/containerd/typeurl" - "github.com/gogo/protobuf/types" - "golang.org/x/sys/unix" - - "gvisor.dev/gvisor/pkg/shim/runsc" - "gvisor.dev/gvisor/pkg/shim/v1/shim" -) - -var ( - debugFlag bool - namespaceFlag string - socketFlag string - addressFlag string - workdirFlag string - runtimeRootFlag string - containerdBinaryFlag string - shimConfigFlag string -) - -// Containerd defaults to runc, unless another runtime is explicitly specified. -// We keep the same default to make the default behavior consistent. -const defaultRoot = "/run/containerd/runc" - -func init() { - flag.BoolVar(&debugFlag, "debug", false, "enable debug output in logs") - flag.StringVar(&namespaceFlag, "namespace", "", "namespace that owns the shim") - flag.StringVar(&socketFlag, "socket", "", "abstract socket path to serve") - flag.StringVar(&addressFlag, "address", "", "grpc address back to main containerd") - flag.StringVar(&workdirFlag, "workdir", "", "path used to storge large temporary data") - flag.StringVar(&runtimeRootFlag, "runtime-root", defaultRoot, "root directory for the runtime") - - // Currently, the `containerd publish` utility is embedded in the - // daemon binary. The daemon invokes `containerd-shim - // -containerd-binary ...` with its own os.Executable() path. - flag.StringVar(&containerdBinaryFlag, "containerd-binary", "containerd", "path to containerd binary (used for `containerd publish`)") - flag.StringVar(&shimConfigFlag, "config", "/etc/containerd/runsc.toml", "path to the shim configuration file") -} - -// Main is the main entrypoint. -func Main() { - flag.Parse() - - // This is a hack. Exec current process to run standard containerd-shim - // if runtime root is not `runsc`. We don't need this for shim v2 api. - if filepath.Base(runtimeRootFlag) != "runsc" { - if err := executeRuncShim(); err != nil { - fmt.Fprintf(os.Stderr, "gvisor-containerd-shim: %s\n", err) - os.Exit(1) - } - } - - // Run regular shim if needed. - if err := executeShim(); err != nil { - fmt.Fprintf(os.Stderr, "gvisor-containerd-shim: %s\n", err) - os.Exit(1) - } -} - -// executeRuncShim execs current process to a containerd-shim process and -// retains all flags and envs. -func executeRuncShim() error { - c, err := loadConfig(shimConfigFlag) - if err != nil && !os.IsNotExist(err) { - return fmt.Errorf("failed to load shim config: %w", err) - } - shimPath := c.RuncShim - if shimPath == "" { - shimPath, err = exec.LookPath("containerd-shim") - if err != nil { - return fmt.Errorf("lookup containerd-shim failed: %w", err) - } - } - - args := append([]string{shimPath}, os.Args[1:]...) - if err := syscall.Exec(shimPath, args, os.Environ()); err != nil { - return fmt.Errorf("exec containerd-shim @ %q failed: %w", shimPath, err) - } - return nil -} - -func executeShim() error { - // start handling signals as soon as possible so that things are - // properly reaped or if runtime exits before we hit the handler. - signals, err := setupSignals() - if err != nil { - return err - } - path, err := os.Getwd() - if err != nil { - return err - } - server, err := ttrpc.NewServer(ttrpc.WithServerHandshaker(ttrpc.UnixSocketRequireSameUser())) - if err != nil { - return fmt.Errorf("failed creating server: %w", err) - } - c, err := loadConfig(shimConfigFlag) - if err != nil && !os.IsNotExist(err) { - return fmt.Errorf("failed to load shim config: %w", err) - } - sv, err := shim.NewService( - shim.Config{ - Path: path, - Namespace: namespaceFlag, - WorkDir: workdirFlag, - RuntimeRoot: runtimeRootFlag, - RunscConfig: c.RunscConfig, - }, - &remoteEventsPublisher{address: addressFlag}, - ) - if err != nil { - return err - } - registerShimService(server, sv) - if err := serve(server, socketFlag); err != nil { - return err - } - return handleSignals(signals, server, sv) -} - -// serve serves the ttrpc API over a unix socket at the provided path this -// function does not block. -func serve(server *ttrpc.Server, path string) error { - var ( - l net.Listener - err error - ) - if path == "" { - l, err = net.FileListener(os.NewFile(3, "socket")) - } else { - if len(path) > 106 { - return fmt.Errorf("%q: unix socket path too long (> 106)", path) - } - l, err = net.Listen("unix", "\x00"+path) - } - if err != nil { - return err - } - go func() { - defer l.Close() - err := server.Serve(context.Background(), l) - if err != nil && !strings.Contains(err.Error(), "use of closed network connection") { - log.Fatalf("ttrpc server failure: %v", err) - } - }() - return nil -} - -// setupSignals creates a new signal handler for all signals and sets the shim -// as a sub-reaper so that the container processes are reparented. -func setupSignals() (chan os.Signal, error) { - signals := make(chan os.Signal, 32) - signal.Notify(signals, unix.SIGTERM, unix.SIGINT, unix.SIGCHLD, unix.SIGPIPE) - // make sure runc is setup to use the monitor for waiting on processes. - // TODO(random-liu): Move shim/reaper.go to a separate package. - runsc.Monitor = reaper.Default - // Set the shim as the subreaper for all orphaned processes created by - // the container. - if err := unix.Prctl(unix.PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0); err != nil { - return nil, err - } - return signals, nil -} - -func handleSignals(signals chan os.Signal, server *ttrpc.Server, sv *shim.Service) error { - var ( - termOnce sync.Once - done = make(chan struct{}) - ) - - for { - select { - case <-done: - return nil - case s := <-signals: - switch s { - case unix.SIGCHLD: - if _, err := sys.Reap(false); err != nil { - log.Printf("reap error: %v", err) - } - case unix.SIGTERM, unix.SIGINT: - go termOnce.Do(func() { - ctx := context.TODO() - if err := server.Shutdown(ctx); err != nil { - log.Printf("failed to shutdown server: %v", err) - } - // Ensure our child is dead if any. - sv.Kill(ctx, &KillRequest{ - Signal: uint32(syscall.SIGKILL), - All: true, - }) - sv.Delete(context.Background(), &types.Empty{}) - close(done) - }) - case unix.SIGPIPE: - } - } - } -} - -type remoteEventsPublisher struct { - address string -} - -func (l *remoteEventsPublisher) Publish(ctx context.Context, topic string, event events.Event) error { - ns, _ := namespaces.Namespace(ctx) - encoded, err := typeurl.MarshalAny(event) - if err != nil { - return err - } - data, err := encoded.Marshal() - if err != nil { - return err - } - cmd := exec.CommandContext(ctx, containerdBinaryFlag, "--address", l.address, "publish", "--topic", topic, "--namespace", ns) - cmd.Stdin = bytes.NewReader(data) - c, err := reaper.Default.Start(cmd) - if err != nil { - return err - } - status, err := reaper.Default.Wait(cmd, c) - if err != nil { - return fmt.Errorf("failed to publish event: %w", err) - } - if status != 0 { - return fmt.Errorf("failed to publish event: status %d", status) - } - return nil -} diff --git a/shim/v1/cli/config.go b/shim/v1/cli/config.go deleted file mode 100644 index 1be9597ed..000000000 --- a/shim/v1/cli/config.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2018 The gVisor 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 -// -// https://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 cli - -import "github.com/BurntSushi/toml" - -// config is the configuration for gvisor containerd shim. -type config struct { - // RuncShim is the shim binary path for standard containerd-shim for runc. - // When the runtime is `runc`, gvisor containerd shim will exec current - // process to standard containerd-shim. This is a work around for containerd - // 1.1. In containerd 1.2, containerd will choose different containerd-shims - // based on runtime. - RuncShim string `toml:"runc_shim"` - // RunscConfig is configuration for runsc. The key value will be converted - // to runsc flags --key=value directly. - RunscConfig map[string]string `toml:"runsc_config"` -} - -// loadConfig load gvisor containerd shim config from config file. -func loadConfig(path string) (*config, error) { - var c config - _, err := toml.DecodeFile(path, &c) - if err != nil { - return &c, err - } - return &c, nil -} diff --git a/shim/v1/main.go b/shim/v1/main.go deleted file mode 100644 index 11ff4add1..000000000 --- a/shim/v1/main.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2020 The gVisor 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 -// -// https://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. - -// Binary gvisor-containerd-shim is the v1 containerd shim. -package main - -import ( - "gvisor.dev/gvisor/shim/v1/cli" -) - -func main() { - cli.Main() -} diff --git a/shim/v2/BUILD b/shim/v2/BUILD deleted file mode 100644 index b4a107d27..000000000 --- a/shim/v2/BUILD +++ /dev/null @@ -1,13 +0,0 @@ -load("//tools:defs.bzl", "go_binary") - -package(licenses = ["notice"]) - -go_binary( - name = "containerd-shim-runsc-v1", - srcs = ["main.go"], - static = True, - visibility = [ - "//visibility:public", - ], - deps = ["//shim/v2/cli"], -) diff --git a/test/root/crictl_test.go b/test/root/crictl_test.go index 863b98d0f..fbf134014 100644 --- a/test/root/crictl_test.go +++ b/test/root/crictl_test.go @@ -98,29 +98,25 @@ var Httpd = SimpleSpec("httpd", "basic/httpd", nil, nil) // TestCrictlSanity refers to b/112433158. func TestCrictlSanity(t *testing.T) { - for _, version := range allVersions { - t.Run(version, func(t *testing.T) { - // Setup containerd and crictl. - crictl, cleanup, err := setup(t, version) - if err != nil { - t.Fatalf("failed to setup crictl: %v", err) - } - defer cleanup() - podID, contID, err := crictl.StartPodAndContainer(containerdRuntime, "basic/httpd", Sandbox("default"), Httpd) - if err != nil { - t.Fatalf("start failed: %v", err) - } - - // Look for the httpd page. - if err = httpGet(crictl, podID, "index.html"); err != nil { - t.Fatalf("failed to get page: %v", err) - } - - // Stop everything. - if err := crictl.StopPodAndContainer(podID, contID); err != nil { - t.Fatalf("stop failed: %v", err) - } - }) + // Setup containerd and crictl. + crictl, cleanup, err := setup(t) + if err != nil { + t.Fatalf("failed to setup crictl: %v", err) + } + defer cleanup() + podID, contID, err := crictl.StartPodAndContainer(containerdRuntime, "basic/httpd", Sandbox("default"), Httpd) + if err != nil { + t.Fatalf("start failed: %v", err) + } + + // Look for the httpd page. + if err = httpGet(crictl, podID, "index.html"); err != nil { + t.Fatalf("failed to get page: %v", err) + } + + // Stop everything. + if err := crictl.StopPodAndContainer(podID, contID); err != nil { + t.Fatalf("stop failed: %v", err) } } @@ -154,152 +150,130 @@ var HttpdMountPaths = SimpleSpec("httpd", "basic/httpd", nil, map[string]interfa // TestMountPaths refers to b/117635704. func TestMountPaths(t *testing.T) { - for _, version := range allVersions { - t.Run(version, func(t *testing.T) { - // Setup containerd and crictl. - crictl, cleanup, err := setup(t, version) - if err != nil { - t.Fatalf("failed to setup crictl: %v", err) - } - defer cleanup() - podID, contID, err := crictl.StartPodAndContainer(containerdRuntime, "basic/httpd", Sandbox("default"), HttpdMountPaths) - if err != nil { - t.Fatalf("start failed: %v", err) - } - - // Look for the directory available at /test. - if err = httpGet(crictl, podID, "test"); err != nil { - t.Fatalf("failed to get page: %v", err) - } - - // Stop everything. - if err := crictl.StopPodAndContainer(podID, contID); err != nil { - t.Fatalf("stop failed: %v", err) - } - }) + // Setup containerd and crictl. + crictl, cleanup, err := setup(t) + if err != nil { + t.Fatalf("failed to setup crictl: %v", err) + } + defer cleanup() + podID, contID, err := crictl.StartPodAndContainer(containerdRuntime, "basic/httpd", Sandbox("default"), HttpdMountPaths) + if err != nil { + t.Fatalf("start failed: %v", err) + } + + // Look for the directory available at /test. + if err = httpGet(crictl, podID, "test"); err != nil { + t.Fatalf("failed to get page: %v", err) + } + + // Stop everything. + if err := crictl.StopPodAndContainer(podID, contID); err != nil { + t.Fatalf("stop failed: %v", err) } } // TestMountPaths refers to b/118728671. func TestMountOverSymlinks(t *testing.T) { - for _, version := range allVersions { - t.Run(version, func(t *testing.T) { - // Setup containerd and crictl. - crictl, cleanup, err := setup(t, version) - if err != nil { - t.Fatalf("failed to setup crictl: %v", err) - } - defer cleanup() - - spec := SimpleSpec("busybox", "basic/resolv", []string{"sleep", "1000"}, nil) - podID, contID, err := crictl.StartPodAndContainer(containerdRuntime, "basic/resolv", Sandbox("default"), spec) - if err != nil { - t.Fatalf("start failed: %v", err) - } - - out, err := crictl.Exec(contID, "readlink", "/etc/resolv.conf") - if err != nil { - t.Fatalf("readlink failed: %v, out: %s", err, out) - } - if want := "/tmp/resolv.conf"; !strings.Contains(string(out), want) { - t.Fatalf("/etc/resolv.conf is not pointing to %q: %q", want, string(out)) - } - - etc, err := crictl.Exec(contID, "cat", "/etc/resolv.conf") - if err != nil { - t.Fatalf("cat failed: %v, out: %s", err, etc) - } - tmp, err := crictl.Exec(contID, "cat", "/tmp/resolv.conf") - if err != nil { - t.Fatalf("cat failed: %v, out: %s", err, out) - } - if tmp != etc { - t.Fatalf("file content doesn't match:\n\t/etc/resolv.conf: %s\n\t/tmp/resolv.conf: %s", string(etc), string(tmp)) - } - - // Stop everything. - if err := crictl.StopPodAndContainer(podID, contID); err != nil { - t.Fatalf("stop failed: %v", err) - } - }) + // Setup containerd and crictl. + crictl, cleanup, err := setup(t) + if err != nil { + t.Fatalf("failed to setup crictl: %v", err) + } + defer cleanup() + + spec := SimpleSpec("busybox", "basic/resolv", []string{"sleep", "1000"}, nil) + podID, contID, err := crictl.StartPodAndContainer(containerdRuntime, "basic/resolv", Sandbox("default"), spec) + if err != nil { + t.Fatalf("start failed: %v", err) + } + + out, err := crictl.Exec(contID, "readlink", "/etc/resolv.conf") + if err != nil { + t.Fatalf("readlink failed: %v, out: %s", err, out) + } + if want := "/tmp/resolv.conf"; !strings.Contains(string(out), want) { + t.Fatalf("/etc/resolv.conf is not pointing to %q: %q", want, string(out)) + } + + etc, err := crictl.Exec(contID, "cat", "/etc/resolv.conf") + if err != nil { + t.Fatalf("cat failed: %v, out: %s", err, etc) + } + tmp, err := crictl.Exec(contID, "cat", "/tmp/resolv.conf") + if err != nil { + t.Fatalf("cat failed: %v, out: %s", err, out) + } + if tmp != etc { + t.Fatalf("file content doesn't match:\n\t/etc/resolv.conf: %s\n\t/tmp/resolv.conf: %s", string(etc), string(tmp)) + } + + // Stop everything. + if err := crictl.StopPodAndContainer(podID, contID); err != nil { + t.Fatalf("stop failed: %v", err) } } // TestHomeDir tests that the HOME environment variable is set for // Pod containers. func TestHomeDir(t *testing.T) { - for _, version := range allVersions { - t.Run(version, func(t *testing.T) { - // Setup containerd and crictl. - crictl, cleanup, err := setup(t, version) - if err != nil { - t.Fatalf("failed to setup crictl: %v", err) - } - defer cleanup() - - // Note that container ID returned here is a sub-container. All Pod - // containers are sub-containers. The root container of the sandbox is the - // pause container. - t.Run("sub-container", func(t *testing.T) { - contSpec := SimpleSpec("subcontainer", "basic/busybox", []string{"sh", "-c", "echo $HOME"}, nil) - podID, contID, err := crictl.StartPodAndContainer(containerdRuntime, "basic/busybox", Sandbox("subcont-sandbox"), contSpec) - if err != nil { - t.Fatalf("start failed: %v", err) - } - - out, err := crictl.Logs(contID) - if err != nil { - t.Fatalf("failed retrieving container logs: %v, out: %s", err, out) - } - if got, want := strings.TrimSpace(string(out)), "/root"; got != want { - t.Fatalf("Home directory invalid. Got %q, Want : %q", got, want) - } - - // Stop everything; note that the pod may have already stopped. - crictl.StopPodAndContainer(podID, contID) - }) - - // Tests that HOME is set for the exec process. - t.Run("exec", func(t *testing.T) { - contSpec := SimpleSpec("exec", "basic/busybox", []string{"sleep", "1000"}, nil) - podID, contID, err := crictl.StartPodAndContainer(containerdRuntime, "basic/busybox", Sandbox("exec-sandbox"), contSpec) - if err != nil { - t.Fatalf("start failed: %v", err) - } - - out, err := crictl.Exec(contID, "sh", "-c", "echo $HOME") - if err != nil { - t.Fatalf("failed retrieving container logs: %v, out: %s", err, out) - } - if got, want := strings.TrimSpace(string(out)), "/root"; got != want { - t.Fatalf("Home directory invalid. Got %q, Want : %q", got, want) - } - - // Stop everything. - if err := crictl.StopPodAndContainer(podID, contID); err != nil { - t.Fatalf("stop failed: %v", err) - } - }) - }) + // Setup containerd and crictl. + crictl, cleanup, err := setup(t) + if err != nil { + t.Fatalf("failed to setup crictl: %v", err) } + defer cleanup() + + // Note that container ID returned here is a sub-container. All Pod + // containers are sub-containers. The root container of the sandbox is the + // pause container. + t.Run("sub-container", func(t *testing.T) { + contSpec := SimpleSpec("subcontainer", "basic/busybox", []string{"sh", "-c", "echo $HOME"}, nil) + podID, contID, err := crictl.StartPodAndContainer(containerdRuntime, "basic/busybox", Sandbox("subcont-sandbox"), contSpec) + if err != nil { + t.Fatalf("start failed: %v", err) + } + + out, err := crictl.Logs(contID) + if err != nil { + t.Fatalf("failed retrieving container logs: %v, out: %s", err, out) + } + if got, want := strings.TrimSpace(string(out)), "/root"; got != want { + t.Fatalf("Home directory invalid. Got %q, Want : %q", got, want) + } + + // Stop everything; note that the pod may have already stopped. + crictl.StopPodAndContainer(podID, contID) + }) + + // Tests that HOME is set for the exec process. + t.Run("exec", func(t *testing.T) { + contSpec := SimpleSpec("exec", "basic/busybox", []string{"sleep", "1000"}, nil) + podID, contID, err := crictl.StartPodAndContainer(containerdRuntime, "basic/busybox", Sandbox("exec-sandbox"), contSpec) + if err != nil { + t.Fatalf("start failed: %v", err) + } + + out, err := crictl.Exec(contID, "sh", "-c", "echo $HOME") + if err != nil { + t.Fatalf("failed retrieving container logs: %v, out: %s", err, out) + } + if got, want := strings.TrimSpace(string(out)), "/root"; got != want { + t.Fatalf("Home directory invalid. Got %q, Want : %q", got, want) + } + + // Stop everything. + if err := crictl.StopPodAndContainer(podID, contID); err != nil { + t.Fatalf("stop failed: %v", err) + } + }) } const containerdRuntime = "runsc" -const v1Template = ` -disabled_plugins = ["restart"] -[plugins.cri] - disable_tcp_service = true -[plugins.linux] - shim = "%s" - shim_debug = true -[plugins.cri.containerd.runtimes.` + containerdRuntime + `] - runtime_type = "io.containerd.runtime.v1.linux" - runtime_engine = "%s" - runtime_root = "%s/root/runsc" -` - -const v2Template = ` +// Template is the containerd configuration file that configures containerd with +// the gVisor shim, Note that the v2 shim binary name must be +// containerd-shim-<runtime>-v1. +const template = ` disabled_plugins = ["restart"] [plugins.cri] disable_tcp_service = true @@ -311,22 +285,11 @@ disabled_plugins = ["restart"] TypeUrl = "io.containerd.` + containerdRuntime + `.v1.options" ` -const ( - // v1 is the containerd API v1. - v1 string = "v1" - - // v2 is the containerd API v2. - v2 string = "v2" -) - -// allVersions is the set of known versions. -var allVersions = []string{v1, v2} - // setup sets up before a test. Specifically it: // * Creates directories and a socket for containerd to utilize. // * Runs containerd and waits for it to reach a "ready" state for testing. // * Returns a cleanup function that should be called at the end of the test. -func setup(t *testing.T, version string) (*criutil.Crictl, func(), error) { +func setup(t *testing.T) (*criutil.Crictl, func(), error) { // Create temporary containerd root and state directories, and a socket // via which crictl and containerd communicate. containerdRoot, err := ioutil.TempDir(testutil.TmpDir(), "containerd-root") @@ -373,6 +336,11 @@ func setup(t *testing.T, version string) (*criutil.Crictl, func(), error) { } t.Logf("Using containerd version: %d.%d", major, minor) + // Check if containerd supports shim v2. + if major < 1 || (major == 1 && minor <= 1) { + t.Skipf("skipping incompatible containerd (want at least 1.2, got %d.%d)", major, minor) + } + // We rewrite a configuration. This is based on the current docker // configuration for the runtime under test. runtime, err := dockerutil.RuntimePath() @@ -393,37 +361,9 @@ func setup(t *testing.T, version string) (*criutil.Crictl, func(), error) { modifiedPath = runtimeDir + ":" + modifiedPath t.Logf("Using PATH: %v", modifiedPath) - var ( - config string - runpArgs []string - ) - switch version { - case v1: - // This is only supported less than 1.3. - if major > 1 || (major == 1 && minor >= 3) { - t.Skipf("skipping unsupported containerd (want less than 1.3, got %d.%d)", major, minor) - } - - // We provide the shim, followed by the runtime, and then a - // temporary root directory. - config = fmt.Sprintf(v1Template, criutil.ResolvePath("gvisor-containerd-shim"), runtime, containerdRoot) - case v2: - // This is only supported past 1.2. - if major < 1 || (major == 1 && minor <= 1) { - t.Skipf("skipping incompatible containerd (want at least 1.2, got %d.%d)", major, minor) - } - - // The runtime is provided via parameter. Note that the v2 shim - // binary name is always containerd-shim-* so we don't actually - // care about the docker runtime name. - config = v2Template - default: - t.Fatalf("unknown version: %s", version) - } - t.Logf("Using config: %s", config) - // Generate the configuration for the test. - configFile, configCleanup, err := testutil.WriteTmpFile("containerd-config", config) + t.Logf("Using config: %s", template) + configFile, configCleanup, err := testutil.WriteTmpFile("containerd-config", template) if err != nil { t.Fatalf("failed to write containerd config") } @@ -488,7 +428,7 @@ func setup(t *testing.T, version string) (*criutil.Crictl, func(), error) { go io.Copy(ioutil.Discard, startupR) // Create the crictl interface. - cc := criutil.NewCrictl(t, sockAddr, runpArgs) + cc := criutil.NewCrictl(t, sockAddr) cu.Add(cc.CleanUp) // Kill must be the last cleanup (as it will be executed first). diff --git a/tools/go_branch.sh b/tools/go_branch.sh index 3a6a83f2e..4b18c015f 100755 --- a/tools/go_branch.sh +++ b/tools/go_branch.sh @@ -144,7 +144,7 @@ EOF # There are a few solitary files that can get left behind due to the way bazel # constructs the gopath target. Note that we don't find all Go files here # because they may correspond to unused templates, etc. -declare -ar binaries=( "runsc" "shim/v1" "shim/v2" "webhook" ) +declare -ar binaries=( "runsc" "shim" "webhook" ) for target in "${binaries[@]}"; do mkdir -p "${target}" cp "${repo_orig}/${target}"/*.go "${target}/" diff --git a/tools/installers/BUILD b/tools/installers/BUILD index bbf3c1f85..d9f9c4c40 100644 --- a/tools/installers/BUILD +++ b/tools/installers/BUILD @@ -27,7 +27,6 @@ sh_binary( name = "shim", srcs = ["shim.sh"], data = [ - "//shim/v1:gvisor-containerd-shim", - "//shim/v2:containerd-shim-runsc-v1", + "//shim:containerd-shim-runsc-v1", ], ) diff --git a/tools/installers/containerd.sh b/tools/installers/containerd.sh index d28549734..e598bce89 100755 --- a/tools/installers/containerd.sh +++ b/tools/installers/containerd.sh @@ -75,14 +75,11 @@ install_helper github.com/containerd/containerd "v${CONTAINERD_VERSION}" "${GOPA install_helper github.com/kubernetes-sigs/cri-tools "v${CRITOOLS_VERSION}" "${GOPATH}" # Configure containerd-shim. -# -# Note that for versions <= 1.1 the legacy shim must be installed in /usr/bin, -# which should align with the installer script in head.sh (or master.sh). -if [[ "${CONTAINERD_MAJOR}" -le 1 ]] && [[ "${CONTAINERD_MINOR}" -lt 2 ]]; then - declare -r shim_config_path=/etc/containerd/gvisor-containerd-shim.toml - mkdir -p $(dirname ${shim_config_path}) - cat > ${shim_config_path} <<-EOF - runc_shim = "/usr/bin/containerd-shim" +declare -r shim_config_path=/etc/containerd/runsc/config.toml +mkdir -p $(dirname ${shim_config_path}) +cat > ${shim_config_path} <<-EOF +log_path = "/tmp/shim-logs/" +log_level = "debug" [runsc_config] debug = "true" @@ -90,7 +87,6 @@ if [[ "${CONTAINERD_MAJOR}" -le 1 ]] && [[ "${CONTAINERD_MINOR}" -lt 2 ]]; then strace = "true" file-access = "shared" EOF -fi # Configure CNI. (cd "${GOPATH}" && src/github.com/containerd/containerd/script/setup/install-cni) diff --git a/tools/installers/shim.sh b/tools/installers/shim.sh index 8153ce283..9af50b5c7 100755 --- a/tools/installers/shim.sh +++ b/tools/installers/shim.sh @@ -30,4 +30,3 @@ if [[ -d "$0.runfiles" ]]; then runfiles="$0.runfiles" fi find -L "${runfiles}" -executable -type f -name containerd-shim-runsc-v1 -exec cp -L {} "${containerd_install_dir}" \; -find -L "${runfiles}" -executable -type f -name gvisor-containerd-shim -exec cp -L {} "${containerd_install_dir}" \; diff --git a/website/_layouts/docs.html b/website/_layouts/docs.html index 0422f9fb0..d45a781a4 100644 --- a/website/_layouts/docs.html +++ b/website/_layouts/docs.html @@ -16,21 +16,24 @@ categories: <ul class="sidebar-nav"> {% assign subcats = site.pages | where: 'layout', 'docs' | where: 'category', category | group_by: 'subcategory' | sort: 'name', 'first' %} {% for subcategory in subcats %} - {% assign sorted_pages = subcategory.items | sort: 'weight', 'last' %} - {% if subcategory.name != "" %} - {% assign ac = "aria-controls" %} - {% assign cid = category | remove: " " | downcase %} - {% assign sid = subcategory.name | remove: " " | downcase %} - <li> - <a class="sidebar-nav-heading" data-toggle="collapse" href="#{{ cid }}-{{ sid }}" aria-expanded="false" {{ ac }}="{{ cid }}-{{ sid }}">{{ subcategory.name }}<span class="caret"></span></a> - <ul class="collapse sidebar-nav sidebar-submenu" id="{{ cid }}-{{ sid }}"> - {% endif %} - {% for p in sorted_pages %} - <li><a href="{{ p.url }}">{{ p.title }}</a></li> - {% endfor %} - {% if subcategory.name != "" %} - </li> - </ul> + {% assign sorted_pages = subcategory.items | where: 'include_in_menu', true | sort: 'weight', 'last' %} + {% comment %}If all pages in the subcategory are excluded don't show it.{% endcomment %} + {% if sorted_pages.size > 0 %} + {% if subcategory.name != "" %} + {% assign ac = "aria-controls" %} + {% assign cid = category | remove: " " | downcase %} + {% assign sid = subcategory.name | remove: " " | downcase %} + <li> + <a class="sidebar-nav-heading" data-toggle="collapse" href="#{{ cid }}-{{ sid }}" aria-expanded="false" {{ ac }}="{{ cid }}-{{ sid }}">{{ subcategory.name }}<span class="caret"></span></a> + <ul class="collapse sidebar-nav sidebar-submenu" id="{{ cid }}-{{ sid }}"> + {% endif %} + {% for p in sorted_pages %} + <li><a href="{{ p.url }}">{{ p.title }}</a></li> + {% endfor %} + {% if subcategory.name != "" %} + </li> + </ul> + {% endif %} {% endif %} {% endfor %} </ul> diff --git a/website/defs.bzl b/website/defs.bzl index f52946c15..703040882 100644 --- a/website/defs.bzl +++ b/website/defs.bzl @@ -7,6 +7,7 @@ load("//tools:defs.bzl", "short_path") # dynamically. This is done the via BUILD system so that the plain # documentation files can be viewable without non-compliant markdown headers. DocInfo = provider( + "Encapsulates information for a documentation page.", fields = [ "layout", "description", @@ -16,6 +17,7 @@ DocInfo = provider( "weight", "editpath", "authors", + "include_in_menu", ], ) @@ -33,6 +35,7 @@ def _doc_impl(ctx): weight = ctx.attr.weight, editpath = short_path(ctx.files.src[0].short_path), authors = ctx.attr.authors, + include_in_menu = ctx.attr.include_in_menu, ), ] @@ -74,6 +77,10 @@ doc = rule( default = "50", ), "authors": attr.string_list(), + "include_in_menu": attr.bool( + doc = "Include document in the navigation menu.", + default = True, + ), }, ) @@ -111,7 +118,8 @@ subcategory: {subcategory} weight: {weight} editpath: {editpath} authors: {authors} -layout: {layout}""" +layout: {layout} +include_in_menu: {include_in_menu}""" for f in dep.files.to_list(): # Is this a markdown file? If not, then we ensure that it ends up |