summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--BUILD3
-rw-r--r--Makefile23
-rw-r--r--WORKSPACE597
-rw-r--r--g3doc/user_guide/BUILD9
-rw-r--r--g3doc/user_guide/runtimeclass.md44
-rw-r--r--go.mod22
-rw-r--r--go.sum123
-rw-r--r--pkg/shim/runsc/BUILD16
-rw-r--r--pkg/shim/runsc/runsc.go49
-rw-r--r--pkg/shim/v1/proc/BUILD35
-rw-r--r--pkg/shim/v1/proc/deleted_state.go12
-rw-r--r--pkg/shim/v1/proc/exec.go25
-rw-r--r--pkg/shim/v1/proc/exec_state.go16
-rw-r--r--pkg/shim/v1/proc/init.go80
-rw-r--r--pkg/shim/v1/proc/init_state.go18
-rw-r--r--pkg/shim/v1/proc/io.go5
-rw-r--r--pkg/shim/v1/proc/process.go6
-rw-r--r--pkg/shim/v1/proc/types.go10
-rw-r--r--pkg/shim/v1/proc/utils.go2
-rw-r--r--pkg/shim/v1/shim/BUILD38
-rw-r--r--pkg/shim/v1/shim/platform.go10
-rw-r--r--pkg/shim/v1/shim/service.go68
-rw-r--r--pkg/shim/v1/utils/BUILD26
-rw-r--r--pkg/shim/v1/utils/volumes.go41
-rw-r--r--pkg/shim/v2/BUILD41
-rw-r--r--pkg/shim/v2/epoll.go6
-rw-r--r--pkg/shim/v2/options/BUILD11
-rw-r--r--pkg/shim/v2/service.go115
-rw-r--r--pkg/shim/v2/service_linux.go10
-rw-r--r--pkg/test/criutil/criutil.go66
-rw-r--r--runsc/BUILD12
-rwxr-xr-xrunsc/debian/postinst.sh9
-rw-r--r--shim/BUILD15
-rw-r--r--shim/README.md21
-rw-r--r--shim/configure-containerd-shim-runsc-v1.md72
-rw-r--r--shim/configure-gvisor-containerd-shim.md42
-rw-r--r--shim/runsc.toml6
-rw-r--r--shim/runtime-handler-quickstart.md251
-rw-r--r--shim/untrusted-workload-quickstart.md212
-rw-r--r--shim/v1/BUILD43
-rw-r--r--shim/v1/README.md50
-rw-r--r--shim/v1/config.go (renamed from shim/v2/config.go)0
-rw-r--r--shim/v1/main.go247
-rw-r--r--shim/v2/BUILD32
-rw-r--r--shim/v2/README.md90
-rw-r--r--shim/v2/main.go298
-rw-r--r--shim/v2/runtime-handler-shim-v2-quickstart.md (renamed from shim/runtime-handler-shim-v2-quickstart.md)0
-rw-r--r--test/root/BUILD5
-rw-r--r--test/root/crictl_test.go452
-rwxr-xr-xtest/shim/containerd-install.sh44
-rwxr-xr-xtest/shim/crictl-install.sh17
-rwxr-xr-xtest/shim/run-container.sh30
-rwxr-xr-xtest/shim/runsc-install.sh8
-rwxr-xr-xtest/shim/runtime-handler-shim-v2/install.sh21
-rwxr-xr-xtest/shim/runtime-handler-shim-v2/test.sh34
-rwxr-xr-xtest/shim/runtime-handler-shim-v2/validate.sh7
-rwxr-xr-xtest/shim/runtime-handler/install.sh24
-rwxr-xr-xtest/shim/runtime-handler/test.sh33
-rwxr-xr-xtest/shim/runtime-handler/usage.sh30
-rwxr-xr-xtest/shim/runtimeclass-install.sh33
-rwxr-xr-xtest/shim/shim-install.sh28
-rwxr-xr-xtest/shim/untrusted-workload/install.sh27
-rwxr-xr-xtest/shim/untrusted-workload/test.sh33
-rwxr-xr-xtest/shim/untrusted-workload/usage.sh33
-rwxr-xr-xtest/shim/validate.sh17
-rw-r--r--tools/bazel.mk2
-rw-r--r--tools/installers/BUILD10
-rwxr-xr-xtools/installers/containerd.sh114
-rwxr-xr-xtools/installers/head.sh8
-rwxr-xr-xtools/vm/ubuntu1604/30_containerd.sh86
-rwxr-xr-xtools/vm/ubuntu1604/30_docker.sh (renamed from tools/vm/ubuntu1604/25_docker.sh)0
-rw-r--r--website/BUILD3
72 files changed, 2166 insertions, 1860 deletions
diff --git a/BUILD b/BUILD
index 962d54821..5d0dbde4c 100644
--- a/BUILD
+++ b/BUILD
@@ -69,7 +69,10 @@ go_path(
name = "gopath",
mode = "link",
deps = [
+ # Main binary.
"//runsc",
+ "//shim/v1:gvisor-containerd-shim",
+ "//shim/v2:containerd-shim-runsc-v1",
# Packages that are not dependencies of //runsc.
"//pkg/sentry/kernel/memevent",
diff --git a/Makefile b/Makefile
index 85818ebea..58648f5d2 100644
--- a/Makefile
+++ b/Makefile
@@ -121,6 +121,22 @@ tests: ## Runs all local ptrace system call tests.
@$(MAKE) test OPTIONS="--test_tag_filters runsc_ptrace test/syscalls/..."
.PHONY: tests
+containerd-test-%: ## Runs a local containerd test.
+containerd-test-%: load-basic_alpine load-basic_python load-basic_busybox load-basic_resolv load-basic_httpd
+containerd-test-%: install-test-runtime
+ @CONTAINERD_VERSION=$* $(MAKE) sudo TARGETS="tools/installers:containerd"
+ @$(MAKE) sudo TARGETS="test/root:root_test" ARGS="-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.
+containerd-tests: ## Runs all supported containerd version tests.
+containerd-tests: containerd-test-1.2.13
+containerd-tests: containerd-test-1.3.4
+containerd-tests: containerd-test-1.4.0-beta.0
+
##
## Website & documentation helpers.
##
@@ -233,11 +249,14 @@ dev: ## Installs a set of local runtimes. Requires sudo.
refresh: ## Refreshes the runtime binary (for development only). Must have called 'dev' or 'test-install' first.
@mkdir -p "$(RUNTIME_DIR)"
- @$(MAKE) copy TARGETS=runsc DESTINATION="$(RUNTIME_BIN)" && chmod 0755 "$(RUNTIME_BIN)"
+ @$(MAKE) copy TARGETS=runsc DESTINATION="$(RUNTIME_BIN)"
+ @$(MAKE) copy TARGETS=shim/v1:gvisor-containerd-shim DESTINATION="$(RUNTIME_DIR)"
+ @$(MAKE) copy TARGETS=shim/v2:containerd-shim-runsc-v1 DESTINATION="$(RUNTIME_DIR)"
.PHONY: install
-test-install: ## Installs the runtime for testing. Requires sudo.
+install-test-runtime: ## Installs the runtime for testing. Requires sudo.
@$(MAKE) refresh ARGS="--net-raw --TESTONLY-test-name-env=RUNSC_TEST_NAME --debug --strace --log-packets $(ARGS)"
+ @$(MAKE) configure RUNTIME=runsc
@$(MAKE) configure
@sudo systemctl restart docker
.PHONY: install-test
diff --git a/WORKSPACE b/WORKSPACE
index 417ec6100..b3e97b0cc 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -4,11 +4,11 @@ load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
# Bazel/starlark utilities.
http_archive(
name = "bazel_skylib",
+ sha256 = "97e70364e9249702246c0e9444bccdc4b847bed1eb03c5a3ece4f83dfe6abc44",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.0.2/bazel-skylib-1.0.2.tar.gz",
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.0.2/bazel-skylib-1.0.2.tar.gz",
],
- sha256 = "97e70364e9249702246c0e9444bccdc4b847bed1eb03c5a3ece4f83dfe6abc44",
)
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
@@ -159,7 +159,38 @@ load("@com_github_grpc_grpc//bazel:grpc_extra_deps.bzl", "grpc_extra_deps")
grpc_extra_deps()
-# External repositories, in sorted order.
+# System Call test dependencies.
+http_archive(
+ name = "com_google_absl",
+ sha256 = "56775f1283a59e6274c28d99981a9717ff4e0b1161e9129fdb2fcf22531d8d93",
+ strip_prefix = "abseil-cpp-a0d1e098c2f99694fa399b175a7ccf920762030e",
+ urls = [
+ "https://mirror.bazel.build/github.com/abseil/abseil-cpp/archive/a0d1e098c2f99694fa399b175a7ccf920762030e.tar.gz",
+ "https://github.com/abseil/abseil-cpp/archive/a0d1e098c2f99694fa399b175a7ccf920762030e.tar.gz",
+ ],
+)
+
+http_archive(
+ name = "com_google_googletest",
+ sha256 = "0a10bea96d8670e5eef948d79d824162b1577bb7889539e49ec786bfc3e48912",
+ strip_prefix = "googletest-565f1b848215b77c3732bca345fe76a0431d8b34",
+ urls = [
+ "https://mirror.bazel.build/github.com/google/googletest/archive/565f1b848215b77c3732bca345fe76a0431d8b34.tar.gz",
+ "https://github.com/google/googletest/archive/565f1b848215b77c3732bca345fe76a0431d8b34.tar.gz",
+ ],
+)
+
+http_archive(
+ name = "com_google_benchmark",
+ sha256 = "3c6a165b6ecc948967a1ead710d4a181d7b0fbcaa183ef7ea84604994966221a",
+ strip_prefix = "benchmark-1.5.0",
+ urls = [
+ "https://mirror.bazel.build/github.com/google/benchmark/archive/v1.5.0.tar.gz",
+ "https://github.com/google/benchmark/archive/v1.5.0.tar.gz",
+ ],
+)
+
+# Go repositories, in gazelle order.
go_repository(
name = "com_github_cenkalti_backoff",
importpath = "github.com/cenkalti/backoff",
@@ -177,15 +208,15 @@ go_repository(
go_repository(
name = "com_github_golang_mock",
importpath = "github.com/golang/mock",
- sum = "h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s=",
- version = "v1.3.1",
+ sum = "h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8=",
+ version = "v1.1.1",
)
go_repository(
name = "com_github_google_go-cmp",
importpath = "github.com/google/go-cmp",
- sum = "h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=",
- version = "v0.2.0",
+ sum = "h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=",
+ version = "v0.3.1",
)
go_repository(
@@ -232,8 +263,8 @@ go_repository(
go_repository(
name = "com_github_opencontainers_runtime-spec",
importpath = "github.com/opencontainers/runtime-spec",
- sum = "h1:d9F+LNYwMyi3BDN4GzZdaSiq4otb8duVEWyZjeUtOQI=",
- version = "v0.1.2-0.20171211145439-b2d941ef6a78",
+ sum = "h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0=",
+ version = "v1.0.2",
)
go_repository(
@@ -261,8 +292,8 @@ go_repository(
name = "org_golang_google_grpc",
build_file_proto_mode = "disable",
importpath = "google.golang.org/grpc",
- sum = "h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=",
- version = "v1.27.1",
+ sum = "h1:Mm8atZtkT+P6R43n/dqNDWkPPu5BwRVu/1rJnJCeZH8=",
+ version = "v1.12.0",
)
go_repository(
@@ -289,8 +320,8 @@ go_repository(
go_repository(
name = "org_golang_x_net",
importpath = "golang.org/x/net",
- sum = "h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=",
- version = "v0.0.0-20190620200207-3b0461eec859",
+ sum = "h1:FCqk7JXVeupwwnGVopQCC0a0xRK0Rj7SL5AyjjWo4pk=",
+ version = "v0.0.0-20170716174642-b3756b4b77d7",
)
go_repository(
@@ -303,8 +334,8 @@ go_repository(
go_repository(
name = "org_golang_x_text",
importpath = "golang.org/x/text",
- sum = "h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=",
- version = "v0.3.0",
+ sum = "h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=",
+ version = "v0.3.2",
)
go_repository(
@@ -317,8 +348,8 @@ go_repository(
go_repository(
name = "org_golang_x_tools",
importpath = "golang.org/x/tools",
- sum = "h1:Uglradbb4KfUWaYasZhlsDsGRwHHvRsHoNAEONef0W8=",
- version = "v0.0.0-20200131233409-575de47986ce",
+ sum = "h1:NIou6eNFigscvKJmsbyez16S2cIS6idossORlFtSt2E=",
+ version = "v0.0.0-20181030221726-6c7e314b6563",
)
go_repository(
@@ -352,8 +383,8 @@ go_repository(
go_repository(
name = "org_golang_x_oauth2",
importpath = "golang.org/x/oauth2",
- sum = "h1:pE8b58s1HRDMi8RDc79m0HISf9D4TzseP40cEA6IGfs=",
- version = "v0.0.0-20191202225959-858c2ad4c8b6",
+ sum = "h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=",
+ version = "v0.0.0-20180821212333-d2e6202438be",
)
go_repository(
@@ -497,12 +528,11 @@ go_repository(
version = "v1.5.0",
)
-# BigQuery Dependencies for Benchmarks
go_repository(
name = "com_google_cloud_go",
importpath = "cloud.google.com/go",
- sum = "h1:eoz/lYxKSL4CNAiaUJ0ZfD1J3bfMYbU5B3rwM1C1EIU=",
- version = "v0.55.0",
+ sum = "h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ=",
+ version = "v0.26.0",
)
go_repository(
@@ -515,8 +545,8 @@ go_repository(
go_repository(
name = "io_opencensus_go",
importpath = "go.opencensus.io",
- sum = "h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8=",
- version = "v0.22.3",
+ sum = "h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4=",
+ version = "v0.22.0",
)
go_repository(
@@ -526,34 +556,505 @@ go_repository(
version = "v0.0.0-20200121045136-8c9f03a8e57e",
)
-# System Call test dependencies.
-http_archive(
- name = "com_google_absl",
- sha256 = "56775f1283a59e6274c28d99981a9717ff4e0b1161e9129fdb2fcf22531d8d93",
- strip_prefix = "abseil-cpp-a0d1e098c2f99694fa399b175a7ccf920762030e",
- urls = [
- "https://mirror.bazel.build/github.com/abseil/abseil-cpp/archive/a0d1e098c2f99694fa399b175a7ccf920762030e.tar.gz",
- "https://github.com/abseil/abseil-cpp/archive/a0d1e098c2f99694fa399b175a7ccf920762030e.tar.gz",
- ],
+go_repository(
+ name = "com_github_census_instrumentation_opencensus_proto",
+ importpath = "github.com/census-instrumentation/opencensus-proto",
+ sum = "h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk=",
+ version = "v0.2.1",
)
-http_archive(
- name = "com_google_googletest",
- sha256 = "0a10bea96d8670e5eef948d79d824162b1577bb7889539e49ec786bfc3e48912",
- strip_prefix = "googletest-565f1b848215b77c3732bca345fe76a0431d8b34",
- urls = [
- "https://mirror.bazel.build/github.com/google/googletest/archive/565f1b848215b77c3732bca345fe76a0431d8b34.tar.gz",
- "https://github.com/google/googletest/archive/565f1b848215b77c3732bca345fe76a0431d8b34.tar.gz",
- ],
+go_repository(
+ name = "com_github_client9_misspell",
+ importpath = "github.com/client9/misspell",
+ sum = "h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=",
+ version = "v0.3.4",
)
-http_archive(
- name = "com_google_benchmark",
- sha256 = "3c6a165b6ecc948967a1ead710d4a181d7b0fbcaa183ef7ea84604994966221a",
- strip_prefix = "benchmark-1.5.0",
- urls = [
- "https://mirror.bazel.build/github.com/google/benchmark/archive/v1.5.0.tar.gz",
- "https://github.com/google/benchmark/archive/v1.5.0.tar.gz",
- ],
+go_repository(
+ name = "com_github_cncf_udpa_go",
+ importpath = "github.com/cncf/udpa/go",
+ sum = "h1:WBZRG4aNOuI15bLRrCgN8fCq8E5Xuty6jGbmSNEvSsU=",
+ version = "v0.0.0-20191209042840-269d4d468f6f",
+)
+
+# K8s must be pinned to 1.14, prior to APIs being split into separate
+# repositories. The containerd versions below assume the existence of the cri
+# API within the kubelet package.
+go_repository(
+ name = "io_k8s_kubernetes",
+ importpath = "k8s.io/kubernetes",
+ sum = "h1:6T2iAEoOYQnzQb3WvPlUkcczEEXZ7+YPlAO8olwujRw=",
+ version = "v1.14.0",
+)
+
+go_repository(
+ name = "com_github_containerd_cgroups",
+ build_file_proto_mode = "disable",
+ importpath = "github.com/containerd/cgroups",
+ sum = "h1:5/YbYIVboEqSpFSC/iMO9FOIP/q8RIuKfYS2TA1M8WE=",
+ version = "v0.0.0-20200520162414-666f4a009ffb",
+)
+
+go_repository(
+ name = "com_github_containerd_console",
+ build_file_proto_mode = "disable",
+ importpath = "github.com/containerd/console",
+ sum = "h1:uict5mhHFTzKLUCufdSLym7z/J0CbBJT59lYbP9wtbg=",
+ version = "v0.0.0-20180822173158-c12b1e7919c1",
+)
+
+go_repository(
+ name = "com_github_containerd_containerd",
+ build_file_proto_mode = "disable",
+ importpath = "github.com/containerd/containerd",
+ sum = "h1:BmZa1bGjKctYrIbyjbhZJlGvHceJASpdW5pIDSQcw1E=",
+ version = "v0.0.0-20190510190154-d0319ec44af6",
+)
+
+go_repository(
+ name = "com_github_containerd_continuity",
+ build_file_proto_mode = "disable",
+ importpath = "github.com/containerd/continuity",
+ sum = "h1:tN9D97v5A5QuKdcKHKt+UMKrkQ5YXUnD8iM7IAAjEfI=",
+ version = "v0.0.0-20190815185530-f2a389ac0a02",
+)
+
+go_repository(
+ name = "com_github_containerd_cri",
+ build_file_proto_mode = "disable",
+ importpath = "github.com/containerd/cri",
+ sum = "h1:+bW7GQb2q32/Liy0ZiR6pkpRXdDHShUXRoWg8OGVWZs=",
+ version = "v0.0.0-20190308093238-8a0bd84b9a4c",
+)
+
+go_repository(
+ name = "com_github_containerd_fifo",
+ build_file_proto_mode = "disable",
+ importpath = "github.com/containerd/fifo",
+ sum = "h1:XGyg7oTtD0DoRFhbpV6x1WfV0flKC4UxXU7ab1zC08U=",
+ version = "v0.0.0-20180307165137-3d5202aec260",
+)
+
+go_repository(
+ name = "com_github_containerd_go_runc",
+ build_file_proto_mode = "disable",
+ importpath = "github.com/containerd/go-runc",
+ sum = "h1:esQOJREg8nw8aXj6uCN5dfW5cKUBiEJ/+nni1Q/D/sw=",
+ version = "v0.0.0-20180907222934-5a6d9f37cfa3",
+)
+
+go_repository(
+ name = "com_github_containerd_ttrpc",
+ build_file_proto_mode = "disable",
+ importpath = "github.com/containerd/ttrpc",
+ sum = "h1:SKDlsIhYxNE1LO0xwuOR+3QWj3zRibVQu5jWIMQmOfU=",
+ version = "v0.0.0-20190411181408-699c4e40d1e7",
+)
+
+go_repository(
+ name = "com_github_containerd_typeurl",
+ build_file_proto_mode = "disable",
+ importpath = "github.com/containerd/typeurl",
+ sum = "h1:JNn81o/xG+8NEo3bC/vx9pbi/g2WI8mtP2/nXzu297Y=",
+ version = "v0.0.0-20180627222232-a93fcdb778cd",
+)
+
+go_repository(
+ name = "com_github_coreos_go_systemd",
+ importpath = "github.com/coreos/go-systemd",
+ sum = "h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU=",
+ version = "v0.0.0-20191104093116-d3cd4ed1dbcf",
+)
+
+go_repository(
+ name = "com_github_davecgh_go_spew",
+ importpath = "github.com/davecgh/go-spew",
+ sum = "h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=",
+ version = "v1.1.1",
+)
+
+go_repository(
+ name = "com_github_docker_distribution",
+ importpath = "github.com/docker/distribution",
+ sum = "h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=",
+ version = "v2.7.1+incompatible",
+)
+
+go_repository(
+ name = "com_github_docker_go_events",
+ importpath = "github.com/docker/go-events",
+ sum = "h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=",
+ version = "v0.0.0-20190806004212-e31b211e4f1c",
+)
+
+go_repository(
+ name = "com_github_docker_go_units",
+ importpath = "github.com/docker/go-units",
+ sum = "h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=",
+ version = "v0.4.0",
+)
+
+go_repository(
+ name = "com_github_dustin_go_humanize",
+ importpath = "github.com/dustin/go-humanize",
+ sum = "h1:qk/FSDDxo05wdJH28W+p5yivv7LuLYLRXPPD8KQCtZs=",
+ version = "v0.0.0-20171111073723-bb3d318650d4",
+)
+
+go_repository(
+ name = "com_github_envoyproxy_go_control_plane",
+ importpath = "github.com/envoyproxy/go-control-plane",
+ sum = "h1:rEvIZUSZ3fx39WIi3JkQqQBitGwpELBIYWeBVh6wn+E=",
+ version = "v0.9.4",
+)
+
+go_repository(
+ name = "com_github_envoyproxy_protoc_gen_validate",
+ importpath = "github.com/envoyproxy/protoc-gen-validate",
+ sum = "h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=",
+ version = "v0.1.0",
+)
+
+go_repository(
+ name = "com_github_fsnotify_fsnotify",
+ importpath = "github.com/fsnotify/fsnotify",
+ sum = "h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=",
+ version = "v1.4.7",
+)
+
+go_repository(
+ name = "com_github_godbus_dbus",
+ importpath = "github.com/godbus/dbus",
+ sum = "h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0=",
+ version = "v0.0.0-20190726142602-4481cbc300e2",
+)
+
+go_repository(
+ name = "com_github_gogo_googleapis",
+ importpath = "github.com/gogo/googleapis",
+ sum = "h1:zgVt4UpGxcqVOw97aRGxT4svlcmdK35fynLNctY32zI=",
+ version = "v1.4.0",
+)
+
+go_repository(
+ name = "com_github_gogo_protobuf",
+ importpath = "github.com/gogo/protobuf",
+ sum = "h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=",
+ version = "v1.3.1",
+)
+
+go_repository(
+ name = "com_github_golang_glog",
+ importpath = "github.com/golang/glog",
+ sum = "h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=",
+ version = "v0.0.0-20160126235308-23def4e6c14b",
+)
+
+go_repository(
+ name = "com_github_hashicorp_golang_lru",
+ importpath = "github.com/hashicorp/golang-lru",
+ sum = "h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=",
+ version = "v0.5.1",
+)
+
+go_repository(
+ name = "com_github_hpcloud_tail",
+ importpath = "github.com/hpcloud/tail",
+ sum = "h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=",
+ version = "v1.0.0",
+)
+
+go_repository(
+ name = "com_github_inconshreveable_mousetrap",
+ importpath = "github.com/inconshreveable/mousetrap",
+ sum = "h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=",
+ version = "v1.0.0",
+)
+
+go_repository(
+ name = "com_github_kisielk_errcheck",
+ importpath = "github.com/kisielk/errcheck",
+ sum = "h1:reN85Pxc5larApoH1keMBiu2GWtPqXQ1nc9gx+jOU+E=",
+ version = "v1.2.0",
+)
+
+go_repository(
+ name = "com_github_kisielk_gotool",
+ importpath = "github.com/kisielk/gotool",
+ sum = "h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=",
+ version = "v1.0.0",
+)
+
+go_repository(
+ name = "com_github_konsorten_go_windows_terminal_sequences",
+ importpath = "github.com/konsorten/go-windows-terminal-sequences",
+ sum = "h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=",
+ version = "v1.0.2",
+)
+
+go_repository(
+ name = "com_github_microsoft_go_winio",
+ importpath = "github.com/Microsoft/go-winio",
+ sum = "h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU=",
+ version = "v0.4.14",
+)
+
+go_repository(
+ name = "com_github_microsoft_hcsshim",
+ importpath = "github.com/Microsoft/hcsshim",
+ sum = "h1:ZfF0+zZeYdzMIVMZHKtDKJvLHj76XCuVae/jNkjj0IA=",
+ version = "v0.8.6",
+)
+
+go_repository(
+ name = "com_github_onsi_ginkgo",
+ importpath = "github.com/onsi/ginkgo",
+ sum = "h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=",
+ version = "v1.10.1",
+)
+
+go_repository(
+ name = "com_github_onsi_gomega",
+ importpath = "github.com/onsi/gomega",
+ sum = "h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=",
+ version = "v1.7.0",
+)
+
+go_repository(
+ name = "com_github_opencontainers_go_digest",
+ importpath = "github.com/opencontainers/go-digest",
+ sum = "h1:QhPf3A2AZW3tTGvHPg0TA+CR3oHbVLlXUhlghqISp1I=",
+ version = "v0.0.0-20180430190053-c9281466c8b2",
+)
+
+go_repository(
+ name = "com_github_opencontainers_image_spec",
+ importpath = "github.com/opencontainers/image-spec",
+ sum = "h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=",
+ version = "v1.0.1",
+)
+
+go_repository(
+ name = "com_github_opencontainers_runc",
+ importpath = "github.com/opencontainers/runc",
+ sum = "h1:dDCFes8Hj1r/i5qnypONo5jdOme/8HWZC/aNDyhECt0=",
+ version = "v1.0.0-rc8",
+)
+
+go_repository(
+ name = "com_github_pkg_errors",
+ importpath = "github.com/pkg/errors",
+ sum = "h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=",
+ version = "v0.9.1",
+)
+
+go_repository(
+ name = "com_github_pmezard_go_difflib",
+ importpath = "github.com/pmezard/go-difflib",
+ sum = "h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=",
+ version = "v1.0.0",
+)
+
+go_repository(
+ name = "com_github_prometheus_client_model",
+ importpath = "github.com/prometheus/client_model",
+ sum = "h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=",
+ version = "v0.0.0-20190812154241-14fe0d1b01d4",
+)
+
+go_repository(
+ name = "com_github_prometheus_procfs",
+ importpath = "github.com/prometheus/procfs",
+ sum = "h1:hhvfGDVThBnd4kYisSFmYuHYeUhglxcwag7FhVPH9zM=",
+ version = "v0.0.0-20180125133057-cb4147076ac7",
+)
+
+go_repository(
+ name = "com_github_sirupsen_logrus",
+ importpath = "github.com/sirupsen/logrus",
+ sum = "h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=",
+ version = "v1.4.2",
+)
+
+go_repository(
+ name = "com_github_spf13_cobra",
+ importpath = "github.com/spf13/cobra",
+ sum = "h1:GQkkv3XSnxhAMjdq2wLfEnptEVr+2BNvmHizILHn+d4=",
+ version = "v0.0.2-0.20171109065643-2da4a54c5cee",
+)
+
+go_repository(
+ name = "com_github_spf13_pflag",
+ importpath = "github.com/spf13/pflag",
+ sum = "h1:j8jxLbQ0+T1DFggy6XoGvyUnrJWPR/JybflPvu5rwS4=",
+ version = "v1.0.1-0.20171106142849-4c012f6dcd95",
+)
+
+go_repository(
+ name = "com_github_stretchr_objx",
+ importpath = "github.com/stretchr/objx",
+ sum = "h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=",
+ version = "v0.1.1",
+)
+
+go_repository(
+ name = "com_github_stretchr_testify",
+ importpath = "github.com/stretchr/testify",
+ sum = "h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=",
+ version = "v1.2.2",
+)
+
+go_repository(
+ name = "com_github_urfave_cli",
+ importpath = "github.com/urfave/cli",
+ sum = "h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo=",
+ version = "v1.22.2",
+)
+
+go_repository(
+ name = "in_gopkg_airbrake_gobrake_v2",
+ importpath = "gopkg.in/airbrake/gobrake.v2",
+ sum = "h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNatLo=",
+ version = "v2.0.9",
+)
+
+go_repository(
+ name = "in_gopkg_fsnotify_v1",
+ importpath = "gopkg.in/fsnotify.v1",
+ sum = "h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=",
+ version = "v1.4.7",
+)
+
+go_repository(
+ name = "in_gopkg_gemnasium_logrus_airbrake_hook_v2",
+ importpath = "gopkg.in/gemnasium/logrus-airbrake-hook.v2",
+ sum = "h1:OAj3g0cR6Dx/R07QgQe8wkA9RNjB2u4i700xBkIT4e0=",
+ version = "v2.1.2",
+)
+
+go_repository(
+ name = "in_gopkg_tomb_v1",
+ importpath = "gopkg.in/tomb.v1",
+ sum = "h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=",
+ version = "v1.0.0-20141024135613-dd632973f1e7",
+)
+
+go_repository(
+ name = "in_gopkg_yaml_v2",
+ importpath = "gopkg.in/yaml.v2",
+ sum = "h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=",
+ version = "v2.2.2",
+)
+
+go_repository(
+ name = "org_bazil_fuse",
+ importpath = "bazil.org/fuse",
+ sum = "h1:SC+c6A1qTFstO9qmB86mPV2IpYme/2ZoEQ0hrP+wo+Q=",
+ version = "v0.0.0-20160811212531-371fbbdaa898",
+)
+
+go_repository(
+ name = "org_golang_google_appengine",
+ importpath = "google.golang.org/appengine",
+ sum = "h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=",
+ version = "v1.4.0",
+)
+
+go_repository(
+ name = "org_golang_google_genproto",
+ importpath = "google.golang.org/genproto",
+ sum = "h1:wVJP1pATLVPNxCz4R2mTO6HUJgfGE0PmIu2E10RuhCw=",
+ version = "v0.0.0-20170523043604-d80a6e20e776",
+)
+
+go_repository(
+ name = "org_golang_x_exp",
+ importpath = "golang.org/x/exp",
+ sum = "h1:c2HOrn5iMezYjSlGPncknSEr/8x5LELb/ilJbXi9DEA=",
+ version = "v0.0.0-20190121172915-509febef88a4",
+)
+
+go_repository(
+ name = "org_golang_x_lint",
+ importpath = "golang.org/x/lint",
+ sum = "h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0=",
+ version = "v0.0.0-20190313153728-d0100b6bd8b3",
+)
+
+go_repository(
+ name = "tools_gotest",
+ importpath = "gotest.tools",
+ sum = "h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=",
+ version = "v2.2.0+incompatible",
+)
+
+go_repository(
+ name = "co_honnef_go_tools",
+ importpath = "honnef.co/go/tools",
+ sum = "h1:/hemPrYIhOhy8zYrNj+069zDB68us2sMGsfkFJO0iZs=",
+ version = "v0.0.0-20190523083050-ea95bdfd59fc",
+)
+
+go_repository(
+ name = "com_github_burntsushi_toml",
+ importpath = "github.com/BurntSushi/toml",
+ sum = "h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=",
+ version = "v0.3.1",
+)
+
+go_repository(
+ name = "io_k8s_cri_api",
+ importpath = "k8s.io/cri-api",
+ sum = "h1:bykYbClh5Bnjo2EMjlYbYQ3ksxHjjLcbriKPm831hVk=",
+ version = "v0.18.2",
+)
+
+go_repository(
+ name = "com_github_docker_docker",
+ importpath = "github.com/docker/docker",
+ sum = "h1:Bh3QS4GYuVi8QeNskrV3ivn8p0bupmk0PfY4xmVulo4=",
+ version = "v17.12.0-ce-rc1.0.20200514230353-811a247d06e8+incompatible",
+)
+
+go_repository(
+ name = "com_github_cilium_ebpf",
+ importpath = "github.com/cilium/ebpf",
+ sum = "h1:i8+1fuPLjSgAYXUyBlHNhFwjcfAsP4ufiuH1+PWkyDU=",
+ version = "v0.0.0-20200110133405-4032b1d8aae3",
+)
+
+go_repository(
+ name = "com_github_coreos_go_systemd_v22",
+ importpath = "github.com/coreos/go-systemd/v22",
+ sum = "h1:XJIw/+VlJ+87J+doOxznsAWIdmWuViOVhkQamW5YV28=",
+ version = "v22.0.0",
+)
+
+go_repository(
+ name = "com_github_cpuguy83_go_md2man_v2",
+ importpath = "github.com/cpuguy83/go-md2man/v2",
+ sum = "h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=",
+ version = "v2.0.0",
+)
+
+go_repository(
+ name = "com_github_godbus_dbus_v5",
+ importpath = "github.com/godbus/dbus/v5",
+ sum = "h1:ZqHaoEF7TBzh4jzPmqVhE/5A1z9of6orkAe5uHoAeME=",
+ version = "v5.0.3",
+)
+
+go_repository(
+ name = "com_github_russross_blackfriday_v2",
+ importpath = "github.com/russross/blackfriday/v2",
+ sum = "h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=",
+ version = "v2.0.1",
+)
+
+go_repository(
+ name = "com_github_shurcool_sanitized_anchor_name",
+ importpath = "github.com/shurcooL/sanitized_anchor_name",
+ sum = "h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=",
+ version = "v1.0.0",
)
diff --git a/g3doc/user_guide/BUILD b/g3doc/user_guide/BUILD
index b69aee12c..355dd49b3 100644
--- a/g3doc/user_guide/BUILD
+++ b/g3doc/user_guide/BUILD
@@ -68,3 +68,12 @@ doc(
permalink = "/docs/user_guide/platforms/",
weight = "30",
)
+
+doc(
+ name = "runtimeclass",
+ src = "runtimeclass.md",
+ category = "User Guide",
+ permalink = "/docs/user_guide/runtimeclass/",
+ subcategory = "Advanced",
+ weight = "91",
+)
diff --git a/g3doc/user_guide/runtimeclass.md b/g3doc/user_guide/runtimeclass.md
new file mode 100644
index 000000000..9f2d794c3
--- /dev/null
+++ b/g3doc/user_guide/runtimeclass.md
@@ -0,0 +1,44 @@
+# RuntimeClass
+
+First, follow the appropriate installation instructions for your version of
+containerd.
+
+* For 1.1 or lower, use `gvisor-containerd-shim`.
+* For 1.2 or higher, use `containerd-shim-runsc-v1`.
+
+# Set up the Kubernetes RuntimeClass
+
+Creating the RuntimeClass in kubernetes is simple once the runtime is available
+for containerd:
+
+```shell
+cat <<EOF | kubectl apply -f -
+apiVersion: node.k8s.io/v1beta1
+kind: RuntimeClass
+metadata:
+ name: gvisor
+handler: runsc
+EOF
+```
+
+Pods can now be created using this RuntimeClass:
+
+```shell
+cat <<EOF | kubectl apply -f -
+apiVersion: v1
+kind: Pod
+metadata:
+ name: nginx-gvisor
+spec:
+ runtimeClassName: gvisor
+ containers:
+ - name: nginx
+ image: nginx
+EOF
+```
+
+You can verify that the Pod is running via this RuntimeClass:
+
+```shell
+kubectl get pod nginx-gvisor -o wide
+```
diff --git a/go.mod b/go.mod
index 434fa713f..ffc33a349 100644
--- a/go.mod
+++ b/go.mod
@@ -3,18 +3,38 @@ module gvisor.dev/gvisor
go 1.14
require (
+ github.com/BurntSushi/toml v0.3.1
+ github.com/Microsoft/go-winio v0.4.14 // indirect
+ github.com/Microsoft/hcsshim v0.8.6 // indirect
github.com/cenkalti/backoff v0.0.0-20190506075156-2146c9339422
+ github.com/containerd/cgroups v0.0.0-20200520162414-666f4a009ffb
+ github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1
+ github.com/containerd/containerd v0.0.0-20190510190154-d0319ec44af6
+ github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02 // indirect
+ github.com/containerd/cri v0.0.0-20190308093238-8a0bd84b9a4c
+ github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260
+ github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3
+ github.com/containerd/ttrpc v0.0.0-20190411181408-699c4e40d1e7 // indirect
+ github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd
github.com/gofrs/flock v0.6.1-0.20180915234121-886344bea079
+ github.com/gogo/protobuf v1.3.1
github.com/golang/protobuf v1.3.1
github.com/google/btree v1.0.0
+ github.com/google/go-cmp v0.3.1 // indirect
github.com/google/subcommands v0.0.0-20190508160503-636abe8753b8
github.com/kr/pretty v0.2.0 // indirect
github.com/kr/pty v1.1.1
- github.com/opencontainers/runtime-spec v0.1.2-0.20171211145439-b2d941ef6a78
+ github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2 // indirect
+ github.com/opencontainers/runc v1.0.0-rc8 // indirect
+ github.com/opencontainers/runtime-spec v1.0.2
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2
github.com/vishvananda/netlink v1.0.1-0.20190318003149-adb577d4a45e
github.com/vishvananda/netns v0.0.0-20171111001504-be1fbeda1936 // indirect
+ golang.org/x/net v0.0.0-20170716174642-b3756b4b77d7 // indirect
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527
golang.org/x/time v0.0.0-20191024005414-555d28b269f0
+ google.golang.org/genproto v0.0.0-20170523043604-d80a6e20e776 // indirect
+ google.golang.org/grpc v1.12.0
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
+ gotest.tools v2.2.0+incompatible // indirect
)
diff --git a/go.sum b/go.sum
index c44a17c71..4212c6975 100644
--- a/go.sum
+++ b/go.sum
@@ -1,32 +1,147 @@
+github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU=
+github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU=
+github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
+github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
+github.com/Microsoft/hcsshim v0.8.6 h1:ZfF0+zZeYdzMIVMZHKtDKJvLHj76XCuVae/jNkjj0IA=
+github.com/Microsoft/hcsshim v0.8.6 h1:ZfF0+zZeYdzMIVMZHKtDKJvLHj76XCuVae/jNkjj0IA=
+github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
+github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
github.com/cenkalti/backoff v0.0.0-20190506075156-2146c9339422 h1:+FKjzBIdfBHYDvxCv+djmDJdes/AoDtg8gpcxowBlF8=
github.com/cenkalti/backoff v0.0.0-20190506075156-2146c9339422/go.mod h1:b6Nc7NRH5C4aCISLry0tLnTjcuTEvoiqcWDdsU0sOGM=
+github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg=
+github.com/containerd/cgroups v0.0.0-20200520162414-666f4a009ffb h1:5/YbYIVboEqSpFSC/iMO9FOIP/q8RIuKfYS2TA1M8WE=
+github.com/containerd/cgroups v0.0.0-20200520162414-666f4a009ffb/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM=
+github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1 h1:uict5mhHFTzKLUCufdSLym7z/J0CbBJT59lYbP9wtbg=
+github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1 h1:uict5mhHFTzKLUCufdSLym7z/J0CbBJT59lYbP9wtbg=
+github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
+github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
+github.com/containerd/containerd v0.0.0-20190510190154-d0319ec44af6 h1:BmZa1bGjKctYrIbyjbhZJlGvHceJASpdW5pIDSQcw1E=
+github.com/containerd/containerd v0.0.0-20190510190154-d0319ec44af6 h1:BmZa1bGjKctYrIbyjbhZJlGvHceJASpdW5pIDSQcw1E=
+github.com/containerd/containerd v0.0.0-20190510190154-d0319ec44af6/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
+github.com/containerd/containerd v0.0.0-20190510190154-d0319ec44af6/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
+github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02 h1:tN9D97v5A5QuKdcKHKt+UMKrkQ5YXUnD8iM7IAAjEfI=
+github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
+github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
+github.com/containerd/cri v0.0.0-20190308093238-8a0bd84b9a4c h1:+bW7GQb2q32/Liy0ZiR6pkpRXdDHShUXRoWg8OGVWZs=
+github.com/containerd/cri v0.0.0-20190308093238-8a0bd84b9a4c/go.mod h1:DavH5Qa8+6jOmeOMO3dhWoqksucZDe06LfuhBz/xPZs=
+github.com/containerd/cri v0.0.0-20190308093238-8a0bd84b9a4c/go.mod h1:DavH5Qa8+6jOmeOMO3dhWoqksucZDe06LfuhBz/xPZs=
+github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260 h1:XGyg7oTtD0DoRFhbpV6x1WfV0flKC4UxXU7ab1zC08U=
+github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260 h1:XGyg7oTtD0DoRFhbpV6x1WfV0flKC4UxXU7ab1zC08U=
+github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
+github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
+github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3 h1:esQOJREg8nw8aXj6uCN5dfW5cKUBiEJ/+nni1Q/D/sw=
+github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3 h1:esQOJREg8nw8aXj6uCN5dfW5cKUBiEJ/+nni1Q/D/sw=
+github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
+github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
+github.com/containerd/ttrpc v0.0.0-20190411181408-699c4e40d1e7 h1:SKDlsIhYxNE1LO0xwuOR+3QWj3zRibVQu5jWIMQmOfU=
+github.com/containerd/ttrpc v0.0.0-20190411181408-699c4e40d1e7 h1:SKDlsIhYxNE1LO0xwuOR+3QWj3zRibVQu5jWIMQmOfU=
+github.com/containerd/ttrpc v0.0.0-20190411181408-699c4e40d1e7/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
+github.com/containerd/ttrpc v0.0.0-20190411181408-699c4e40d1e7/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
+github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd h1:JNn81o/xG+8NEo3bC/vx9pbi/g2WI8mtP2/nXzu297Y=
+github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd h1:JNn81o/xG+8NEo3bC/vx9pbi/g2WI8mtP2/nXzu297Y=
+github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
+github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
+github.com/coreos/go-systemd/v22 v22.0.0 h1:XJIw/+VlJ+87J+doOxznsAWIdmWuViOVhkQamW5YV28=
+github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
+github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
+github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
+github.com/godbus/dbus/v5 v5.0.3 h1:ZqHaoEF7TBzh4jzPmqVhE/5A1z9of6orkAe5uHoAeME=
+github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gofrs/flock v0.6.1-0.20180915234121-886344bea079 h1:JFTFz3HZTGmgMz4E1TabNBNJljROSYgja1b4l50FNVs=
github.com/gofrs/flock v0.6.1-0.20180915234121-886344bea079/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
+github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
+github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/subcommands v0.0.0-20190508160503-636abe8753b8 h1:GZGUPQiZfYrd9uOqyqwbQcHPkz/EZJVkZB1MkaO9UBI=
github.com/google/subcommands v0.0.0-20190508160503-636abe8753b8/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
+github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
+github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/opencontainers/runtime-spec v0.1.2-0.20171211145439-b2d941ef6a78 h1:d9F+LNYwMyi3BDN4GzZdaSiq4otb8duVEWyZjeUtOQI=
-github.com/opencontainers/runtime-spec v0.1.2-0.20171211145439-b2d941ef6a78/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
+github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2 h1:QhPf3A2AZW3tTGvHPg0TA+CR3oHbVLlXUhlghqISp1I=
+github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
+github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
+github.com/opencontainers/runc v1.0.0-rc8 h1:dDCFes8Hj1r/i5qnypONo5jdOme/8HWZC/aNDyhECt0=
+github.com/opencontainers/runc v1.0.0-rc8/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
+github.com/opencontainers/runc v1.0.0-rc8/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
+github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0=
+github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
+github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
+github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
+github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
+github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
+github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
+github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 h1:b6uOv7YOFK0TYG7HtkIgExQo+2RdLuwRft63jn2HWj8=
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
+github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/vishvananda/netlink v1.0.1-0.20190318003149-adb577d4a45e h1:/Tdc23Arz1OtdIsBY2utWepGRQ9fEAJlhkdoLzWMK8Q=
github.com/vishvananda/netlink v1.0.1-0.20190318003149-adb577d4a45e/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
github.com/vishvananda/netns v0.0.0-20171111001504-be1fbeda1936 h1:J9gO8RJCAFlln1jsvRba/CWVUnMHwObklfxxjErl1uk=
github.com/vishvananda/netns v0.0.0-20171111001504-be1fbeda1936/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/net v0.0.0-20170716174642-b3756b4b77d7 h1:FCqk7JXVeupwwnGVopQCC0a0xRK0Rj7SL5AyjjWo4pk=
+golang.org/x/net v0.0.0-20170716174642-b3756b4b77d7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20170716174642-b3756b4b77d7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b h1:ag/x1USPSsqHud38I9BAC88qdNLDHHtQ4mlgQIZPPNA=
+golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+google.golang.org/genproto v0.0.0-20170523043604-d80a6e20e776 h1:wVJP1pATLVPNxCz4R2mTO6HUJgfGE0PmIu2E10RuhCw=
+google.golang.org/genproto v0.0.0-20170523043604-d80a6e20e776/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20170523043604-d80a6e20e776/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/grpc v1.12.0 h1:Mm8atZtkT+P6R43n/dqNDWkPPu5BwRVu/1rJnJCeZH8=
+google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
+google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
+gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
+gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
diff --git a/pkg/shim/runsc/BUILD b/pkg/shim/runsc/BUILD
new file mode 100644
index 000000000..4d388ca05
--- /dev/null
+++ b/pkg/shim/runsc/BUILD
@@ -0,0 +1,16 @@
+load("//tools:defs.bzl", "go_library")
+
+package(licenses = ["notice"])
+
+go_library(
+ name = "runsc",
+ srcs = [
+ "runsc.go",
+ "utils.go",
+ ],
+ visibility = ["//:sandbox"],
+ deps = [
+ "@com_github_containerd_go_runc//:go_default_library",
+ "@com_github_opencontainers_runtime-spec//specs-go:go_default_library",
+ ],
+)
diff --git a/pkg/shim/runsc/runsc.go b/pkg/shim/runsc/runsc.go
index 41ba9c3af..50807d0c5 100644
--- a/pkg/shim/runsc/runsc.go
+++ b/pkg/shim/runsc/runsc.go
@@ -34,10 +34,10 @@ import (
var Monitor runc.ProcessMonitor = runc.Monitor
-// DefaultCommand is the default command for Runsc
+// DefaultCommand is the default command for Runsc.
const DefaultCommand = "runsc"
-// Runsc is the client to the runsc cli
+// Runsc is the client to the runsc cli.
type Runsc struct {
Command string
PdeathSignal syscall.Signal
@@ -48,7 +48,7 @@ type Runsc struct {
Config map[string]string
}
-// List returns all containers created inside the provided runsc root directory
+// List returns all containers created inside the provided runsc root directory.
func (r *Runsc) List(context context.Context) ([]*runc.Container, error) {
data, err := cmdOutput(r.command(context, "list", "--format=json"), false)
if err != nil {
@@ -61,7 +61,7 @@ func (r *Runsc) List(context context.Context) ([]*runc.Container, error) {
return out, nil
}
-// State returns the state for the container provided by id
+// State returns the state for the container provided by id.
func (r *Runsc) State(context context.Context, id string) (*runc.Container, error) {
data, err := cmdOutput(r.command(context, "state", id), true)
if err != nil {
@@ -76,9 +76,11 @@ func (r *Runsc) State(context context.Context, id string) (*runc.Container, erro
type CreateOpts struct {
runc.IO
- // PidFile is a path to where a pid file should be created
- PidFile string
ConsoleSocket runc.ConsoleSocket
+
+ // PidFile is a path to where a pid file should be created.
+ PidFile string
+
// UserLog is a path to where runsc user log should be generated.
UserLog string
}
@@ -100,7 +102,7 @@ func (o *CreateOpts) args() (out []string, err error) {
return out, nil
}
-// Create creates a new container and returns its pid if it was created successfully
+// Create creates a new container and returns its pid if it was created successfully.
func (r *Runsc) Create(context context.Context, id, bundle string, opts *CreateOpts) error {
args := []string{"create", "--bundle", bundle}
if opts != nil {
@@ -141,7 +143,7 @@ func (r *Runsc) Create(context context.Context, id, bundle string, opts *CreateO
return err
}
-// Start will start an already created container
+// Start will start an already created container.
func (r *Runsc) Start(context context.Context, id string, cio runc.IO) error {
cmd := r.command(context, "start", id)
if cio != nil {
@@ -181,6 +183,7 @@ type waitResult struct {
}
// Wait will wait for a running container, and return its exit status.
+//
// TODO(random-liu): Add exec process support.
func (r *Runsc) Wait(context context.Context, id string) (int, error) {
data, err := cmdOutput(r.command(context, "wait", id), true)
@@ -226,8 +229,8 @@ func (o *ExecOpts) args() (out []string, err error) {
return out, nil
}
-// Exec executres and additional process inside the container based on a full
-// OCI Process specification
+// Exec executes an additional process inside the container based on a full OCI
+// Process specification.
func (r *Runsc) Exec(context context.Context, id string, spec specs.Process, opts *ExecOpts) error {
f, err := ioutil.TempFile(os.Getenv("XDG_RUNTIME_DIR"), "runsc-process")
if err != nil {
@@ -276,8 +279,8 @@ func (r *Runsc) Exec(context context.Context, id string, spec specs.Process, opt
return err
}
-// Run runs the create, start, delete lifecycle of the container
-// and returns its exit status after it has exited
+// Run runs the create, start, delete lifecycle of the container and returns
+// its exit status after it has exited.
func (r *Runsc) Run(context context.Context, id, bundle string, opts *CreateOpts) (int, error) {
args := []string{"run", "--bundle", bundle}
if opts != nil {
@@ -309,7 +312,7 @@ func (o *DeleteOpts) args() (out []string) {
return out
}
-// Delete deletes the container
+// Delete deletes the container.
func (r *Runsc) Delete(context context.Context, id string, opts *DeleteOpts) error {
args := []string{"delete"}
if opts != nil {
@@ -318,7 +321,7 @@ func (r *Runsc) Delete(context context.Context, id string, opts *DeleteOpts) err
return r.runOrError(r.command(context, append(args, id)...))
}
-// KillOpts specifies options for killing a container and its processes
+// KillOpts specifies options for killing a container and its processes.
type KillOpts struct {
All bool
Pid int
@@ -334,7 +337,7 @@ func (o *KillOpts) args() (out []string) {
return out
}
-// Kill sends the specified signal to the container
+// Kill sends the specified signal to the container.
func (r *Runsc) Kill(context context.Context, id string, sig int, opts *KillOpts) error {
args := []string{
"kill",
@@ -345,7 +348,7 @@ func (r *Runsc) Kill(context context.Context, id string, sig int, opts *KillOpts
return r.runOrError(r.command(context, append(args, id, strconv.Itoa(sig))...))
}
-// Stats return the stats for a container like cpu, memory, and io
+// Stats return the stats for a container like cpu, memory, and I/O.
func (r *Runsc) Stats(context context.Context, id string) (*runc.Stats, error) {
cmd := r.command(context, "events", "--stats", id)
rd, err := cmd.StdoutPipe()
@@ -367,7 +370,7 @@ func (r *Runsc) Stats(context context.Context, id string) (*runc.Stats, error) {
return e.Stats, nil
}
-// Events returns an event stream from runsc for a container with stats and OOM notifications
+// Events returns an event stream from runsc for a container with stats and OOM notifications.
func (r *Runsc) Events(context context.Context, id string, interval time.Duration) (chan *runc.Event, error) {
cmd := r.command(context, "events", fmt.Sprintf("--interval=%ds", int(interval.Seconds())), id)
rd, err := cmd.StdoutPipe()
@@ -406,7 +409,7 @@ func (r *Runsc) Events(context context.Context, id string, interval time.Duratio
return c, nil
}
-// Ps lists all the processes inside the container returning their pids
+// Ps lists all the processes inside the container returning their pids.
func (r *Runsc) Ps(context context.Context, id string) ([]int, error) {
data, err := cmdOutput(r.command(context, "ps", "--format", "json", id), true)
if err != nil {
@@ -419,7 +422,7 @@ func (r *Runsc) Ps(context context.Context, id string) ([]int, error) {
return pids, nil
}
-// Top lists all the processes inside the container returning the full ps data
+// Top lists all the processes inside the container returning the full ps data.
func (r *Runsc) Top(context context.Context, id string) (*runc.TopResults, error) {
data, err := cmdOutput(r.command(context, "ps", "--format", "table", id), true)
if err != nil {
@@ -450,10 +453,10 @@ func (r *Runsc) args() []string {
return args
}
-// runOrError will run the provided command. If an error is
-// encountered and neither Stdout or Stderr was set the error and the
-// stderr of the command will be returned in the format of <error>:
-// <stderr>
+// runOrError will run the provided command.
+//
+// If an error is encountered and neither Stdout or Stderr was set the error
+// will be returned in the format of <error>: <stderr>.
func (r *Runsc) runOrError(cmd *exec.Cmd) error {
if cmd.Stdout != nil || cmd.Stderr != nil {
ec, err := Monitor.Start(cmd)
diff --git a/pkg/shim/v1/proc/BUILD b/pkg/shim/v1/proc/BUILD
new file mode 100644
index 000000000..a59bf198d
--- /dev/null
+++ b/pkg/shim/v1/proc/BUILD
@@ -0,0 +1,35 @@
+load("//tools:defs.bzl", "go_library")
+
+package(licenses = ["notice"])
+
+go_library(
+ name = "proc",
+ srcs = [
+ "deleted_state.go",
+ "exec.go",
+ "exec_state.go",
+ "init.go",
+ "init_state.go",
+ "io.go",
+ "process.go",
+ "types.go",
+ "utils.go",
+ ],
+ visibility = [
+ "//pkg/shim:__subpackages__",
+ "//shim:__subpackages__",
+ ],
+ deps = [
+ "//pkg/shim/runsc",
+ "@com_github_containerd_console//:go_default_library",
+ "@com_github_containerd_containerd//errdefs:go_default_library",
+ "@com_github_containerd_containerd//log:go_default_library",
+ "@com_github_containerd_containerd//mount:go_default_library",
+ "@com_github_containerd_containerd//runtime/proc:go_default_library",
+ "@com_github_containerd_fifo//:go_default_library",
+ "@com_github_containerd_go_runc//:go_default_library",
+ "@com_github_gogo_protobuf//types:go_default_library",
+ "@com_github_opencontainers_runtime-spec//specs-go:go_default_library",
+ "@org_golang_x_sys//unix:go_default_library",
+ ],
+)
diff --git a/pkg/shim/v1/proc/deleted_state.go b/pkg/shim/v1/proc/deleted_state.go
index 0196c96dd..52aad40ac 100644
--- a/pkg/shim/v1/proc/deleted_state.go
+++ b/pkg/shim/v1/proc/deleted_state.go
@@ -17,33 +17,33 @@ package proc
import (
"context"
+ "fmt"
"github.com/containerd/console"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/runtime/proc"
- "github.com/pkg/errors"
)
type deletedState struct{}
func (*deletedState) Resize(ws console.WinSize) error {
- return errors.Errorf("cannot resize a deleted process")
+ return fmt.Errorf("cannot resize a deleted process")
}
func (*deletedState) Start(ctx context.Context) error {
- return errors.Errorf("cannot start a deleted process")
+ return fmt.Errorf("cannot start a deleted process")
}
func (*deletedState) Delete(ctx context.Context) error {
- return errors.Wrap(errdefs.ErrNotFound, "cannot delete a deleted process")
+ return fmt.Errorf("cannot delete a deleted process: %w", errdefs.ErrNotFound)
}
func (*deletedState) Kill(ctx context.Context, sig uint32, all bool) error {
- return errors.Wrap(errdefs.ErrNotFound, "cannot kill a deleted process")
+ return fmt.Errorf("cannot kill a deleted process: %w", errdefs.ErrNotFound)
}
func (*deletedState) SetExited(status int) {}
func (*deletedState) Exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) {
- return nil, errors.Errorf("cannot exec in a deleted state")
+ return nil, fmt.Errorf("cannot exec in a deleted state")
}
diff --git a/pkg/shim/v1/proc/exec.go b/pkg/shim/v1/proc/exec.go
index 6821e09cd..4ef9cf6cf 100644
--- a/pkg/shim/v1/proc/exec.go
+++ b/pkg/shim/v1/proc/exec.go
@@ -31,7 +31,6 @@ import (
"github.com/containerd/fifo"
runc "github.com/containerd/go-runc"
specs "github.com/opencontainers/runtime-spec/specs-go"
- "github.com/pkg/errors"
"golang.org/x/sys/unix"
"gvisor.dev/gvisor/pkg/shim/runsc"
@@ -151,9 +150,11 @@ func (e *execProcess) kill(ctx context.Context, sig uint32, _ bool) error {
if err := e.parent.runtime.Kill(ctx, e.parent.id, int(sig), &runsc.KillOpts{
Pid: internalPid,
}); err != nil {
- // If this returns error, consider the process has already stopped.
+ // If this returns error, consider the process has
+ // already stopped.
+ //
// TODO: Fix after signal handling is fixed.
- return errors.Wrapf(errdefs.ErrNotFound, err.Error())
+ return fmt.Errorf("%s: %w", err.Error(), errdefs.ErrNotFound)
}
}
return nil
@@ -182,16 +183,16 @@ func (e *execProcess) start(ctx context.Context) (err error) {
)
if e.stdio.Terminal {
if socket, err = runc.NewTempConsoleSocket(); err != nil {
- return errors.Wrap(err, "failed to create runc console socket")
+ return fmt.Errorf("failed to create runc console socket: %w", err)
}
defer socket.Close()
} else if e.stdio.IsNull() {
if e.io, err = runc.NewNullIO(); err != nil {
- return errors.Wrap(err, "creating new NULL IO")
+ return fmt.Errorf("creating new NULL IO: %w", err)
}
} else {
if e.io, err = runc.NewPipeIO(e.parent.IoUID, e.parent.IoGID, withConditionalIO(e.stdio)); err != nil {
- return errors.Wrap(err, "failed to create runc io pipes")
+ return fmt.Errorf("failed to create runc io pipes: %w", err)
}
}
opts := &runsc.ExecOpts{
@@ -217,7 +218,7 @@ func (e *execProcess) start(ctx context.Context) (err error) {
if e.stdio.Stdin != "" {
sc, err := fifo.OpenFifo(context.Background(), e.stdio.Stdin, syscall.O_WRONLY|syscall.O_NONBLOCK, 0)
if err != nil {
- return errors.Wrapf(err, "failed to open stdin fifo %s", e.stdio.Stdin)
+ return fmt.Errorf("failed to open stdin fifo %s: %w", e.stdio.Stdin, err)
}
e.closers = append(e.closers, sc)
e.stdin = sc
@@ -228,25 +229,25 @@ func (e *execProcess) start(ctx context.Context) (err error) {
if socket != nil {
console, err := socket.ReceiveMaster()
if err != nil {
- return errors.Wrap(err, "failed to retrieve console master")
+ return fmt.Errorf("failed to retrieve console master: %w", err)
}
if e.console, err = e.parent.Platform.CopyConsole(ctx, console, e.stdio.Stdin, e.stdio.Stdout, e.stdio.Stderr, &e.wg, &copyWaitGroup); err != nil {
- return errors.Wrap(err, "failed to start console copy")
+ return fmt.Errorf("failed to start console copy: %w", err)
}
} else if !e.stdio.IsNull() {
if err := copyPipes(ctx, e.io, e.stdio.Stdin, e.stdio.Stdout, e.stdio.Stderr, &e.wg, &copyWaitGroup); err != nil {
- return errors.Wrap(err, "failed to start io pipe copy")
+ return fmt.Errorf("failed to start io pipe copy: %w", err)
}
}
copyWaitGroup.Wait()
pid, err := runc.ReadPidFile(opts.PidFile)
if err != nil {
- return errors.Wrap(err, "failed to retrieve OCI runtime exec pid")
+ return fmt.Errorf("failed to retrieve OCI runtime exec pid: %w", err)
}
e.pid = pid
internalPid, err := runc.ReadPidFile(opts.InternalPidFile)
if err != nil {
- return errors.Wrap(err, "failed to retrieve OCI runtime exec internal pid")
+ return fmt.Errorf("failed to retrieve OCI runtime exec internal pid: %w", err)
}
e.internalPid = internalPid
go func() {
diff --git a/pkg/shim/v1/proc/exec_state.go b/pkg/shim/v1/proc/exec_state.go
index 5416cb601..4dcda8b44 100644
--- a/pkg/shim/v1/proc/exec_state.go
+++ b/pkg/shim/v1/proc/exec_state.go
@@ -17,9 +17,9 @@ package proc
import (
"context"
+ "fmt"
"github.com/containerd/console"
- "github.com/pkg/errors"
)
type execState interface {
@@ -43,7 +43,7 @@ func (s *execCreatedState) transition(name string) error {
case "deleted":
s.p.execState = &deletedState{}
default:
- return errors.Errorf("invalid state transition %q to %q", stateName(s), name)
+ return fmt.Errorf("invalid state transition %q to %q", stateName(s), name)
}
return nil
}
@@ -87,7 +87,7 @@ func (s *execRunningState) transition(name string) error {
case "stopped":
s.p.execState = &execStoppedState{p: s.p}
default:
- return errors.Errorf("invalid state transition %q to %q", stateName(s), name)
+ return fmt.Errorf("invalid state transition %q to %q", stateName(s), name)
}
return nil
}
@@ -97,11 +97,11 @@ func (s *execRunningState) Resize(ws console.WinSize) error {
}
func (s *execRunningState) Start(ctx context.Context) error {
- return errors.Errorf("cannot start a running process")
+ return fmt.Errorf("cannot start a running process")
}
func (s *execRunningState) Delete(ctx context.Context) error {
- return errors.Errorf("cannot delete a running process")
+ return fmt.Errorf("cannot delete a running process")
}
func (s *execRunningState) Kill(ctx context.Context, sig uint32, all bool) error {
@@ -125,17 +125,17 @@ func (s *execStoppedState) transition(name string) error {
case "deleted":
s.p.execState = &deletedState{}
default:
- return errors.Errorf("invalid state transition %q to %q", stateName(s), name)
+ return fmt.Errorf("invalid state transition %q to %q", stateName(s), name)
}
return nil
}
func (s *execStoppedState) Resize(ws console.WinSize) error {
- return errors.Errorf("cannot resize a stopped container")
+ return fmt.Errorf("cannot resize a stopped container")
}
func (s *execStoppedState) Start(ctx context.Context) error {
- return errors.Errorf("cannot start a stopped process")
+ return fmt.Errorf("cannot start a stopped process")
}
func (s *execStoppedState) Delete(ctx context.Context) error {
diff --git a/pkg/shim/v1/proc/init.go b/pkg/shim/v1/proc/init.go
index 0771540a9..b429cb94f 100644
--- a/pkg/shim/v1/proc/init.go
+++ b/pkg/shim/v1/proc/init.go
@@ -18,6 +18,7 @@ package proc
import (
"context"
"encoding/json"
+ "fmt"
"io"
"path/filepath"
"strings"
@@ -33,23 +34,22 @@ import (
"github.com/containerd/fifo"
runc "github.com/containerd/go-runc"
specs "github.com/opencontainers/runtime-spec/specs-go"
- "github.com/pkg/errors"
"gvisor.dev/gvisor/pkg/shim/runsc"
)
-// InitPidFile name of the file that contains the init pid
+// InitPidFile name of the file that contains the init pid.
const InitPidFile = "init.pid"
-// Init represents an initial process for a container
+// Init represents an initial process for a container.
type Init struct {
wg sync.WaitGroup
initState initState
// mu is used to ensure that `Start()` and `Exited()` calls return in
- // the right order when invoked in separate go routines.
- // This is the case within the shim implementation as it makes use of
- // the reaper interface.
+ // the right order when invoked in separate go routines. This is the
+ // case within the shim implementation as it makes use of the reaper
+ // interface.
mu sync.Mutex
waitBlock chan struct{}
@@ -76,7 +76,7 @@ type Init struct {
Monitor ProcessMonitor
}
-// NewRunsc returns a new runsc instance for a process
+// NewRunsc returns a new runsc instance for a process.
func NewRunsc(root, path, namespace, runtime string, config map[string]string) *runsc.Runsc {
if root == "" {
root = RunscRoot
@@ -91,7 +91,7 @@ func NewRunsc(root, path, namespace, runtime string, config map[string]string) *
}
}
-// New returns a new init process
+// New returns a new init process.
func New(id string, runtime *runsc.Runsc, stdio proc.Stdio) *Init {
p := &Init{
id: id,
@@ -104,21 +104,21 @@ func New(id string, runtime *runsc.Runsc, stdio proc.Stdio) *Init {
return p
}
-// Create the process with the provided config
+// Create the process with the provided config.
func (p *Init) Create(ctx context.Context, r *CreateConfig) (err error) {
var socket *runc.Socket
if r.Terminal {
if socket, err = runc.NewTempConsoleSocket(); err != nil {
- return errors.Wrap(err, "failed to create OCI runtime console socket")
+ return fmt.Errorf("failed to create OCI runtime console socket: %w", err)
}
defer socket.Close()
} else if hasNoIO(r) {
if p.io, err = runc.NewNullIO(); err != nil {
- return errors.Wrap(err, "creating new NULL IO")
+ return fmt.Errorf("creating new NULL IO: %w", err)
}
} else {
if p.io, err = runc.NewPipeIO(p.IoUID, p.IoGID, withConditionalIO(p.stdio)); err != nil {
- return errors.Wrap(err, "failed to create OCI runtime io pipes")
+ return fmt.Errorf("failed to create OCI runtime io pipes: %w", err)
}
}
pidFile := filepath.Join(p.Bundle, InitPidFile)
@@ -139,7 +139,7 @@ func (p *Init) Create(ctx context.Context, r *CreateConfig) (err error) {
if r.Stdin != "" {
sc, err := fifo.OpenFifo(context.Background(), r.Stdin, syscall.O_WRONLY|syscall.O_NONBLOCK, 0)
if err != nil {
- return errors.Wrapf(err, "failed to open stdin fifo %s", r.Stdin)
+ return fmt.Errorf("failed to open stdin fifo %s: %w", r.Stdin, err)
}
p.stdin = sc
p.closers = append(p.closers, sc)
@@ -150,58 +150,58 @@ func (p *Init) Create(ctx context.Context, r *CreateConfig) (err error) {
if socket != nil {
console, err := socket.ReceiveMaster()
if err != nil {
- return errors.Wrap(err, "failed to retrieve console master")
+ return fmt.Errorf("failed to retrieve console master: %w", err)
}
console, err = p.Platform.CopyConsole(ctx, console, r.Stdin, r.Stdout, r.Stderr, &p.wg, &copyWaitGroup)
if err != nil {
- return errors.Wrap(err, "failed to start console copy")
+ return fmt.Errorf("failed to start console copy: %w", err)
}
p.console = console
} else if !hasNoIO(r) {
if err := copyPipes(ctx, p.io, r.Stdin, r.Stdout, r.Stderr, &p.wg, &copyWaitGroup); err != nil {
- return errors.Wrap(err, "failed to start io pipe copy")
+ return fmt.Errorf("failed to start io pipe copy: %w", err)
}
}
copyWaitGroup.Wait()
pid, err := runc.ReadPidFile(pidFile)
if err != nil {
- return errors.Wrap(err, "failed to retrieve OCI runtime container pid")
+ return fmt.Errorf("failed to retrieve OCI runtime container pid: %w", err)
}
p.pid = pid
return nil
}
-// Wait for the process to exit
+// Wait waits for the process to exit.
func (p *Init) Wait() {
<-p.waitBlock
}
-// ID of the process
+// ID returns the ID of the process.
func (p *Init) ID() string {
return p.id
}
-// Pid of the process
+// Pid returns the PID of the process.
func (p *Init) Pid() int {
return p.pid
}
-// ExitStatus of the process
+// ExitStatus returns the exit status of the process.
func (p *Init) ExitStatus() int {
p.mu.Lock()
defer p.mu.Unlock()
return p.status
}
-// ExitedAt at time when the process exited
+// ExitedAt returns the time when the process exited.
func (p *Init) ExitedAt() time.Time {
p.mu.Lock()
defer p.mu.Unlock()
return p.exited
}
-// Status of the process
+// Status returns the status of the process.
func (p *Init) Status(ctx context.Context) (string, error) {
p.mu.Lock()
defer p.mu.Unlock()
@@ -215,7 +215,7 @@ func (p *Init) Status(ctx context.Context) (string, error) {
return p.convertStatus(c.Status), nil
}
-// Start the init process
+// Start starts the init process.
func (p *Init) Start(ctx context.Context) error {
p.mu.Lock()
defer p.mu.Unlock()
@@ -250,7 +250,7 @@ func (p *Init) start(ctx context.Context) error {
return nil
}
-// SetExited of the init process with the next status
+// SetExited set the exit stauts of the init process.
func (p *Init) SetExited(status int) {
p.mu.Lock()
defer p.mu.Unlock()
@@ -265,7 +265,7 @@ func (p *Init) setExited(status int) {
close(p.waitBlock)
}
-// Delete the init process
+// Delete deletes the init process.
func (p *Init) Delete(ctx context.Context) error {
p.mu.Lock()
defer p.mu.Unlock()
@@ -298,13 +298,13 @@ func (p *Init) delete(ctx context.Context) error {
if err2 := mount.UnmountAll(p.Rootfs, 0); err2 != nil {
log.G(ctx).WithError(err2).Warn("failed to cleanup rootfs mount")
if err == nil {
- err = errors.Wrap(err2, "failed rootfs umount")
+ err = fmt.Errorf("failed rootfs umount: %w", err2)
}
}
return err
}
-// Resize the init processes console
+// Resize resizes the init processes console.
func (p *Init) Resize(ws console.WinSize) error {
p.mu.Lock()
defer p.mu.Unlock()
@@ -322,7 +322,7 @@ func (p *Init) resize(ws console.WinSize) error {
return p.console.Resize(ws)
}
-// Kill the init process
+// Kill kills the init process.
func (p *Init) Kill(ctx context.Context, signal uint32, all bool) error {
p.mu.Lock()
defer p.mu.Unlock()
@@ -340,7 +340,7 @@ func (p *Init) kill(context context.Context, signal uint32, all bool) error {
c, err := p.runtime.State(context, p.id)
if err != nil {
if strings.Contains(err.Error(), "does not exist") {
- return errors.Wrapf(errdefs.ErrNotFound, "no such process")
+ return fmt.Errorf("no such process: %w", errdefs.ErrNotFound)
}
return p.runtimeError(err, "OCI runtime state failed")
}
@@ -348,7 +348,7 @@ func (p *Init) kill(context context.Context, signal uint32, all bool) error {
// If the container is not in running state, directly return
// "no such process"
if p.convertStatus(c.Status) == "stopped" {
- return errors.Wrapf(errdefs.ErrNotFound, "no such process")
+ return fmt.Errorf("no such process: %w", errdefs.ErrNotFound)
}
killErr = p.runtime.Kill(context, p.id, int(signal), &runsc.KillOpts{
All: all,
@@ -362,7 +362,7 @@ func (p *Init) kill(context context.Context, signal uint32, all bool) error {
return p.runtimeError(killErr, "kill timeout")
}
-// KillAll processes belonging to the init process
+// KillAll kills all processes belonging to the init process.
func (p *Init) KillAll(context context.Context) error {
p.mu.Lock()
defer p.mu.Unlock()
@@ -380,17 +380,17 @@ func (p *Init) killAll(context context.Context) error {
return nil
}
-// Stdin of the process
+// Stdin returns the stdin of the process.
func (p *Init) Stdin() io.Closer {
return p.stdin
}
-// Runtime returns the OCI runtime configured for the init process
+// Runtime returns the OCI runtime configured for the init process.
func (p *Init) Runtime() *runsc.Runsc {
return p.runtime
}
-// Exec returns a new child process
+// Exec returns a new child process.
func (p *Init) Exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) {
p.mu.Lock()
defer p.mu.Unlock()
@@ -398,7 +398,7 @@ func (p *Init) Exec(ctx context.Context, path string, r *ExecConfig) (proc.Proce
return p.initState.Exec(ctx, path, r)
}
-// exec returns a new exec'd process
+// exec returns a new exec'd process.
func (p *Init) exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) {
// process exec request
var spec specs.Process
@@ -424,7 +424,7 @@ func (p *Init) exec(ctx context.Context, path string, r *ExecConfig) (proc.Proce
return e, nil
}
-// Stdio of the process
+// Stdio returns the stdio of the process.
func (p *Init) Stdio() proc.Stdio {
return p.stdio
}
@@ -437,11 +437,11 @@ func (p *Init) runtimeError(rErr error, msg string) error {
rMsg, err := getLastRuntimeError(p.runtime)
switch {
case err != nil:
- return errors.Wrapf(rErr, "%s: %s (%s)", msg, "unable to retrieve OCI runtime error", err.Error())
+ return fmt.Errorf("%s: %w (unable to retrieve OCI runtime error: %v)", msg, rErr, err)
case rMsg == "":
- return errors.Wrap(rErr, msg)
+ return fmt.Errorf("%s: %w", msg, rErr)
default:
- return errors.Errorf("%s: %s", msg, rMsg)
+ return fmt.Errorf("%s: %s", msg, rMsg)
}
}
diff --git a/pkg/shim/v1/proc/init_state.go b/pkg/shim/v1/proc/init_state.go
index 868646b6c..509f27762 100644
--- a/pkg/shim/v1/proc/init_state.go
+++ b/pkg/shim/v1/proc/init_state.go
@@ -17,11 +17,11 @@ package proc
import (
"context"
+ "fmt"
"github.com/containerd/console"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/runtime/proc"
- "github.com/pkg/errors"
)
type initState interface {
@@ -46,7 +46,7 @@ func (s *createdState) transition(name string) error {
case "deleted":
s.p.initState = &deletedState{}
default:
- return errors.Errorf("invalid state transition %q to %q", stateName(s), name)
+ return fmt.Errorf("invalid state transition %q to %q", stateName(s), name)
}
return nil
}
@@ -107,7 +107,7 @@ func (s *runningState) transition(name string) error {
case "stopped":
s.p.initState = &stoppedState{p: s.p}
default:
- return errors.Errorf("invalid state transition %q to %q", stateName(s), name)
+ return fmt.Errorf("invalid state transition %q to %q", stateName(s), name)
}
return nil
}
@@ -117,11 +117,11 @@ func (s *runningState) Resize(ws console.WinSize) error {
}
func (s *runningState) Start(ctx context.Context) error {
- return errors.Errorf("cannot start a running process")
+ return fmt.Errorf("cannot start a running process")
}
func (s *runningState) Delete(ctx context.Context) error {
- return errors.Errorf("cannot delete a running process")
+ return fmt.Errorf("cannot delete a running process")
}
func (s *runningState) Kill(ctx context.Context, sig uint32, all bool) error {
@@ -149,17 +149,17 @@ func (s *stoppedState) transition(name string) error {
case "deleted":
s.p.initState = &deletedState{}
default:
- return errors.Errorf("invalid state transition %q to %q", stateName(s), name)
+ return fmt.Errorf("invalid state transition %q to %q", stateName(s), name)
}
return nil
}
func (s *stoppedState) Resize(ws console.WinSize) error {
- return errors.Errorf("cannot resize a stopped container")
+ return fmt.Errorf("cannot resize a stopped container")
}
func (s *stoppedState) Start(ctx context.Context) error {
- return errors.Errorf("cannot start a stopped process")
+ return fmt.Errorf("cannot start a stopped process")
}
func (s *stoppedState) Delete(ctx context.Context) error {
@@ -178,5 +178,5 @@ func (s *stoppedState) SetExited(status int) {
}
func (s *stoppedState) Exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) {
- return nil, errors.Errorf("cannot exec in a stopped state")
+ return nil, fmt.Errorf("cannot exec in a stopped state")
}
diff --git a/pkg/shim/v1/proc/io.go b/pkg/shim/v1/proc/io.go
index 2677b4e54..5313c7a50 100644
--- a/pkg/shim/v1/proc/io.go
+++ b/pkg/shim/v1/proc/io.go
@@ -150,8 +150,9 @@ func (c *countingWriteCloser) Close() error {
return c.WriteCloser.Close()
}
-// isFifo checks if a file is a fifo
-// if the file does not exist then it returns false
+// isFifo checks if a file is a fifo.
+//
+// If the file does not exist then it returns false.
func isFifo(path string) (bool, error) {
stat, err := os.Stat(path)
if err != nil {
diff --git a/pkg/shim/v1/proc/process.go b/pkg/shim/v1/proc/process.go
index 1bfa99f4c..d462c3eef 100644
--- a/pkg/shim/v1/proc/process.go
+++ b/pkg/shim/v1/proc/process.go
@@ -16,10 +16,10 @@
package proc
import (
- "github.com/pkg/errors"
+ "fmt"
)
-// RunscRoot is the path to the root runsc state directory
+// RunscRoot is the path to the root runsc state directory.
const RunscRoot = "/run/containerd/runsc"
func stateName(v interface{}) string {
@@ -33,5 +33,5 @@ func stateName(v interface{}) string {
case *stoppedState:
return "stopped"
}
- panic(errors.Errorf("invalid state %v", v))
+ panic(fmt.Errorf("invalid state %v", v))
}
diff --git a/pkg/shim/v1/proc/types.go b/pkg/shim/v1/proc/types.go
index dcd43bcca..5c215de5f 100644
--- a/pkg/shim/v1/proc/types.go
+++ b/pkg/shim/v1/proc/types.go
@@ -23,7 +23,7 @@ import (
runc "github.com/containerd/go-runc"
)
-// Mount holds filesystem mount configuration
+// Mount holds filesystem mount configuration.
type Mount struct {
Type string
Source string
@@ -31,7 +31,7 @@ type Mount struct {
Options []string
}
-// CreateConfig hold task creation configuration
+// CreateConfig hold task creation configuration.
type CreateConfig struct {
ID string
Bundle string
@@ -44,7 +44,7 @@ type CreateConfig struct {
Options *google_protobuf.Any
}
-// ExecConfig holds exec creation configuration
+// ExecConfig holds exec creation configuration.
type ExecConfig struct {
ID string
Terminal bool
@@ -54,14 +54,14 @@ type ExecConfig struct {
Spec *google_protobuf.Any
}
-// Exit is the type of exit events
+// Exit is the type of exit events.
type Exit struct {
Timestamp time.Time
ID string
Status int
}
-// ProcessMonitor monitors process exit changes
+// ProcessMonitor monitors process exit changes.
type ProcessMonitor interface {
// Subscribe to process exit changes
Subscribe() chan runc.Exit
diff --git a/pkg/shim/v1/proc/utils.go b/pkg/shim/v1/proc/utils.go
index 6e7dbdad7..716de2f59 100644
--- a/pkg/shim/v1/proc/utils.go
+++ b/pkg/shim/v1/proc/utils.go
@@ -34,8 +34,6 @@ const (
// inside the sandbox.
var ExitCh = make(chan Exit, bufferSize)
-// TODO(random-liu): This can be a utility.
-
// TODO(mlaventure): move to runc package?
func getLastRuntimeError(r *runsc.Runsc) (string, error) {
if r.Log == "" {
diff --git a/pkg/shim/v1/shim/BUILD b/pkg/shim/v1/shim/BUILD
new file mode 100644
index 000000000..02cffbb01
--- /dev/null
+++ b/pkg/shim/v1/shim/BUILD
@@ -0,0 +1,38 @@
+load("//tools:defs.bzl", "go_library")
+
+package(licenses = ["notice"])
+
+go_library(
+ name = "shim",
+ srcs = [
+ "platform.go",
+ "service.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//runtime:go_default_library",
+ "@com_github_containerd_containerd//runtime/linux/runctypes:go_default_library",
+ "@com_github_containerd_containerd//runtime/proc:go_default_library",
+ "@com_github_containerd_containerd//runtime/v1/shim:go_default_library",
+ "@com_github_containerd_containerd//runtime/v1/shim/v1: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/platform.go b/pkg/shim/v1/shim/platform.go
index 86252c3f5..f6795563c 100644
--- a/pkg/shim/v1/shim/platform.go
+++ b/pkg/shim/v1/shim/platform.go
@@ -17,13 +17,13 @@ package shim
import (
"context"
+ "fmt"
"io"
"sync"
"syscall"
"github.com/containerd/console"
"github.com/containerd/fifo"
- "github.com/pkg/errors"
)
type linuxPlatform struct {
@@ -32,7 +32,7 @@ type linuxPlatform struct {
func (p *linuxPlatform) CopyConsole(ctx context.Context, console console.Console, stdin, stdout, stderr string, wg, cwg *sync.WaitGroup) (console.Console, error) {
if p.epoller == nil {
- return nil, errors.New("uninitialized epoller")
+ return nil, fmt.Errorf("uninitialized epoller")
}
epollConsole, err := p.epoller.Add(console)
@@ -79,11 +79,11 @@ func (p *linuxPlatform) CopyConsole(ctx context.Context, console console.Console
func (p *linuxPlatform) ShutdownConsole(ctx context.Context, cons console.Console) error {
if p.epoller == nil {
- return errors.New("uninitialized epoller")
+ return fmt.Errorf("uninitialized epoller")
}
epollConsole, ok := cons.(*console.EpollConsole)
if !ok {
- return errors.Errorf("expected EpollConsole, got %#v", cons)
+ return fmt.Errorf("expected EpollConsole, got %#v", cons)
}
return epollConsole.Shutdown(p.epoller.CloseConsole)
}
@@ -100,7 +100,7 @@ func (s *Service) initPlatform() error {
}
epoller, err := console.NewEpoller()
if err != nil {
- return errors.Wrap(err, "failed to initialize epoller")
+ return fmt.Errorf("failed to initialize epoller: %w", err)
}
s.platform = &linuxPlatform{
epoller: epoller,
diff --git a/pkg/shim/v1/shim/service.go b/pkg/shim/v1/shim/service.go
index aac172801..7b0280ed2 100644
--- a/pkg/shim/v1/shim/service.go
+++ b/pkg/shim/v1/shim/service.go
@@ -37,8 +37,6 @@ import (
shimapi "github.com/containerd/containerd/runtime/v1/shim/v1"
"github.com/containerd/typeurl"
ptypes "github.com/gogo/protobuf/types"
- "github.com/pkg/errors"
- "github.com/sirupsen/logrus"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
@@ -57,7 +55,7 @@ var (
}
)
-// Config contains shim specific configuration
+// Config contains shim specific configuration.
type Config struct {
Path string
Namespace string
@@ -66,17 +64,12 @@ type Config struct {
RunscConfig map[string]string
}
-// NewService returns a new shim service that can be used via GRPC
+// 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)
- ctx = log.WithLogger(ctx, logrus.WithFields(logrus.Fields{
- "namespace": config.Namespace,
- "path": config.Path,
- "pid": os.Getpid(),
- }))
s := &Service{
config: config,
context: ctx,
@@ -86,13 +79,13 @@ func NewService(config Config, publisher events.Publisher) (*Service, error) {
}
go s.processExits()
if err := s.initPlatform(); err != nil {
- return nil, errors.Wrap(err, "failed to initialized platform behavior")
+ 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
+// Service is the shim implementation of a remote shim over GRPC.
type Service struct {
mu sync.Mutex
@@ -108,7 +101,7 @@ type Service struct {
bundle string
}
-// Create a new initial process and container with the underlying OCI runtime
+// Create creates a new initial process and container with the underlying OCI runtime.
func (s *Service) Create(ctx context.Context, r *shimapi.CreateTaskRequest) (_ *shimapi.CreateTaskResponse, err error) {
s.mu.Lock()
defer s.mu.Unlock()
@@ -153,7 +146,7 @@ func (s *Service) Create(ctx context.Context, r *shimapi.CreateTaskRequest) (_ *
Options: rm.Options,
}
if err := m.Mount(rootfs); err != nil {
- return nil, errors.Wrapf(err, "failed to mount rootfs component %v", m)
+ return nil, fmt.Errorf("failed to mount rootfs component %v: %w", m, err)
}
}
process, err := newInit(
@@ -169,7 +162,8 @@ func (s *Service) Create(ctx context.Context, r *shimapi.CreateTaskRequest) (_ *
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
+ // Save the main task id and bundle to the shim for additional
+ // requests.
s.id = r.ID
s.bundle = r.Bundle
pid := process.Pid()
@@ -179,7 +173,7 @@ func (s *Service) Create(ctx context.Context, r *shimapi.CreateTaskRequest) (_ *
}, nil
}
-// Start a process
+// Start starts a process.
func (s *Service) Start(ctx context.Context, r *shimapi.StartRequest) (*shimapi.StartResponse, error) {
p, err := s.getExecProcess(r.ID)
if err != nil {
@@ -194,7 +188,7 @@ func (s *Service) Start(ctx context.Context, r *shimapi.StartRequest) (*shimapi.
}, nil
}
-// Delete the initial process and container
+// Delete deletes the initial process and container.
func (s *Service) Delete(ctx context.Context, r *ptypes.Empty) (*shimapi.DeleteResponse, error) {
p, err := s.getInitProcess()
if err != nil {
@@ -214,7 +208,7 @@ func (s *Service) Delete(ctx context.Context, r *ptypes.Empty) (*shimapi.DeleteR
}, nil
}
-// DeleteProcess deletes an exec'd process
+// DeleteProcess deletes an exec'd process.
func (s *Service) DeleteProcess(ctx context.Context, r *shimapi.DeleteProcessRequest) (*shimapi.DeleteResponse, error) {
if r.ID == s.id {
return nil, status.Errorf(codes.InvalidArgument, "cannot delete init process with DeleteProcess")
@@ -236,7 +230,7 @@ func (s *Service) DeleteProcess(ctx context.Context, r *shimapi.DeleteProcessReq
}, nil
}
-// Exec an additional process inside the container
+// Exec spawns an additional process inside the container.
func (s *Service) Exec(ctx context.Context, r *shimapi.ExecProcessRequest) (*ptypes.Empty, error) {
s.mu.Lock()
@@ -268,7 +262,7 @@ func (s *Service) Exec(ctx context.Context, r *shimapi.ExecProcessRequest) (*pty
return empty, nil
}
-// ResizePty of a process
+// ResizePty resises the terminal of a process.
func (s *Service) ResizePty(ctx context.Context, r *shimapi.ResizePtyRequest) (*ptypes.Empty, error) {
if r.ID == "" {
return nil, errdefs.ToGRPCf(errdefs.ErrInvalidArgument, "id not provided")
@@ -287,7 +281,7 @@ func (s *Service) ResizePty(ctx context.Context, r *shimapi.ResizePtyRequest) (*
return empty, nil
}
-// State returns runtime state information for a process
+// State returns runtime state information for a process.
func (s *Service) State(ctx context.Context, r *shimapi.StateRequest) (*shimapi.StateResponse, error) {
p, err := s.getExecProcess(r.ID)
if err != nil {
@@ -321,17 +315,17 @@ func (s *Service) State(ctx context.Context, r *shimapi.StateRequest) (*shimapi.
}, nil
}
-// Pause the container
+// Pause pauses the container.
func (s *Service) Pause(ctx context.Context, r *ptypes.Empty) (*ptypes.Empty, error) {
return empty, errdefs.ToGRPC(errdefs.ErrNotImplemented)
}
-// Resume the container
+// Resume resumes the container.
func (s *Service) Resume(ctx context.Context, r *ptypes.Empty) (*ptypes.Empty, error) {
return empty, errdefs.ToGRPC(errdefs.ErrNotImplemented)
}
-// Kill a process with the provided signal
+// Kill kills a process with the provided signal.
func (s *Service) Kill(ctx context.Context, r *shimapi.KillRequest) (*ptypes.Empty, error) {
if r.ID == "" {
p, err := s.getInitProcess()
@@ -354,7 +348,7 @@ func (s *Service) Kill(ctx context.Context, r *shimapi.KillRequest) (*ptypes.Emp
return empty, nil
}
-// ListPids returns all pids inside the container
+// ListPids returns all pids inside the container.
func (s *Service) ListPids(ctx context.Context, r *shimapi.ListPidsRequest) (*shimapi.ListPidsResponse, error) {
pids, err := s.getContainerPids(ctx, r.ID)
if err != nil {
@@ -372,7 +366,7 @@ func (s *Service) ListPids(ctx context.Context, r *shimapi.ListPidsRequest) (*sh
}
a, err := typeurl.MarshalAny(d)
if err != nil {
- return nil, errors.Wrapf(err, "failed to marshal process %d info", pid)
+ return nil, fmt.Errorf("failed to marshal process %d info: %w", pid, err)
}
pInfo.Info = a
break
@@ -385,7 +379,7 @@ func (s *Service) ListPids(ctx context.Context, r *shimapi.ListPidsRequest) (*sh
}, nil
}
-// CloseIO of a process
+// CloseIO closes the I/O context of a process.
func (s *Service) CloseIO(ctx context.Context, r *shimapi.CloseIORequest) (*ptypes.Empty, error) {
p, err := s.getExecProcess(r.ID)
if err != nil {
@@ -393,30 +387,30 @@ func (s *Service) CloseIO(ctx context.Context, r *shimapi.CloseIORequest) (*ptyp
}
if stdin := p.Stdin(); stdin != nil {
if err := stdin.Close(); err != nil {
- return nil, errors.Wrap(err, "close stdin")
+ return nil, fmt.Errorf("close stdin: %w", err)
}
}
return empty, nil
}
-// Checkpoint the container
+// Checkpoint checkpoints the container.
func (s *Service) Checkpoint(ctx context.Context, r *shimapi.CheckpointTaskRequest) (*ptypes.Empty, error) {
return empty, errdefs.ToGRPC(errdefs.ErrNotImplemented)
}
-// ShimInfo returns shim information such as the shim's pid
+// ShimInfo returns shim information such as the shim's pid.
func (s *Service) ShimInfo(ctx context.Context, r *ptypes.Empty) (*shimapi.ShimInfoResponse, error) {
return &shimapi.ShimInfoResponse{
ShimPid: uint32(os.Getpid()),
}, nil
}
-// Update a running container
+// Update updates a running container.
func (s *Service) Update(ctx context.Context, r *shimapi.UpdateTaskRequest) (*ptypes.Empty, error) {
return empty, errdefs.ToGRPC(errdefs.ErrNotImplemented)
}
-// Wait for a process to exit
+// Wait waits for a process to exit.
func (s *Service) Wait(ctx context.Context, r *shimapi.WaitRequest) (*shimapi.WaitResponse, error) {
p, err := s.getExecProcess(r.ID)
if err != nil {
@@ -451,7 +445,7 @@ 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
+ // 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")
@@ -495,7 +489,7 @@ func (s *Service) forward(publisher events.Publisher) {
}
}
-// getInitProcess returns initial process
+// getInitProcess returns the init process.
func (s *Service) getInitProcess() (rproc.Process, error) {
s.mu.Lock()
defer s.mu.Unlock()
@@ -506,7 +500,7 @@ func (s *Service) getInitProcess() (rproc.Process, error) {
return p, nil
}
-// getExecProcess returns exec process
+// getExecProcess returns the given exec process.
func (s *Service) getExecProcess(id string) (rproc.Process, error) {
s.mu.Lock()
defer s.mu.Unlock()
@@ -534,7 +528,7 @@ func getTopic(ctx context.Context, e interface{}) string {
case *eventstypes.TaskExecStarted:
return runtime.TaskExecStartedEventTopic
default:
- logrus.Warnf("no topic for type %#v", e)
+ log.L.Printf("no topic for type %#v", e)
}
return runtime.TaskUnknownTopic
}
@@ -551,10 +545,10 @@ func newInit(ctx context.Context, path, workDir, runtimeRoot, namespace string,
spec, err := utils.ReadSpec(r.Bundle)
if err != nil {
- return nil, errors.Wrap(err, "read oci spec")
+ return nil, fmt.Errorf("read oci spec: %w", err)
}
if err := utils.UpdateVolumeAnnotations(r.Bundle, spec); err != nil {
- return nil, errors.Wrap(err, "update volume annotations")
+ return nil, fmt.Errorf("update volume annotations: %w", err)
}
runsc.FormatLogPath(r.ID, config)
diff --git a/pkg/shim/v1/utils/BUILD b/pkg/shim/v1/utils/BUILD
new file mode 100644
index 000000000..9045781e1
--- /dev/null
+++ b/pkg/shim/v1/utils/BUILD
@@ -0,0 +1,26 @@
+load("//tools:defs.bzl", "go_library", "go_test")
+
+package(licenses = ["notice"])
+
+go_library(
+ name = "utils",
+ srcs = [
+ "utils.go",
+ "volumes.go",
+ ],
+ visibility = [
+ "//pkg/shim:__subpackages__",
+ "//shim:__subpackages__",
+ ],
+ deps = [
+ "@com_github_containerd_cri//pkg/annotations:go_default_library",
+ "@com_github_opencontainers_runtime-spec//specs-go:go_default_library",
+ ],
+)
+
+go_test(
+ name = "utils_test",
+ size = "small",
+ srcs = ["volumes_test.go"],
+ library = ":utils",
+)
diff --git a/pkg/shim/v1/utils/volumes.go b/pkg/shim/v1/utils/volumes.go
index 7323e7245..e4e9bf9b1 100644
--- a/pkg/shim/v1/utils/volumes.go
+++ b/pkg/shim/v1/utils/volumes.go
@@ -23,8 +23,6 @@ import (
"github.com/containerd/cri/pkg/annotations"
specs "github.com/opencontainers/runtime-spec/specs-go"
- "github.com/pkg/errors"
- "github.com/sirupsen/logrus"
)
const volumeKeyPrefix = "dev.gvisor.spec.mount."
@@ -32,13 +30,13 @@ const volumeKeyPrefix = "dev.gvisor.spec.mount."
var kubeletPodsDir = "/var/lib/kubelet/pods"
// volumeName gets volume name from volume annotation key, example:
-// dev.gvisor.spec.mount.NAME.share
+// dev.gvisor.spec.mount.NAME.share
func volumeName(k string) string {
return strings.SplitN(strings.TrimPrefix(k, volumeKeyPrefix), ".", 2)[0]
}
// volumeFieldName gets volume field name from volume annotation key, example:
-// `type` is the field of dev.gvisor.spec.mount.NAME.type
+// `type` is the field of dev.gvisor.spec.mount.NAME.type
func volumeFieldName(k string) string {
parts := strings.Split(strings.TrimPrefix(k, volumeKeyPrefix), ".")
return parts[len(parts)-1]
@@ -48,16 +46,16 @@ func volumeFieldName(k string) string {
func podUID(s *specs.Spec) (string, error) {
sandboxLogDir := s.Annotations[annotations.SandboxLogDir]
if sandboxLogDir == "" {
- return "", errors.New("no sandbox log path annotation")
+ return "", fmt.Errorf("no sandbox log path annotation")
}
fields := strings.Split(filepath.Base(sandboxLogDir), "_")
switch len(fields) {
- case 1: // This is the old CRI logging path
+ case 1: // This is the old CRI logging path.
return fields[0], nil
- case 3: // This is the new CRI logging path
+ case 3: // This is the new CRI logging path.
return fields[2], nil
}
- return "", errors.Errorf("unexpected sandbox log path %q", sandboxLogDir)
+ return "", fmt.Errorf("unexpected sandbox log path %q", sandboxLogDir)
}
// isVolumeKey checks whether an annotation key is for volume.
@@ -79,7 +77,7 @@ func volumePath(volume, uid string) (string, error) {
return "", err
}
if len(dirs) != 1 {
- return "", errors.Errorf("unexpected matched volume list %v", dirs)
+ return "", fmt.Errorf("unexpected matched volume list %v", dirs)
}
return dirs[0], nil
}
@@ -103,7 +101,7 @@ func UpdateVolumeAnnotations(bundle string, s *specs.Spec) error {
if err != nil {
// Skip if we can't get pod UID, because this doesn't work
// for containerd 1.1.
- logrus.WithError(err).Error("Can't get pod uid")
+ fmt.Errorf("Can't get pod uid: %w", err)
return nil
}
}
@@ -117,22 +115,25 @@ func UpdateVolumeAnnotations(bundle string, s *specs.Spec) error {
}
volume := volumeName(k)
if uid != "" {
- // This is a sandbox
+ // This is a sandbox.
path, err := volumePath(volume, uid)
if err != nil {
- return errors.Wrapf(err, "get volume path for %q", volume)
+ return fmt.Errorf("get volume path for %q: %w", volume, err)
}
s.Annotations[volumeSourceKey(volume)] = path
updated = true
} else {
- // This is a container
+ // This is a container.
for i := range s.Mounts {
- // An error is returned for sandbox if source annotation
- // is not successfully applied, so it is guaranteed that
- // the source annotation for sandbox has already been
- // successfully applied at this point.
- // The volume name is unique inside a pod, so matching without
- // podUID is fine here.
+ // An error is returned for sandbox if source
+ // annotation is not successfully applied, so
+ // it is guaranteed that the source annotation
+ // for sandbox has already been successfully
+ // applied at this point.
+ //
+ // The volume name is unique inside a pod, so
+ // matching without podUID is fine here.
+ //
// TODO: Pass podUID down to shim for containers to do
// more accurate matching.
if yes, _ := isVolumePath(volume, s.Mounts[i].Source); yes {
@@ -147,7 +148,7 @@ func UpdateVolumeAnnotations(bundle string, s *specs.Spec) error {
if !updated {
return nil
}
- // Update bundle
+ // Update bundle.
b, err := json.Marshal(s)
if err != nil {
return err
diff --git a/pkg/shim/v2/BUILD b/pkg/shim/v2/BUILD
new file mode 100644
index 000000000..450f62979
--- /dev/null
+++ b/pkg/shim/v2/BUILD
@@ -0,0 +1,41 @@
+load("//tools:defs.bzl", "go_library")
+
+package(licenses = ["notice"])
+
+go_library(
+ name = "v2",
+ srcs = [
+ "epoll.go",
+ "service.go",
+ "service_linux.go",
+ ],
+ visibility = ["//shim:__subpackages__"],
+ deps = [
+ "//pkg/shim/runsc",
+ "//pkg/shim/v1/proc",
+ "//pkg/shim/v1/utils",
+ "//pkg/shim/v2/options",
+ "//runsc/specutils",
+ "@com_github_burntsushi_toml//:go_default_library",
+ "@com_github_containerd_cgroups//:go_default_library",
+ "@com_github_containerd_cgroups//stats/v1:go_default_library",
+ "@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//runtime:go_default_library",
+ "@com_github_containerd_containerd//runtime/linux/runctypes:go_default_library",
+ "@com_github_containerd_containerd//runtime/proc:go_default_library",
+ "@com_github_containerd_containerd//runtime/v2/shim:go_default_library",
+ "@com_github_containerd_containerd//runtime/v2/task:go_default_library",
+ "@com_github_containerd_cri//pkg/api/runtimeoptions/v1: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_x_sys//unix:go_default_library",
+ ],
+)
diff --git a/pkg/shim/v2/epoll.go b/pkg/shim/v2/epoll.go
index 57a2c5452..45cc38c2a 100644
--- a/pkg/shim/v2/epoll.go
+++ b/pkg/shim/v2/epoll.go
@@ -19,13 +19,13 @@ package v2
import (
"context"
+ "fmt"
"sync"
"github.com/containerd/cgroups"
eventstypes "github.com/containerd/containerd/api/events"
"github.com/containerd/containerd/events"
"github.com/containerd/containerd/runtime"
- "github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)
@@ -71,7 +71,7 @@ func (e *epoller) run(ctx context.Context) {
if err == unix.EINTR {
continue
}
- logrus.WithError(err).Error("cgroups: epoll wait")
+ fmt.Errorf("cgroups: epoll wait: %w", err)
}
for i := 0; i < n; i++ {
e.process(ctx, uintptr(events[i].Fd))
@@ -117,7 +117,7 @@ func (e *epoller) process(ctx context.Context, fd uintptr) {
if err := e.publisher.Publish(ctx, runtime.TaskOOMEventTopic, &eventstypes.TaskOOM{
ContainerID: i.id,
}); err != nil {
- logrus.WithError(err).Error("publish OOM event")
+ fmt.Errorf("publish OOM event: %w", err)
}
}
diff --git a/pkg/shim/v2/options/BUILD b/pkg/shim/v2/options/BUILD
new file mode 100644
index 000000000..ca212e874
--- /dev/null
+++ b/pkg/shim/v2/options/BUILD
@@ -0,0 +1,11 @@
+load("//tools:defs.bzl", "go_library")
+
+package(licenses = ["notice"])
+
+go_library(
+ name = "options",
+ srcs = [
+ "options.go",
+ ],
+ visibility = ["//:sandbox"],
+)
diff --git a/pkg/shim/v2/service.go b/pkg/shim/v2/service.go
index 0cff82a89..c67b1beba 100644
--- a/pkg/shim/v2/service.go
+++ b/pkg/shim/v2/service.go
@@ -16,6 +16,7 @@ package v2
import (
"context"
+ "fmt"
"io/ioutil"
"os"
"os/exec"
@@ -26,6 +27,7 @@ import (
"github.com/BurntSushi/toml"
"github.com/containerd/cgroups"
+ metrics "github.com/containerd/cgroups/stats/v1"
"github.com/containerd/console"
eventstypes "github.com/containerd/containerd/api/events"
"github.com/containerd/containerd/api/types/task"
@@ -42,14 +44,13 @@ import (
runtimeoptions "github.com/containerd/cri/pkg/api/runtimeoptions/v1"
"github.com/containerd/typeurl"
ptypes "github.com/gogo/protobuf/types"
- "github.com/pkg/errors"
- "github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
"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/options"
+ "gvisor.dev/gvisor/runsc/specutils"
)
var (
@@ -68,7 +69,7 @@ var _ = (taskAPI.TaskService)(&service{})
// we assume that a config.toml should exist in the runtime root.
const configFile = "config.toml"
-// New returns a new shim service that can be used via GRPC
+// New returns a new shim service that can be used via GRPC.
func New(ctx context.Context, id string, publisher events.Publisher) (shim.Shim, error) {
ep, err := newOOMEpoller(publisher)
if err != nil {
@@ -89,13 +90,13 @@ func New(ctx context.Context, id string, publisher events.Publisher) (shim.Shim,
runsc.Monitor = shim.Default
if err := s.initPlatform(); err != nil {
cancel()
- return nil, errors.Wrap(err, "failed to initialized platform behavior")
+ 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
+// service is the shim implementation of a remote shim over GRPC.
type service struct {
mu sync.Mutex
@@ -179,7 +180,7 @@ func (s *service) StartShim(ctx context.Context, id, containerdBinary, container
return "", err
}
if err := shim.SetScore(cmd.Process.Pid); err != nil {
- return "", errors.Wrap(err, "failed to set OOM Score on shim")
+ return "", fmt.Errorf("failed to set OOM Score on shim: %w", err)
}
return address, nil
}
@@ -201,10 +202,10 @@ func (s *service) Cleanup(ctx context.Context) (*taskAPI.DeleteResponse, error)
if err := r.Delete(ctx, s.id, &runsc.DeleteOpts{
Force: true,
}); err != nil {
- logrus.WithError(err).Warn("failed to remove runc container")
+ log.L.Printf("failed to remove runc container: %v", err)
}
if err := mount.UnmountAll(filepath.Join(path, "rootfs"), 0); err != nil {
- logrus.WithError(err).Warn("failed to cleanup rootfs mount")
+ log.L.Printf("failed to cleanup rootfs mount: %v", err)
}
return &taskAPI.DeleteResponse{
ExitedAt: time.Now(),
@@ -224,14 +225,15 @@ func (s *service) writeRuntime(path, runtime string) error {
return ioutil.WriteFile(filepath.Join(path, "runtime"), []byte(runtime), 0600)
}
-// Create a new initial process and container with the underlying OCI runtime
+// Create creates a new initial process and container with the underlying OCI
+// runtime.
func (s *service) Create(ctx context.Context, r *taskAPI.CreateTaskRequest) (_ *taskAPI.CreateTaskResponse, err error) {
s.mu.Lock()
defer s.mu.Unlock()
ns, err := namespaces.NamespaceRequired(ctx)
if err != nil {
- return nil, errors.Wrap(err, "create namespace")
+ return nil, fmt.Errorf("create namespace: %w", err)
}
// Read from root for now.
@@ -258,7 +260,7 @@ func (s *service) Create(ctx context.Context, r *taskAPI.CreateTaskRequest) (_ *
path = filepath.Join(root, configFile)
if _, err := os.Stat(path); err != nil {
if !os.IsNotExist(err) {
- return nil, errors.Wrapf(err, "stat config file %q", path)
+ return nil, fmt.Errorf("stat config file %q: %w", path, err)
}
// A config file in runtime root is not required.
path = ""
@@ -268,15 +270,15 @@ func (s *service) Create(ctx context.Context, r *taskAPI.CreateTaskRequest) (_ *
break
}
if o.TypeUrl != options.OptionType {
- return nil, errors.Errorf("unsupported runtimeoptions %q", o.TypeUrl)
+ return nil, fmt.Errorf("unsupported runtimeoptions %q", o.TypeUrl)
}
path = o.ConfigPath
default:
- return nil, errors.Errorf("unsupported option type %q", r.Options.TypeUrl)
+ return nil, fmt.Errorf("unsupported option type %q", r.Options.TypeUrl)
}
if path != "" {
if _, err = toml.DecodeFile(path, &opts); err != nil {
- return nil, errors.Wrapf(err, "decode config file %q", path)
+ return nil, fmt.Errorf("decode config file %q: %w", path, err)
}
}
}
@@ -312,8 +314,8 @@ func (s *service) Create(ctx context.Context, r *taskAPI.CreateTaskRequest) (_ *
}
defer func() {
if err != nil {
- if err2 := mount.UnmountAll(rootfs, 0); err2 != nil {
- logrus.WithError(err2).Warn("failed to cleanup rootfs mount")
+ if err := mount.UnmountAll(rootfs, 0); err != nil {
+ log.L.Printf("failed to cleanup rootfs mount: %v", err)
}
}
}()
@@ -324,7 +326,7 @@ func (s *service) Create(ctx context.Context, r *taskAPI.CreateTaskRequest) (_ *
Options: rm.Options,
}
if err := m.Mount(rootfs); err != nil {
- return nil, errors.Wrapf(err, "failed to mount rootfs component %v", m)
+ return nil, fmt.Errorf("failed to mount rootfs component %v: %w", m, err)
}
}
process, err := newInit(
@@ -343,20 +345,21 @@ func (s *service) Create(ctx context.Context, r *taskAPI.CreateTaskRequest) (_ *
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
+ // Save the main task id and bundle to the shim for additional
+ // requests.
s.id = r.ID
s.bundle = r.Bundle
- // Set up OOM notification on the sandbox's cgroup. This is done on sandbox
- // create since the sandbox process will be created here.
+ // Set up OOM notification on the sandbox's cgroup. This is done on
+ // sandbox create since the sandbox process will be created here.
pid := process.Pid()
if pid > 0 {
cg, err := cgroups.Load(cgroups.V1, cgroups.PidPath(pid))
if err != nil {
- return nil, errors.Wrapf(err, "loading cgroup for %d", pid)
+ return nil, fmt.Errorf("loading cgroup for %d: %w", pid, err)
}
if err := s.oomPoller.add(s.id, cg); err != nil {
- return nil, errors.Wrapf(err, "add cg to OOM monitor")
+ return nil, fmt.Errorf("add cg to OOM monitor: %w", err)
}
}
s.task = process
@@ -367,7 +370,7 @@ func (s *service) Create(ctx context.Context, r *taskAPI.CreateTaskRequest) (_ *
}
-// Start a process
+// Start starts a process.
func (s *service) Start(ctx context.Context, r *taskAPI.StartRequest) (*taskAPI.StartResponse, error) {
p, err := s.getProcess(r.ExecID)
if err != nil {
@@ -383,7 +386,7 @@ func (s *service) Start(ctx context.Context, r *taskAPI.StartRequest) (*taskAPI.
}, nil
}
-// Delete the initial process and container
+// Delete deletes the initial process and container.
func (s *service) Delete(ctx context.Context, r *taskAPI.DeleteRequest) (*taskAPI.DeleteResponse, error) {
p, err := s.getProcess(r.ExecID)
if err != nil {
@@ -411,7 +414,7 @@ func (s *service) Delete(ctx context.Context, r *taskAPI.DeleteRequest) (*taskAP
}, nil
}
-// Exec an additional process inside the container
+// Exec spawns an additional process inside the container.
func (s *service) Exec(ctx context.Context, r *taskAPI.ExecProcessRequest) (*ptypes.Empty, error) {
s.mu.Lock()
p := s.processes[r.ExecID]
@@ -440,7 +443,7 @@ func (s *service) Exec(ctx context.Context, r *taskAPI.ExecProcessRequest) (*pty
return empty, nil
}
-// ResizePty of a process
+// ResizePty resizes the terminal of a process.
func (s *service) ResizePty(ctx context.Context, r *taskAPI.ResizePtyRequest) (*ptypes.Empty, error) {
p, err := s.getProcess(r.ExecID)
if err != nil {
@@ -456,7 +459,7 @@ func (s *service) ResizePty(ctx context.Context, r *taskAPI.ResizePtyRequest) (*
return empty, nil
}
-// State returns runtime state information for a process
+// State returns runtime state information for a process.
func (s *service) State(ctx context.Context, r *taskAPI.StateRequest) (*taskAPI.StateResponse, error) {
p, err := s.getProcess(r.ExecID)
if err != nil {
@@ -490,17 +493,17 @@ func (s *service) State(ctx context.Context, r *taskAPI.StateRequest) (*taskAPI.
}, nil
}
-// Pause the container
+// Pause the container.
func (s *service) Pause(ctx context.Context, r *taskAPI.PauseRequest) (*ptypes.Empty, error) {
return empty, errdefs.ToGRPC(errdefs.ErrNotImplemented)
}
-// Resume the container
+// Resume the container.
func (s *service) Resume(ctx context.Context, r *taskAPI.ResumeRequest) (*ptypes.Empty, error) {
return empty, errdefs.ToGRPC(errdefs.ErrNotImplemented)
}
-// Kill a process with the provided signal
+// Kill a process with the provided signal.
func (s *service) Kill(ctx context.Context, r *taskAPI.KillRequest) (*ptypes.Empty, error) {
p, err := s.getProcess(r.ExecID)
if err != nil {
@@ -515,7 +518,7 @@ func (s *service) Kill(ctx context.Context, r *taskAPI.KillRequest) (*ptypes.Emp
return empty, nil
}
-// Pids returns all pids inside the container
+// Pids returns all pids inside the container.
func (s *service) Pids(ctx context.Context, r *taskAPI.PidsRequest) (*taskAPI.PidsResponse, error) {
pids, err := s.getContainerPids(ctx, r.ID)
if err != nil {
@@ -533,7 +536,7 @@ func (s *service) Pids(ctx context.Context, r *taskAPI.PidsRequest) (*taskAPI.Pi
}
a, err := typeurl.MarshalAny(d)
if err != nil {
- return nil, errors.Wrapf(err, "failed to marshal process %d info", pid)
+ return nil, fmt.Errorf("failed to marshal process %d info: %w", pid, err)
}
pInfo.Info = a
break
@@ -546,7 +549,7 @@ func (s *service) Pids(ctx context.Context, r *taskAPI.PidsRequest) (*taskAPI.Pi
}, nil
}
-// CloseIO of a process
+// CloseIO closes the I/O context of a process.
func (s *service) CloseIO(ctx context.Context, r *taskAPI.CloseIORequest) (*ptypes.Empty, error) {
p, err := s.getProcess(r.ExecID)
if err != nil {
@@ -554,18 +557,18 @@ func (s *service) CloseIO(ctx context.Context, r *taskAPI.CloseIORequest) (*ptyp
}
if stdin := p.Stdin(); stdin != nil {
if err := stdin.Close(); err != nil {
- return nil, errors.Wrap(err, "close stdin")
+ return nil, fmt.Errorf("close stdin: %w", err)
}
}
return empty, nil
}
-// Checkpoint the container
+// Checkpoint checkpoints the container.
func (s *service) Checkpoint(ctx context.Context, r *taskAPI.CheckpointTaskRequest) (*ptypes.Empty, error) {
return empty, errdefs.ToGRPC(errdefs.ErrNotImplemented)
}
-// Connect returns shim information such as the shim's pid
+// Connect returns shim information such as the shim's pid.
func (s *service) Connect(ctx context.Context, r *taskAPI.ConnectRequest) (*taskAPI.ConnectResponse, error) {
var pid int
if s.task != nil {
@@ -605,52 +608,52 @@ func (s *service) Stats(ctx context.Context, r *taskAPI.StatsRequest) (*taskAPI.
// gvisor currently (as of 2020-03-03) only returns the total memory
// usage and current PID value[0]. However, we copy the common fields here
// so that future updates will propagate correct information. We're
- // using the cgroups.Metrics structure so we're returning the same type
+ // using the metrics.Metrics structure so we're returning the same type
// as runc.
//
// [0]: https://github.com/google/gvisor/blob/277a0d5a1fbe8272d4729c01ee4c6e374d047ebc/runsc/boot/events.go#L61-L81
- data, err := typeurl.MarshalAny(&cgroups.Metrics{
- CPU: &cgroups.CPUStat{
- Usage: &cgroups.CPUUsage{
+ data, err := typeurl.MarshalAny(&metrics.Metrics{
+ CPU: &metrics.CPUStat{
+ Usage: &metrics.CPUUsage{
Total: stats.Cpu.Usage.Total,
Kernel: stats.Cpu.Usage.Kernel,
User: stats.Cpu.Usage.User,
PerCPU: stats.Cpu.Usage.Percpu,
},
- Throttling: &cgroups.Throttle{
+ Throttling: &metrics.Throttle{
Periods: stats.Cpu.Throttling.Periods,
ThrottledPeriods: stats.Cpu.Throttling.ThrottledPeriods,
ThrottledTime: stats.Cpu.Throttling.ThrottledTime,
},
},
- Memory: &cgroups.MemoryStat{
+ Memory: &metrics.MemoryStat{
Cache: stats.Memory.Cache,
- Usage: &cgroups.MemoryEntry{
+ Usage: &metrics.MemoryEntry{
Limit: stats.Memory.Usage.Limit,
Usage: stats.Memory.Usage.Usage,
Max: stats.Memory.Usage.Max,
Failcnt: stats.Memory.Usage.Failcnt,
},
- Swap: &cgroups.MemoryEntry{
+ Swap: &metrics.MemoryEntry{
Limit: stats.Memory.Swap.Limit,
Usage: stats.Memory.Swap.Usage,
Max: stats.Memory.Swap.Max,
Failcnt: stats.Memory.Swap.Failcnt,
},
- Kernel: &cgroups.MemoryEntry{
+ Kernel: &metrics.MemoryEntry{
Limit: stats.Memory.Kernel.Limit,
Usage: stats.Memory.Kernel.Usage,
Max: stats.Memory.Kernel.Max,
Failcnt: stats.Memory.Kernel.Failcnt,
},
- KernelTCP: &cgroups.MemoryEntry{
+ KernelTCP: &metrics.MemoryEntry{
Limit: stats.Memory.KernelTCP.Limit,
Usage: stats.Memory.KernelTCP.Usage,
Max: stats.Memory.KernelTCP.Max,
Failcnt: stats.Memory.KernelTCP.Failcnt,
},
},
- Pids: &cgroups.PidsStat{
+ Pids: &metrics.PidsStat{
Current: stats.Pids.Current,
Limit: stats.Pids.Limit,
},
@@ -663,12 +666,12 @@ func (s *service) Stats(ctx context.Context, r *taskAPI.StatsRequest) (*taskAPI.
}, nil
}
-// Update a running container
+// Update updates a running container.
func (s *service) Update(ctx context.Context, r *taskAPI.UpdateTaskRequest) (*ptypes.Empty, error) {
return empty, errdefs.ToGRPC(errdefs.ErrNotImplemented)
}
-// Wait for a process to exit
+// Wait waits for a process to exit.
func (s *service) Wait(ctx context.Context, r *taskAPI.WaitRequest) (*taskAPI.WaitResponse, error) {
p, err := s.getProcess(r.ExecID)
if err != nil {
@@ -697,7 +700,7 @@ 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
+ // 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")
@@ -733,7 +736,7 @@ func (s *service) getContainerPids(ctx context.Context, id string) ([]uint32, er
p := s.task
s.mu.Unlock()
if p == nil {
- return nil, errors.Wrapf(errdefs.ErrFailedPrecondition, "container must be created")
+ return nil, fmt.Errorf("container must be created: %w", errdefs.ErrFailedPrecondition)
}
ps, err := p.(*proc.Init).Runtime().Ps(ctx, id)
if err != nil {
@@ -752,7 +755,7 @@ func (s *service) forward(publisher events.Publisher) {
err := publisher.Publish(ctx, getTopic(e), e)
cancel()
if err != nil {
- logrus.WithError(err).Error("post event")
+ fmt.Errorf("post event: %w", err)
}
}
}
@@ -787,7 +790,7 @@ func getTopic(e interface{}) string {
case *eventstypes.TaskExecStarted:
return runtime.TaskExecStartedEventTopic
default:
- logrus.Warnf("no topic for type %#v", e)
+ log.L.Printf("no topic for type %#v", e)
}
return runtime.TaskUnknownTopic
}
@@ -795,10 +798,10 @@ func getTopic(e interface{}) string {
func newInit(ctx context.Context, path, workDir, namespace string, platform rproc.Platform, r *proc.CreateConfig, options *options.Options, rootfs string) (*proc.Init, error) {
spec, err := utils.ReadSpec(r.Bundle)
if err != nil {
- return nil, errors.Wrap(err, "read oci spec")
+ return nil, fmt.Errorf("read oci spec: %w", err)
}
if err := utils.UpdateVolumeAnnotations(r.Bundle, spec); err != nil {
- return nil, errors.Wrap(err, "update volume annotations")
+ return nil, fmt.Errorf("update volume annotations: %w", err)
}
runsc.FormatLogPath(r.ID, options.RunscConfig)
runtime := proc.NewRunsc(options.Root, path, namespace, options.BinaryName, options.RunscConfig)
@@ -814,7 +817,7 @@ func newInit(ctx context.Context, path, workDir, namespace string, platform rpro
p.WorkDir = workDir
p.IoUID = int(options.IoUid)
p.IoGID = int(options.IoGid)
- p.Sandbox = utils.IsSandbox(spec)
+ p.Sandbox = specutils.SpecContainerType(spec) == specutils.ContainerTypeSandbox
p.UserLog = utils.UserLogPath(spec)
p.Monitor = shim.Default
return p, nil
diff --git a/pkg/shim/v2/service_linux.go b/pkg/shim/v2/service_linux.go
index cd259cd44..257c58812 100644
--- a/pkg/shim/v2/service_linux.go
+++ b/pkg/shim/v2/service_linux.go
@@ -19,13 +19,13 @@ package v2
import (
"context"
+ "fmt"
"io"
"sync"
"syscall"
"github.com/containerd/console"
"github.com/containerd/fifo"
- "github.com/pkg/errors"
)
type linuxPlatform struct {
@@ -34,7 +34,7 @@ type linuxPlatform struct {
func (p *linuxPlatform) CopyConsole(ctx context.Context, console console.Console, stdin, stdout, stderr string, wg, cwg *sync.WaitGroup) (console.Console, error) {
if p.epoller == nil {
- return nil, errors.New("uninitialized epoller")
+ return nil, fmt.Errorf("uninitialized epoller")
}
epollConsole, err := p.epoller.Add(console)
@@ -81,11 +81,11 @@ func (p *linuxPlatform) CopyConsole(ctx context.Context, console console.Console
func (p *linuxPlatform) ShutdownConsole(ctx context.Context, cons console.Console) error {
if p.epoller == nil {
- return errors.New("uninitialized epoller")
+ return fmt.Errorf("uninitialized epoller")
}
epollConsole, ok := cons.(*console.EpollConsole)
if !ok {
- return errors.Errorf("expected EpollConsole, got %#v", cons)
+ return fmt.Errorf("expected EpollConsole, got %#v", cons)
}
return epollConsole.Shutdown(p.epoller.CloseConsole)
}
@@ -102,7 +102,7 @@ func (s *service) initPlatform() error {
}
epoller, err := console.NewEpoller()
if err != nil {
- return errors.Wrap(err, "failed to initialize epoller")
+ return fmt.Errorf("failed to initialize epoller: %w", err)
}
s.platform = &linuxPlatform{
epoller: epoller,
diff --git a/pkg/test/criutil/criutil.go b/pkg/test/criutil/criutil.go
index 8fed29ff5..4c63d669a 100644
--- a/pkg/test/criutil/criutil.go
+++ b/pkg/test/criutil/criutil.go
@@ -22,6 +22,9 @@ import (
"fmt"
"os"
"os/exec"
+ "path"
+ "regexp"
+ "strconv"
"strings"
"time"
@@ -33,28 +36,44 @@ import (
type Crictl struct {
logger testutil.Logger
endpoint string
+ runpArgs []string
cleanup []func()
}
// resolvePath attempts to find binary paths. It may set the path to invalid,
// which will cause the execution to fail with a sensible error.
func resolvePath(executable string) string {
+ runtime, err := dockerutil.RuntimePath()
+ if err == nil {
+ // Check first the directory of the runtime itself.
+ if dir := path.Dir(runtime); dir != "" && dir != "." {
+ guess := path.Join(dir, executable)
+ if fi, err := os.Stat(guess); err == nil && (fi.Mode()&0111) != 0 {
+ return guess
+ }
+ }
+ }
+
+ // Try to find via the path.
guess, err := exec.LookPath(executable)
- if err != nil {
- guess = fmt.Sprintf("/usr/local/bin/%s", executable)
+ if err == nil {
+ return guess
}
- return guess
+
+ // Return a default path.
+ return fmt.Sprintf("/usr/local/bin/%s", executable)
}
// 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) *Crictl {
+func NewCrictl(logger testutil.Logger, endpoint string, runpArgs []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,
}
}
@@ -67,8 +86,8 @@ func (cc *Crictl) CleanUp() {
}
// RunPod creates a sandbox. It corresponds to `crictl runp`.
-func (cc *Crictl) RunPod(sbSpecFile string) (string, error) {
- podID, err := cc.run("runp", sbSpecFile)
+func (cc *Crictl) RunPod(runtime, sbSpecFile string) (string, error) {
+ podID, err := cc.run("runp", "--runtime", runtime, sbSpecFile)
if err != nil {
return "", fmt.Errorf("runp failed: %v", err)
}
@@ -79,10 +98,39 @@ func (cc *Crictl) RunPod(sbSpecFile string) (string, error) {
// Create creates a container within a sandbox. It corresponds to `crictl
// create`.
func (cc *Crictl) Create(podID, contSpecFile, sbSpecFile string) (string, error) {
- podID, err := cc.run("create", podID, contSpecFile, sbSpecFile)
+ // In version 1.16.0, crictl annoying starting attempting to pull the
+ // container, even if it was already available locally. We therefore
+ // need to parse the version and add an appropriate --no-pull argument
+ // since the image has already been loaded locally.
+ out, err := cc.run("-v")
+ r := regexp.MustCompile("crictl version ([0-9]+)\\.([0-9]+)\\.([0-9+])")
+ vs := r.FindStringSubmatch(out)
+ if len(vs) != 4 {
+ return "", fmt.Errorf("crictl -v had unexpected output: %s", out)
+ }
+ major, err := strconv.ParseUint(vs[1], 10, 64)
+ if err != nil {
+ return "", fmt.Errorf("crictl had invalid version: %v (%s)", err, out)
+ }
+ minor, err := strconv.ParseUint(vs[2], 10, 64)
if err != nil {
+ return "", fmt.Errorf("crictl had invalid version: %v (%s)", err, out)
+ }
+
+ args := []string{"create"}
+ if (major == 1 && minor >= 16) || major > 1 {
+ args = append(args, "--no-pull")
+ }
+ args = append(args, podID)
+ args = append(args, contSpecFile)
+ args = append(args, sbSpecFile)
+
+ podID, err = cc.run(args...)
+ if err != nil {
+ time.Sleep(10 * time.Minute) // XXX
return "", fmt.Errorf("create failed: %v", err)
}
+
// Strip the trailing newline from crictl output.
return strings.TrimSpace(podID), nil
}
@@ -260,7 +308,7 @@ func (cc *Crictl) StopContainer(contID string) error {
// StartPodAndContainer starts a sandbox and container in that sandbox. It
// returns the pod ID and container ID.
-func (cc *Crictl) StartPodAndContainer(image, sbSpec, contSpec string) (string, string, error) {
+func (cc *Crictl) StartPodAndContainer(runtime, image, sbSpec, contSpec string) (string, string, error) {
if err := cc.Import(image); err != nil {
return "", "", err
}
@@ -277,7 +325,7 @@ func (cc *Crictl) StartPodAndContainer(image, sbSpec, contSpec string) (string,
}
cc.cleanup = append(cc.cleanup, cleanup)
- podID, err := cc.RunPod(sbSpecFile)
+ podID, err := cc.RunPod(runtime, sbSpecFile)
if err != nil {
return "", "", err
}
diff --git a/runsc/BUILD b/runsc/BUILD
index 757f6d44c..96f697a5f 100644
--- a/runsc/BUILD
+++ b/runsc/BUILD
@@ -62,18 +62,22 @@ go_binary(
)
pkg_tar(
- name = "runsc-bin",
- srcs = [":runsc"],
+ name = "debian-bin",
+ srcs = [
+ ":runsc",
+ "//shim/v1:gvisor-containerd-shim",
+ "//shim/v2:containerd-shim-runsc-v1",
+ ],
mode = "0755",
package_dir = "/usr/bin",
- strip_prefix = "/runsc/linux_amd64_pure_stripped",
)
pkg_tar(
name = "debian-data",
extension = "tar.gz",
deps = [
- ":runsc-bin",
+ ":debian-bin",
+ "//shim:config",
],
)
diff --git a/runsc/debian/postinst.sh b/runsc/debian/postinst.sh
index dc7aeee87..d1e28e17b 100755
--- a/runsc/debian/postinst.sh
+++ b/runsc/debian/postinst.sh
@@ -18,7 +18,14 @@ if [ "$1" != configure ]; then
exit 0
fi
+# Update docker configuration.
if [ -f /etc/docker/daemon.json ]; then
runsc install
- systemctl restart docker || echo "unable to restart docker; you must do so manually." >&2
+ if systemctl status docker 2>/dev/null; then
+ systemctl restart docker || echo "unable to restart docker; you must do so manually." >&2
+ fi
fi
+
+# For containerd-based installers, we don't automatically update the
+# configuration. If it uses a v2 shim, then it will find the package binaries
+# automatically when provided the appropriate annotation.
diff --git a/shim/BUILD b/shim/BUILD
new file mode 100644
index 000000000..e581618b2
--- /dev/null
+++ b/shim/BUILD
@@ -0,0 +1,15 @@
+load("//tools:defs.bzl", "pkg_tar")
+
+package(licenses = ["notice"])
+
+pkg_tar(
+ name = "config",
+ srcs = [
+ "runsc.toml",
+ ],
+ mode = "0644",
+ package_dir = "/etc/containerd",
+ visibility = [
+ "//runsc:__pkg__",
+ ],
+)
diff --git a/shim/README.md b/shim/README.md
index e446ec970..c6824ebdc 100644
--- a/shim/README.md
+++ b/shim/README.md
@@ -1,16 +1,11 @@
-# gvisor-containerd-shim
+# gVisor Containerd shims
-gvisor-containerd-shim is a containerd shim. It implements the containerd v1
-shim API. It can be used as a drop-in replacement for
-[containerd-shim][containerd-shim]
-(though containerd-shim must still be installed). It allows the use of both
-gVisor (runsc) and normal containers in the same containerd installation by
-deferring to the runc shim if the desired runtime engine is not runsc.
+There are various shims supported for differt versions of
+[containerd][containerd].
-- [Untrusted Workload Quick Start (containerd >=1.1)](docs/untrusted-workload-quickstart.md)
-- [Runtime Handler/RuntimeClass Quick Start (containerd >=1.2)](docs/runtime-handler-quickstart.md)
-- [Runtime Handler/RuntimeClass Quick Start (shim v2) (containerd >=1.2)](docs/runtime-handler-shim-v2-quickstart.md)
-- [Configure containerd-shim-runsc-v1 (shim v2) (containerd >= 1.3)](docs/configure-containerd-shim-runsc-v1.md)
-- [Configure gvisor-containerd-shim (shim v1) (containerd &lt;= 1.2)](docs/configure-gvisor-containerd-shim.md)
+- [Configure gvisor-containerd-shim (shim v1) (containerd &le; 1.2)](v1/configure-gvisor-containerd-shim.md)
+- [Runtime Handler/RuntimeClass Quick Start (containerd >= 1.2)](v2/runtime-handler-quickstart.md)
+- [Runtime Handler/RuntimeClass Quick Start (shim v2) (containerd >= 1.2)](v2/runtime-handler-shim-v2-quickstart.md)
+- [Configure containerd-shim-runsc-v1 (shim v2) (containerd >= 1.3)](v2/configure-containerd-shim-runsc-v1.md)
-[containerd-shim]: https://github.com/containerd/containerd/tree/master/cmd/containerd-shim
+[containerd]: https://github.com/containerd/containerd
diff --git a/shim/configure-containerd-shim-runsc-v1.md b/shim/configure-containerd-shim-runsc-v1.md
deleted file mode 100644
index 977ceacbd..000000000
--- a/shim/configure-containerd-shim-runsc-v1.md
+++ /dev/null
@@ -1,72 +0,0 @@
-# Configure containerd-shim-runsc-v1 (Shim V2)
-
-This document describes how to configure runtime options for
-`containerd-shim-runsc-v1`. This is follows on to the instructions of
-[Runtime Handler Quick Start (shim v2) (containerd >=1.2)](runtime-handler-shim-v2-quickstart.md)
-and requires containerd 1.3 or later.
-
-### Update `/etc/containerd/config.toml` to point to a configuration file for `containerd-shim-runsc-v1`.
-
-`containerd-shim-runsc-v1` supports a few different configuration options based
-on the version of containerd that is used. For versions >= 1.3, it supports a
-configurable config path in the containerd runtime configuration.
-
-```shell
-{ # Step 1: Update runtime options for runsc in containerd config.toml
-cat <<EOF | sudo tee /etc/containerd/config.toml
-disabled_plugins = ["restart"]
-[plugins.linux]
- shim_debug = true
-[plugins.cri.containerd.runtimes.runsc]
- runtime_type = "io.containerd.runsc.v1"
-[plugins.cri.containerd.runtimes.runsc.options]
- TypeUrl = "io.containerd.runsc.v1.options"
- ConfigPath = "/etc/containerd/runsc.toml"
-EOF
-}
-```
-
-### Configure `/etc/containerd/runsc.toml`
-
-The set of options that can be configured can be found in
-[options.go](../pkg/v2/options/options.go).
-
-#### Example: Enable the KVM platform
-
-gVisor enables the use of a number of platforms. This example shows how to
-configure `containerd-shim-runsc-v1` to use gvisor with the KVM platform.
-
-Find out more about platform in the
-(gVisor documentation)[https://gvisor.dev/docs/user_guide/platforms/].
-
-```shell
-cat <<EOF | sudo tee /etc/containerd/runsc.toml
-[runsc_config]
-platform = "kvm"
-EOF
-```
-
-### Example: Enable gVisor debug logging
-
-gVisor debug logging can be enabled by setting the `debug` and `debug-log`
-flag. The shim will replace "%ID%" with the container ID in the path of the
-`debug-log` flag.
-
-Find out more about debugging in the
-(gVisor documentation)[https://gvisor.dev/docs/user_guide/debugging/].
-
-```shell
-cat <<EOF | sudo tee /etc/containerd/runsc.toml
-[runsc_config]
- debug=true
- debug-log=/var/log/%ID%/gvisor.log
-EOF
-```
-
-## Restart `containerd`
-
-When you are done restart containerd to pick up the new configuration files.
-
-```shell
-sudo systemctl restart containerd
-```
diff --git a/shim/configure-gvisor-containerd-shim.md b/shim/configure-gvisor-containerd-shim.md
deleted file mode 100644
index 40151da56..000000000
--- a/shim/configure-gvisor-containerd-shim.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# Configure gvisor-containerd-shim (Shim V1)
-
-This document describes how to configure runtime options for `gvisor-containerd-shim`.
-
-The shim configuration is stored in `/etc/containerd/gvisor-containerd-shim.toml`. The configuration file supports two values.
-
-`runc_shim`: The path to the runc shim. This is used by the gvisor-containerd-shim to run normal containers.
-`runsc_config`: This is a set of key/value pairs that are converted into `runsc` command line flags. You can learn more about which flags are available by running `runsc flags`.
-
-## Example: Enable the KVM platform
-
-gVisor enables the use of a number of platforms. This configuration enables the
-KVM platform.
-
-Find out more about platform in the
-(gVisor documentation)[https://gvisor.dev/docs/user_guide/platforms/].
-
-```shell
-cat <<EOF | sudo tee /etc/containerd/gvisor-containerd-shim.toml
-[runsc_config]
-platform = "kvm"
-EOF
-```
-
-## Example: Enable gVisor debug logging
-
-gVisor debug logging can be enabled by setting the `debug` and `debug-log`
-flag. The shim will replace "%ID%" with the container ID in the path of the
-`debug-log` flag.
-
-Find out more about debugging in the
-(gVisor documentation)[https://gvisor.dev/docs/user_guide/debugging/].
-
-```shell
-cat <<EOF | sudo tee /etc/containerd/gvisor-containerd-shim.toml
-# This is the path to the default runc containerd-shim.
-runc_shim = "/usr/local/bin/containerd-shim"
-[runsc_config]
- debug=true
- debug-log=/var/log/%ID%/gvisor.log
-EOF
-```
diff --git a/shim/runsc.toml b/shim/runsc.toml
new file mode 100644
index 000000000..e1c7de1bb
--- /dev/null
+++ b/shim/runsc.toml
@@ -0,0 +1,6 @@
+# This is an example configuration file for runsc.
+#
+# By default, it will be parsed from /etc/containerd/runsc.toml, but see the
+# static path configured in v1/main.go. Note that the configuration mechanism
+# for newer container shim versions is different: see the documentation in v2.
+[runsc_config]
diff --git a/shim/runtime-handler-quickstart.md b/shim/runtime-handler-quickstart.md
deleted file mode 100644
index 684390b55..000000000
--- a/shim/runtime-handler-quickstart.md
+++ /dev/null
@@ -1,251 +0,0 @@
-# Runtime Handler Quickstart
-
-This document describes how to install and run the `gvisor-containerd-shim`
-using the containerd runtime handler support. This requires containerd 1.2 or
-later.
-
-## Requirements
-
-- **runsc**: See the [gVisor documentation](https://github.com/google/gvisor) for information on how to install runsc.
-- **containerd**: See the [containerd website](https://containerd.io/) for information on how to install containerd.
-
-## Install
-
-### Install gvisor-containerd-shim
-
-1. Download the latest release of the `gvisor-containerd-shim`. See the
- [releases page](https://github.com/google/gvisor-containerd-shim/releases)
-
-[embedmd]:# (../test/e2e/shim-install.sh shell /{ # Step 1\(release\)/ /^}/)
-```shell
-{ # Step 1(release): Install gvisor-containerd-shim
-LATEST_RELEASE=$(wget -qO - https://api.github.com/repos/google/gvisor-containerd-shim/releases | grep -oP '(?<="browser_download_url": ")https://[^"]*gvisor-containerd-shim.linux-amd64' | head -1)
-wget -O gvisor-containerd-shim ${LATEST_RELEASE}
-chmod +x gvisor-containerd-shim
-sudo mv gvisor-containerd-shim /usr/local/bin/gvisor-containerd-shim
-}
-```
-
-2. Create the configuration for the gvisor shim in
- `/etc/containerd/gvisor-containerd-shim.toml`:
-
-[embedmd]:# (../test/e2e/shim-install.sh shell /{ # Step 2/ /^}/)
-```shell
-{ # Step 2: Create the gvisor-containerd-shim.toml
-cat <<EOF | sudo tee /etc/containerd/gvisor-containerd-shim.toml
-# This is the path to the default runc containerd-shim.
-runc_shim = "/usr/local/bin/containerd-shim"
-EOF
-}
-```
-
-### Configure containerd
-
-1. Update `/etc/containerd/config.toml`. Be sure to update the path to
- `gvisor-containerd-shim` and `runsc` if necessary:
-
-[embedmd]:# (../test/e2e/runtime-handler/install.sh shell /{ # Step 1/ /^}/)
-```shell
-{ # Step 1: Create containerd config.toml
-cat <<EOF | sudo tee /etc/containerd/config.toml
-disabled_plugins = ["restart"]
-[plugins.linux]
- shim = "/usr/local/bin/gvisor-containerd-shim"
- shim_debug = true
-[plugins.cri.containerd.runtimes.runsc]
- runtime_type = "io.containerd.runtime.v1.linux"
- runtime_engine = "/usr/local/bin/runsc"
- runtime_root = "/run/containerd/runsc"
-EOF
-}
-```
-
-2. Restart `containerd`
-
-```shell
-sudo systemctl restart containerd
-```
-
-## Usage
-
-You can run containers in gVisor via containerd's CRI.
-
-### Install crictl
-
-1. Download and install the crictl binary:
-
-[embedmd]:# (../test/e2e/crictl-install.sh shell /{ # Step 1/ /^}/)
-```shell
-{ # Step 1: Download crictl
-wget https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.13.0/crictl-v1.13.0-linux-amd64.tar.gz
-tar xf crictl-v1.13.0-linux-amd64.tar.gz
-sudo mv crictl /usr/local/bin
-}
-```
-
-2. Write the crictl configuration file
-
-[embedmd]:# (../test/e2e/crictl-install.sh shell /{ # Step 2/ /^}/)
-```shell
-{ # Step 2: Configure crictl
-cat <<EOF | sudo tee /etc/crictl.yaml
-runtime-endpoint: unix:///run/containerd/containerd.sock
-EOF
-}
-```
-
-### Create the nginx Sandbox in gVisor
-
-1. Pull the nginx image
-
-[embedmd]:# (../test/e2e/runtime-handler/usage.sh shell /{ # Step 1/ /^}/)
-```shell
-{ # Step 1: Pull the nginx image
-sudo crictl pull nginx
-}
-```
-
-2. Create the sandbox creation request
-
-[embedmd]:# (../test/e2e/runtime-handler/usage.sh shell /{ # Step 2/ /^EOF\n}/)
-```shell
-{ # Step 2: Create sandbox.json
-cat <<EOF | tee sandbox.json
-{
- "metadata": {
- "name": "nginx-sandbox",
- "namespace": "default",
- "attempt": 1,
- "uid": "hdishd83djaidwnduwk28bcsb"
- },
- "linux": {
- },
- "log_directory": "/tmp"
-}
-EOF
-}
-```
-
-3. Create the pod in gVisor
-
-[embedmd]:# (../test/e2e/runtime-handler/usage.sh shell /{ # Step 3/ /^}/)
-```shell
-{ # Step 3: Create the sandbox
-SANDBOX_ID=$(sudo crictl runp --runtime runsc sandbox.json)
-}
-```
-
-### Run the nginx Container in the Sandbox
-
-1. Create the nginx container creation request
-
-[embedmd]:# (../test/e2e/run-container.sh shell /{ # Step 1/ /^EOF\n}/)
-```shell
-{ # Step 1: Create nginx container config
-cat <<EOF | tee container.json
-{
- "metadata": {
- "name": "nginx"
- },
- "image":{
- "image": "nginx"
- },
- "log_path":"nginx.0.log",
- "linux": {
- }
-}
-EOF
-}
-```
-
-2. Create the nginx container
-
-[embedmd]:# (../test/e2e/run-container.sh shell /{ # Step 2/ /^}/)
-```shell
-{ # Step 2: Create nginx container
-CONTAINER_ID=$(sudo crictl create ${SANDBOX_ID} container.json sandbox.json)
-}
-```
-
-3. Start the nginx container
-
-[embedmd]:# (../test/e2e/run-container.sh shell /{ # Step 3/ /^}/)
-```shell
-{ # Step 3: Start nginx container
-sudo crictl start ${CONTAINER_ID}
-}
-```
-
-### Validate the container
-
-1. Inspect the created pod
-
-[embedmd]:# (../test/e2e/validate.sh shell /{ # Step 1/ /^}/)
-```shell
-{ # Step 1: Inspect the pod
-sudo crictl inspectp ${SANDBOX_ID}
-}
-```
-
-2. Inspect the nginx container
-
-[embedmd]:# (../test/e2e/validate.sh shell /{ # Step 2/ /^}/)
-```shell
-{ # Step 2: Inspect the container
-sudo crictl inspect ${CONTAINER_ID}
-}
-```
-
-3. Verify that nginx is running in gVisor
-
-[embedmd]:# (../test/e2e/validate.sh shell /{ # Step 3/ /^}/)
-```shell
-{ # Step 3: Check dmesg
-sudo crictl exec ${CONTAINER_ID} dmesg | grep -i gvisor
-}
-```
-
-### Set up the Kubernetes Runtime Class
-
-1. Install the Runtime Class for gVisor
-
-[embedmd]:# (../test/e2e/runtimeclass-install.sh shell /{ # Step 1/ /^}/)
-```shell
-{ # Step 1: Install a RuntimeClass
-cat <<EOF | kubectl apply -f -
-apiVersion: node.k8s.io/v1beta1
-kind: RuntimeClass
-metadata:
- name: gvisor
-handler: runsc
-EOF
-}
-```
-
-2. Create a Pod with the gVisor Runtime Class
-
-[embedmd]:# (../test/e2e/runtimeclass-install.sh shell /{ # Step 2/ /^}/)
-```shell
-{ # Step 2: Create a pod
-cat <<EOF | kubectl apply -f -
-apiVersion: v1
-kind: Pod
-metadata:
- name: nginx-gvisor
-spec:
- runtimeClassName: gvisor
- containers:
- - name: nginx
- image: nginx
-EOF
-}
-```
-
-3. Verify that the Pod is running
-
-[embedmd]:# (../test/e2e/runtimeclass-install.sh shell /{ # Step 3/ /^}/)
-```shell
-{ # Step 3: Get the pod
-kubectl get pod nginx-gvisor -o wide
-}
-```
diff --git a/shim/untrusted-workload-quickstart.md b/shim/untrusted-workload-quickstart.md
deleted file mode 100644
index fb4441845..000000000
--- a/shim/untrusted-workload-quickstart.md
+++ /dev/null
@@ -1,212 +0,0 @@
-# Untrusted Workload Quickstart
-
-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.
-
-*Note: The untrusted workload CRI extension is deprecated by containerd. If you
-are using containerd 1.2, please consider using runtime handler.*
-
-## Requirements
-
-- **runsc**: See the [gVisor documentation](https://github.com/google/gvisor) for information on how to install runsc.
-- **containerd**: See the [containerd website](https://containerd.io/) for information on how to install containerd.
-
-## Install
-
-### Install gvisor-containerd-shim
-
-1. Download the latest release of the `gvisor-containerd-shim`. See the
- [releases page](https://github.com/google/gvisor-containerd-shim/releases)
-
-[embedmd]:# (../test/e2e/shim-install.sh shell /{ # Step 1/ /^}/)
-```shell
-{ # Step 1(release): Install gvisor-containerd-shim
-LATEST_RELEASE=$(wget -qO - https://api.github.com/repos/google/gvisor-containerd-shim/releases | grep -oP '(?<="browser_download_url": ")https://[^"]*gvisor-containerd-shim.linux-amd64' | head -1)
-wget -O gvisor-containerd-shim ${LATEST_RELEASE}
-chmod +x gvisor-containerd-shim
-sudo mv gvisor-containerd-shim /usr/local/bin/gvisor-containerd-shim
-}
-```
-
-2. Create the configuration for the gvisor shim in
- `/etc/containerd/gvisor-containerd-shim.toml`:
-
-[embedmd]:# (../test/e2e/shim-install.sh shell /{ # Step 2/ /^}/)
-```shell
-{ # Step 2: Create the gvisor-containerd-shim.toml
-cat <<EOF | sudo tee /etc/containerd/gvisor-containerd-shim.toml
-# This is the path to the default runc containerd-shim.
-runc_shim = "/usr/local/bin/containerd-shim"
-EOF
-}
-```
-
-### Configure containerd
-
-1. Update `/etc/containerd/config.toml`. Be sure to update the path to
- `gvisor-containerd-shim` and `runsc` if necessary:
-
-[embedmd]:# (../test/e2e/untrusted-workload/install.sh shell /{ # Step 1/ /^}/)
-```shell
-{ # Step 1: Create containerd config.toml
-cat <<EOF | sudo tee /etc/containerd/config.toml
-disabled_plugins = ["restart"]
-[plugins.linux]
- shim = "/usr/local/bin/gvisor-containerd-shim"
- shim_debug = true
-[plugins.cri.containerd.untrusted_workload_runtime]
- runtime_type = "io.containerd.runtime.v1.linux"
- runtime_engine = "/usr/local/bin/runsc"
- runtime_root = "/run/containerd/runsc"
-EOF
-}
-```
-
-2. Restart `containerd`
-
-```shell
-sudo systemctl restart containerd
-```
-
-## Usage
-
-You can run containers in gVisor via containerd's CRI.
-
-### Install crictl
-
-1. Download and install the crictl binary:
-
-[embedmd]:# (../test/e2e/crictl-install.sh shell /{ # Step 1/ /^}/)
-```shell
-{ # Step 1: Download crictl
-wget https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.13.0/crictl-v1.13.0-linux-amd64.tar.gz
-tar xf crictl-v1.13.0-linux-amd64.tar.gz
-sudo mv crictl /usr/local/bin
-}
-```
-
-2. Write the crictl configuration file
-
-[embedmd]:# (../test/e2e/crictl-install.sh shell /{ # Step 2/ /^}/)
-```shell
-{ # Step 2: Configure crictl
-cat <<EOF | sudo tee /etc/crictl.yaml
-runtime-endpoint: unix:///run/containerd/containerd.sock
-EOF
-}
-```
-
-### Create the nginx Sandbox in gVisor
-
-1. Pull the nginx image
-
-[embedmd]:# (../test/e2e/untrusted-workload/usage.sh shell /{ # Step 1/ /^}/)
-```shell
-{ # Step 1: Pull the nginx image
-sudo crictl pull nginx
-}
-```
-
-2. Create the sandbox creation request
-
-[embedmd]:# (../test/e2e/untrusted-workload/usage.sh shell /{ # Step 2/ /^EOF\n}/)
-```shell
-{ # Step 2: Create sandbox.json
-cat <<EOF | tee sandbox.json
-{
- "metadata": {
- "name": "nginx-sandbox",
- "namespace": "default",
- "attempt": 1,
- "uid": "hdishd83djaidwnduwk28bcsb"
- },
- "annotations": {
- "io.kubernetes.cri.untrusted-workload": "true"
- },
- "linux": {
- },
- "log_directory": "/tmp"
-}
-EOF
-}
-```
-
-3. Create the pod in gVisor
-
-[embedmd]:# (../test/e2e/untrusted-workload/usage.sh shell /{ # Step 3/ /^}/)
-```shell
-{ # Step 3: Create the sandbox
-SANDBOX_ID=$(sudo crictl runp sandbox.json)
-}
-```
-
-### Run the nginx Container in the Sandbox
-
-1. Create the nginx container creation request
-
-[embedmd]:# (../test/e2e/run-container.sh shell /{ # Step 1/ /^EOF\n}/)
-```shell
-{ # Step 1: Create nginx container config
-cat <<EOF | tee container.json
-{
- "metadata": {
- "name": "nginx"
- },
- "image":{
- "image": "nginx"
- },
- "log_path":"nginx.0.log",
- "linux": {
- }
-}
-EOF
-}
-```
-
-2. Create the nginx container
-
-[embedmd]:# (../test/e2e/run-container.sh shell /{ # Step 2/ /^}/)
-```shell
-{ # Step 2: Create nginx container
-CONTAINER_ID=$(sudo crictl create ${SANDBOX_ID} container.json sandbox.json)
-}
-```
-
-3. Start the nginx container
-
-[embedmd]:# (../test/e2e/run-container.sh shell /{ # Step 3/ /^}/)
-```shell
-{ # Step 3: Start nginx container
-sudo crictl start ${CONTAINER_ID}
-}
-```
-
-### Validate the container
-
-1. Inspect the created pod
-
-[embedmd]:# (../test/e2e/validate.sh shell /{ # Step 1/ /^}/)
-```shell
-{ # Step 1: Inspect the pod
-sudo crictl inspectp ${SANDBOX_ID}
-}
-```
-
-2. Inspect the nginx container
-
-[embedmd]:# (../test/e2e/validate.sh shell /{ # Step 2/ /^}/)
-```shell
-{ # Step 2: Inspect the container
-sudo crictl inspect ${CONTAINER_ID}
-}
-```
-
-3. Verify that nginx is running in gVisor
-
-[embedmd]:# (../test/e2e/validate.sh shell /{ # Step 3/ /^}/)
-```shell
-{ # Step 3: Check dmesg
-sudo crictl exec ${CONTAINER_ID} dmesg | grep -i gvisor
-}
-```
diff --git a/shim/v1/BUILD b/shim/v1/BUILD
new file mode 100644
index 000000000..3a863ecbb
--- /dev/null
+++ b/shim/v1/BUILD
@@ -0,0 +1,43 @@
+load("//tools:defs.bzl", "go_binary")
+load("//website:defs.bzl", "doc")
+
+package(licenses = ["notice"])
+
+go_binary(
+ name = "gvisor-containerd-shim",
+ srcs = [
+ "config.go",
+ "main.go",
+ ],
+ pure = True,
+ visibility = [
+ "//visibility:public",
+ ],
+ deps = [
+ "//pkg/shim/runsc",
+ "//pkg/shim/v1/shim",
+ "//pkg/shim/v2",
+ "@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/linux/proc:go_default_library",
+ "@com_github_containerd_containerd//runtime/v1/shim:go_default_library",
+ "@com_github_containerd_containerd//runtime/v1/shim/v1:go_default_library",
+ "@com_github_containerd_containerd//runtime/v2/shim: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",
+ "@com_github_opencontainers_runc//libcontainer/system:go_default_library",
+ "@org_golang_x_sys//unix:go_default_library",
+ ],
+)
+
+doc(
+ name = "doc",
+ src = "README.md",
+ category = "User Guide",
+ permalink = "/docs/user_guide/gvisor-containerd-shim/",
+ subcategory = "Advanced",
+ visibility = ["//website:__pkg__"],
+ weight = "93",
+)
diff --git a/shim/v1/README.md b/shim/v1/README.md
new file mode 100644
index 000000000..fcdf3ad77
--- /dev/null
+++ b/shim/v1/README.md
@@ -0,0 +1,50 @@
+# gvisor-containerd-shim
+
+> Note: This shim version is supported only for containerd versions less than
+> 1.2. If you are using a containerd version greater than or equal to 1.2, then
+> please use `containerd-shim-runsc-v1` (Shim API v1).
+>
+> This containerd shim is supported only in a best-effort capacity.
+
+This document describes how to configure and use `gvisor-containerd-shim`.
+
+## Containerd Configuration
+
+To use this shim, you must configure `/etc/containerd/config.toml` as follows:
+
+```
+[plugins.linux]
+ shim = "/usr/bin/gvisor-containerd-shim"
+[plugins.cri.containerd.runtimes.gvisor]
+ runtime_type = "io.containerd.runtime.v1.linux"
+ runtime_engine = "/usr/bin/runsc"
+ runtime_root = "/run/containerd/runsc"
+```
+
+In order to pick-up the new configuration, you may need to restart containerd:
+
+```shell
+sudo systemctl restart containerd
+```
+
+## Shim Confguration
+
+The shim configuration is stored in `/etc/containerd/runsc.toml`. The
+configuration file supports two values.
+
+* `runc_shim`: The path to the runc shim. This is used by
+ `gvisor-containerd-shim` to run standard containers.
+
+* `runsc_config`: This is a set of key/value pairs that are converted into
+ `runsc` command line flags. You can learn more about which flags are available
+ by running `runsc flags`.
+
+For example, a configuration might look as follows:
+
+```
+runc_shim = "/usr/local/bin/containerd-shim"
+[runsc_config]
+platform = "kvm"
+debug = true
+debug-log = /var/log/%ID%/gvisor.log
+```
diff --git a/shim/v2/config.go b/shim/v1/config.go
index a72cc7754..a72cc7754 100644
--- a/shim/v2/config.go
+++ b/shim/v1/config.go
diff --git a/shim/v1/main.go b/shim/v1/main.go
index 41c77394a..43deee858 100644
--- a/shim/v1/main.go
+++ b/shim/v1/main.go
@@ -16,11 +16,252 @@
package main
import (
- "github.com/containerd/containerd/runtime/v2/shim"
+ "bytes"
+ "context"
+ "flag"
+ "fmt"
+ "log"
+ "net"
+ "os"
+ "os/exec"
+ "os/signal"
+ "path/filepath"
+ "strings"
+ "sync"
+ "syscall"
- runsc "gvisor.dev/gvisor/pkg/shim/v2"
+ "github.com/containerd/containerd/events"
+ "github.com/containerd/containerd/namespaces"
+ "github.com/containerd/containerd/runtime/v1/linux/proc"
+ containerdshim "github.com/containerd/containerd/runtime/v1/shim"
+ shimapi "github.com/containerd/containerd/runtime/v1/shim/v1"
+ "github.com/containerd/ttrpc"
+ "github.com/containerd/typeurl"
+ ptypes "github.com/gogo/protobuf/types"
+ "github.com/opencontainers/runc/libcontainer/system"
+ "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
)
+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")
+
+ // Containerd default to runc, unless another runtime is explicitly
+ // specified. We keep the same default to make the default behavior
+ // consistent.
+ flag.StringVar(&runtimeRootFlag, "runtime-root", proc.RuncRoot, "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")
+}
+
func main() {
- shim.Run("io.containerd.runsc.v1", runsc.New)
+ 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
+ }
+ shimapi.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"))
+ path = "[inherited from parent]"
+ } 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 = containerdshim.Default
+ // Set the shim as the subreaper for all orphaned processes created by
+ // the container.
+ if err := system.SetSubreaper(1); 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 := containerdshim.Reap(); err != nil {
+ log.Printf("reap exit status: %v")
+ }
+ 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")
+ }
+ // Ensure our child is dead if any.
+ sv.Kill(ctx, &shimapi.KillRequest{
+ Signal: uint32(syscall.SIGKILL),
+ All: true,
+ })
+ sv.Delete(context.Background(), &ptypes.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 := containerdshim.Default.Start(cmd)
+ if err != nil {
+ return err
+ }
+ status, err := containerdshim.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/v2/BUILD b/shim/v2/BUILD
new file mode 100644
index 000000000..1e1947dab
--- /dev/null
+++ b/shim/v2/BUILD
@@ -0,0 +1,32 @@
+load("//tools:defs.bzl", "go_binary", "pkg_tar")
+load("//website:defs.bzl", "doc")
+
+package(licenses = ["notice"])
+
+go_binary(
+ name = "containerd-shim-runsc-v1",
+ srcs = [
+ "main.go",
+ ],
+ pure = True,
+ visibility = [
+ "//visibility:public",
+ ],
+ deps = [
+ "//pkg/shim/runsc",
+ "//pkg/shim/v1/shim",
+ "//pkg/shim/v2",
+ "@com_github_burntsushi_toml//:go_default_library",
+ "@com_github_containerd_containerd//runtime/v2/shim:go_default_library",
+ ],
+)
+
+doc(
+ name = "doc",
+ src = "README.md",
+ category = "User Guide",
+ permalink = "/docs/user_guide/containerd-shim-runsc-v1/",
+ subcategory = "Advanced",
+ visibility = ["//website:__pkg__"],
+ weight = "92",
+)
diff --git a/shim/v2/README.md b/shim/v2/README.md
new file mode 100644
index 000000000..2fd625415
--- /dev/null
+++ b/shim/v2/README.md
@@ -0,0 +1,90 @@
+# containerd-shim-runsc-v1
+
+> Note: This shim version is the recommended shim for containerd versions
+> greater than or equal to 1.2. For older versions of containerd, use
+> `gvisor-containerd-shim`.
+
+This document describes how to configure and use `containerd-shim-runsc-v1`.
+
+## Configuring Containerd 1.2
+
+To configure containerd 1.2 to use this shim, add the runtime to
+`/etc/containerd/config.toml` as follows:
+
+```
+[plugins.cri.containerd.runtimes.runsc]
+ runtime_type = "io.containerd.runsc.v1"
+ runtime_root = "/run/containerd/runsc"
+[plugins.cri.containerd.runtimes.runsc.options]
+ TypeUrl = "io.containerd.runsc.v1.options"
+```
+
+The configuration will optionally loaded from a file named `config.toml` in the
+`runtime_root` configured above.
+
+In order to pick up the new configuration, you may need to restart containerd:
+
+```shell
+sudo systemctl restart containerd
+```
+
+## Configuring Containerd 1.3 and above
+
+To configure containerd 1.3 to use this shim, add the runtime to
+`/etc/containerd/config.toml` as follows:
+
+```
+[plugins.cri.containerd.runtimes.runsc]
+ runtime_type = "io.containerd.runsc.v1"
+[plugins.cri.containerd.runtimes.runsc.options]
+ TypeUrl = "io.containerd.runsc.v1.options"
+ ConfigPath = "/etc/containerd/runsc.toml"
+```
+
+The `ConfigPath` above will be used to provide a pointer to the configuration
+file to be loaded.
+
+> Note that there will be configuration file loaded if `ConfigPath` is not set.
+
+In order to pick up the new configuration, you may need to restart containerd:
+
+```shell
+sudo systemctl restart containerd
+```
+## Shim Confguration
+
+The shim configuration may carry the following options:
+
+* `shim_cgroup`: The cgroup to use for the shim itself.
+* `io_uid`: The UID to use for pipes.
+* `ui_gid`: The GID to use for pipes.
+* `binary_name`: The runtime binary name (defaults to `runsc`).
+* `root`: The root directory for the runtime.
+* `runsc_config`: A dictionary of key-value pairs that will be passed to the
+ runtime as arguments.
+
+### Example: Enable the KVM platform
+
+gVisor enables the use of a number of platforms. This example shows how to
+configure `containerd-shim-runsc-v1` to use gVisor with the KVM platform:
+
+```shell
+cat <<EOF | sudo tee /etc/containerd/runsc.toml
+[runsc_config]
+platform = "kvm"
+EOF
+```
+
+### Example: Enable gVisor debug logging
+
+gVisor debug logging can be enabled by setting the `debug` and `debug-log` flag.
+The shim will replace "%ID%" with the container ID in the path of the
+`debug-log` flag.
+
+```shell
+cat <<EOF | sudo tee /etc/containerd/runsc.toml
+[runsc_config]
+debug = true
+debug-log = /var/log/%ID%/gvisor.log
+EOF
+```
diff --git a/shim/v2/main.go b/shim/v2/main.go
index 118b6f6e5..41c77394a 100644
--- a/shim/v2/main.go
+++ b/shim/v2/main.go
@@ -16,303 +16,11 @@
package main
import (
- "bytes"
- "context"
- "flag"
- "fmt"
- "net"
- "os"
- "os/exec"
- "os/signal"
- "path/filepath"
- "runtime"
- "runtime/debug"
- "strings"
- "sync"
- "syscall"
- "time"
+ "github.com/containerd/containerd/runtime/v2/shim"
- "github.com/containerd/containerd/events"
- "github.com/containerd/containerd/namespaces"
- "github.com/containerd/containerd/runtime/v1/linux/proc"
- containerdshim "github.com/containerd/containerd/runtime/v1/shim"
- shimapi "github.com/containerd/containerd/runtime/v1/shim/v1"
- "github.com/containerd/ttrpc"
- "github.com/containerd/typeurl"
- ptypes "github.com/gogo/protobuf/types"
- "github.com/opencontainers/runc/libcontainer/system"
- "github.com/pkg/errors"
- "github.com/sirupsen/logrus"
- "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
+ runsc "gvisor.dev/gvisor/pkg/shim/v2"
)
-// ShimConfigPath is the default shim config file path.
-const ShimConfigPath = "/etc/containerd/gvisor-containerd-shim.toml"
-
-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")
- // Containerd default to runc, unless another runtime is explicitly specified.
- // We keep the same default to make the default behavior consistent.
- flag.StringVar(&runtimeRootFlag, "runtime-root", proc.RuncRoot, "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", ShimConfigPath, "path to the shim configuration file")
- flag.Parse()
-}
-
func main() {
- // 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)
- }
- }
-
- debug.SetGCPercent(40)
- go func() {
- for range time.Tick(30 * time.Second) {
- debug.FreeOSMemory()
- }
- }()
-
- if debugFlag {
- logrus.SetLevel(logrus.DebugLevel)
- }
-
- if os.Getenv("GOMAXPROCS") == "" {
- // If GOMAXPROCS hasn't been set, we default to a value of 2 to reduce
- // the number of Go stacks present in the shim.
- runtime.GOMAXPROCS(2)
- }
-
- // 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 errors.Wrap(err, "failed to load shim config")
- }
- shimPath := c.RuncShim
- if shimPath == "" {
- shimPath, err = exec.LookPath("containerd-shim")
- if err != nil {
- return errors.Wrapf(err, "lookup containerd-shim")
- }
- }
-
- args := append([]string{shimPath}, os.Args[1:]...)
- if err := syscall.Exec(shimPath, args, os.Environ()); err != nil {
- return errors.Wrapf(err, "exec containerd-shim %q", shimPath)
- }
- 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
- }
- dump := make(chan os.Signal, 32)
- signal.Notify(dump, syscall.SIGUSR1)
-
- path, err := os.Getwd()
- if err != nil {
- return err
- }
- server, err := ttrpc.NewServer(ttrpc.WithServerHandshaker(ttrpc.UnixSocketRequireSameUser()))
- if err != nil {
- return errors.Wrap(err, "failed creating server")
- }
- c, err := loadConfig(shimConfigFlag)
- if err != nil && !os.IsNotExist(err) {
- return errors.Wrap(err, "failed to load shim config")
- }
- 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
- }
- logrus.Debug("registering ttrpc server")
- shimapi.RegisterShimService(server, sv)
-
- socket := socketFlag
- if err := serve(server, socket); err != nil {
- return err
- }
- logger := logrus.WithFields(logrus.Fields{
- "pid": os.Getpid(),
- "path": path,
- "namespace": namespaceFlag,
- })
- go func() {
- for range dump {
- dumpStacks(logger)
- }
- }()
- return handleSignals(logger, 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"))
- path = "[inherited from parent]"
- } else {
- if len(path) > 106 {
- return errors.Errorf("%q: unix socket path too long (> 106)", path)
- }
- l, err = net.Listen("unix", "\x00"+path)
- }
- if err != nil {
- return err
- }
- logrus.WithField("socket", path).Debug("serving api on unix socket")
- go func() {
- defer l.Close()
- if err := server.Serve(context.Background(), l); err != nil &&
- !strings.Contains(err.Error(), "use of closed network connection") {
- logrus.WithError(err).Fatal("gvisor-containerd-shim: ttrpc server failure")
- }
- }()
- 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 = containerdshim.Default
- // set the shim as the subreaper for all orphaned processes created by the container
- if err := system.SetSubreaper(1); err != nil {
- return nil, err
- }
- return signals, nil
-}
-
-func handleSignals(logger *logrus.Entry, 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 := containerdshim.Reap(); err != nil {
- logger.WithError(err).Error("reap exit status")
- }
- case unix.SIGTERM, unix.SIGINT:
- go termOnce.Do(func() {
- ctx := context.TODO()
- if err := server.Shutdown(ctx); err != nil {
- logger.WithError(err).Error("failed to shutdown server")
- }
- // Ensure our child is dead if any
- sv.Kill(ctx, &shimapi.KillRequest{
- Signal: uint32(syscall.SIGKILL),
- All: true,
- })
- sv.Delete(context.Background(), &ptypes.Empty{})
- close(done)
- })
- case unix.SIGPIPE:
- }
- }
- }
-}
-
-func dumpStacks(logger *logrus.Entry) {
- var (
- buf []byte
- stackSize int
- )
- bufferLen := 16384
- for stackSize == len(buf) {
- buf = make([]byte, bufferLen)
- stackSize = runtime.Stack(buf, true)
- bufferLen *= 2
- }
- buf = buf[:stackSize]
- logger.Infof("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===", buf)
-}
-
-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 := containerdshim.Default.Start(cmd)
- if err != nil {
- return err
- }
- status, err := containerdshim.Default.Wait(cmd, c)
- if err != nil {
- return err
- }
- if status != 0 {
- return errors.New("failed to publish event")
- }
- return nil
+ shim.Run("io.containerd.runsc.v1", runsc.New)
}
diff --git a/shim/runtime-handler-shim-v2-quickstart.md b/shim/v2/runtime-handler-shim-v2-quickstart.md
index ca8336089..ca8336089 100644
--- a/shim/runtime-handler-shim-v2-quickstart.md
+++ b/shim/v2/runtime-handler-shim-v2-quickstart.md
diff --git a/test/root/BUILD b/test/root/BUILD
index a9e91ccd6..1d19d1f5f 100644
--- a/test/root/BUILD
+++ b/test/root/BUILD
@@ -51,8 +51,5 @@ vm_test(
name = "root_vm_test",
size = "large",
shard_count = 1,
- targets = [
- "//tools/installers:shim",
- ":root_test",
- ],
+ targets = [":root_test"],
)
diff --git a/test/root/crictl_test.go b/test/root/crictl_test.go
index 732fae821..193705ab8 100644
--- a/test/root/crictl_test.go
+++ b/test/root/crictl_test.go
@@ -20,13 +20,14 @@ import (
"fmt"
"io"
"io/ioutil"
- "log"
"net/http"
"os"
"os/exec"
"path"
- "path/filepath"
+ "regexp"
+ "strconv"
"strings"
+ "sync"
"testing"
"time"
@@ -75,6 +76,8 @@ func SimpleSpec(name, image string, cmd []string, extra map[string]interface{})
// Log files are not deleted after root tests are run. Log to random
// paths to ensure logs are fresh.
"log_path": fmt.Sprintf("%s.log", testutil.RandomID(name)),
+ "stdin": false,
+ "tty": false,
}
if len(cmd) > 0 { // Omit if empty.
s["command"] = cmd
@@ -95,25 +98,29 @@ var Httpd = SimpleSpec("httpd", "basic/httpd", nil, nil)
// TestCrictlSanity refers to b/112433158.
func TestCrictlSanity(t *testing.T) {
- // 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("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)
+ 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)
+ }
+ })
}
}
@@ -147,146 +154,179 @@ var HttpdMountPaths = SimpleSpec("httpd", "basic/httpd", nil, map[string]interfa
// TestMountPaths refers to b/117635704.
func TestMountPaths(t *testing.T) {
- // 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("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)
+ 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)
+ }
+ })
}
}
// TestMountPaths refers to b/118728671.
func TestMountOverSymlinks(t *testing.T) {
- // 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("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)
+ 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)
+ }
+ })
}
}
// TestHomeDir tests that the HOME environment variable is set for
// Pod containers.
func TestHomeDir(t *testing.T) {
- // Setup containerd and crictl.
- crictl, cleanup, err := setup(t)
- if err != nil {
- t.Fatalf("failed to setup crictl: %v", err)
+ 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)
+ }
+ })
+ })
}
- 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("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.
- if err := crictl.StopPodAndContainer(podID, contID); err != nil {
- t.Fatalf("stop failed: %v", err)
- }
- })
-
- // 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("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)
- }
- })
}
-// containerdConfigTemplate is a .toml config for containerd. It contains a
-// formatting verb so the runtime field can be set via fmt.Sprintf.
-const containerdConfigTemplate = `
+const containerdRuntime = "runsc"
+
+const v1Template = `
disabled_plugins = ["restart"]
+[plugins.cri]
+ disable_tcp_service = true
[plugins.linux]
- runtime = "%s"
- runtime_root = "/tmp/test-containerd/runsc"
- shim = "/usr/local/bin/gvisor-containerd-shim"
+ shim = "%s"
shim_debug = true
-
-[plugins.cri.containerd.runtimes.runsc]
+[plugins.cri.containerd.runtimes.` + containerdRuntime + `]
runtime_type = "io.containerd.runtime.v1.linux"
runtime_engine = "%s"
+ runtime_root = "%s/root/runsc"
`
+const v2Template = `
+disabled_plugins = ["restart"]
+[plugins.cri]
+ disable_tcp_service = true
+[plugins.linux]
+ shim_debug = true
+[plugins.cri.containerd.runtimes.` + containerdRuntime + `]
+ runtime_type = "io.containerd.` + containerdRuntime + `.v1"
+[plugins.cri.containerd.runtimes.` + containerdRuntime + `.options]
+ TypeUrl = "io.containerd.` + containerdRuntime + `.v1.options"
+`
+
+const (
+ // v1 is the containerd API v1.
+ v1 string = "v1"
+
+ // v1 is the containerd API v21.
+ 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) (*criutil.Crictl, func(), error) {
+func setup(t *testing.T, version string) (*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")
@@ -295,13 +335,43 @@ func setup(t *testing.T) (*criutil.Crictl, func(), error) {
}
cu := cleanup.Make(func() { os.RemoveAll(containerdRoot) })
defer cu.Clean()
+ t.Logf("Using containerd root: %s", containerdRoot)
containerdState, err := ioutil.TempDir(testutil.TmpDir(), "containerd-state")
if err != nil {
t.Fatalf("failed to create containerd state: %v", err)
}
cu.Add(func() { os.RemoveAll(containerdState) })
- sockAddr := filepath.Join(testutil.TmpDir(), "containerd-test.sock")
+ t.Logf("Using containerd state: %s", containerdState)
+
+ sockDir, err := ioutil.TempDir(testutil.TmpDir(), "containerd-sock")
+ if err != nil {
+ t.Fatalf("failed to create containerd socket directory: %v", err)
+ }
+ cu.Add(func() { os.RemoveAll(sockDir) })
+ sockAddr := path.Join(sockDir, "test.sock")
+ t.Logf("Using containerd socket: %s", sockAddr)
+
+ // Extract the containerd version.
+ versionCmd := exec.Command(getContainerd(), "-v")
+ out, err := versionCmd.CombinedOutput()
+ if err != nil {
+ t.Fatalf("error extracting containerd version: %v (%s)", err, string(out))
+ }
+ r := regexp.MustCompile(" v([0-9]+)\\.([0-9]+)\\.([0-9+])")
+ vs := r.FindStringSubmatch(string(out))
+ if len(vs) != 4 {
+ t.Fatalf("error unexpected version string: %s", string(out))
+ }
+ major, err := strconv.ParseUint(vs[1], 10, 64)
+ if err != nil {
+ t.Fatalf("error parsing containerd major version: %v (%s)", err, string(out))
+ }
+ minor, err := strconv.ParseUint(vs[2], 10, 64)
+ if err != nil {
+ t.Fatalf("error parsing containerd minor version: %v (%s)", err, string(out))
+ }
+ t.Logf("Using containerd version: %d.%d", major, minor)
// We rewrite a configuration. This is based on the current docker
// configuration for the runtime under test.
@@ -309,28 +379,100 @@ func setup(t *testing.T) (*criutil.Crictl, func(), error) {
if err != nil {
t.Fatalf("error discovering runtime path: %v", err)
}
- config, configCleanup, err := testutil.WriteTmpFile("containerd-config", fmt.Sprintf(containerdConfigTemplate, runtime, runtime))
+ t.Logf("Using runtime: %v", runtime)
+
+ // Construct a PATH that includes the runtime directory. This is
+ // because the shims will be installed there, and containerd may infer
+ // the binary name and search the PATH.
+ runtimeDir := path.Dir(runtime)
+ modifiedPath := os.Getenv("PATH")
+ if modifiedPath != "" {
+ modifiedPath = ":" + modifiedPath // We prepend below.
+ }
+ modifiedPath = path.Dir(getContainerd()) + modifiedPath
+ 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. Note that we can safely assume
+ // that the shim has been installed in the same directory as
+ // the runtime (for test installs and for normal installs).
+ // Since this is v1, the binary name will be fixed.
+ config = fmt.Sprintf(v1Template, path.Join(runtimeDir, "gvisor-containerd-shim"), runtime, runtimeDir)
+ 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: %d", version)
+ }
+ t.Logf("Using config: %s", config)
+
+ // Generate the configuration for the test.
+ configFile, configCleanup, err := testutil.WriteTmpFile("containerd-config", config)
if err != nil {
t.Fatalf("failed to write containerd config")
}
cu.Add(configCleanup)
// Start containerd.
- cmd := exec.Command(getContainerd(),
- "--config", config,
+ args := []string{
+ getContainerd(),
+ "--config", configFile,
"--log-level", "debug",
"--root", containerdRoot,
"--state", containerdState,
- "--address", sockAddr)
+ "--address", sockAddr,
+ }
+ t.Logf("Using args: %s", strings.Join(args, " "))
+ cmd := exec.Command(args[0], args[1:]...)
+ cmd.Env = append(os.Environ(), "PATH="+modifiedPath)
+
+ // Include output in logs.
+ stderrPipe, err := cmd.StderrPipe()
+ if err != nil {
+ t.Fatalf("failed to create stderr pipe: %v", err)
+ }
+ cu.Add(func() { stderrPipe.Close() })
+ stdoutPipe, err := cmd.StdoutPipe()
+ if err != nil {
+ t.Fatalf("failed to create stdout pipe: %v", err)
+ }
+ cu.Add(func() { stdoutPipe.Close() })
+ var (
+ wg sync.WaitGroup
+ stderr bytes.Buffer
+ stdout bytes.Buffer
+ )
startupR, startupW := io.Pipe()
- defer startupR.Close()
- defer startupW.Close()
- stderr := &bytes.Buffer{}
- stdout := &bytes.Buffer{}
- cmd.Stderr = io.MultiWriter(startupW, stderr)
- cmd.Stdout = io.MultiWriter(startupW, stdout)
+ wg.Add(2)
+ go func() {
+ defer wg.Done()
+ io.Copy(io.MultiWriter(startupW, &stderr), stderrPipe)
+ }()
+ go func() {
+ defer wg.Done()
+ io.Copy(io.MultiWriter(startupW, &stdout), stdoutPipe)
+ }()
cu.Add(func() {
- // Log output in case of failure.
+ wg.Wait()
t.Logf("containerd stdout: %s", stdout.String())
t.Logf("containerd stderr: %s", stderr.String())
})
@@ -345,13 +487,17 @@ func setup(t *testing.T) (*criutil.Crictl, func(), error) {
t.Fatalf("failed to start containerd: %v", err)
}
+ // Discard all subsequent data.
+ go io.Copy(ioutil.Discard, startupR)
+
+ // Create the crictl interface.
+ cc := criutil.NewCrictl(t, sockAddr, runpArgs)
+ cu.Add(cc.CleanUp)
+
// Kill must be the last cleanup (as it will be executed first).
- cc := criutil.NewCrictl(t, sockAddr)
cu.Add(func() {
- cc.CleanUp() // Remove tmp files, etc.
- if err := testutil.KillCommand(cmd); err != nil {
- log.Printf("error killing containerd: %v", err)
- }
+ // Best effort: ignore errors.
+ testutil.KillCommand(cmd)
})
return cc, cu.Release(), nil
diff --git a/test/shim/containerd-install.sh b/test/shim/containerd-install.sh
deleted file mode 100755
index 400819245..000000000
--- a/test/shim/containerd-install.sh
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/bin/bash
-
-# A script to install containerd and CNI plugins for e2e testing
-
-wget -q --https-only \
- https://github.com/containerd/containerd/releases/download/v${CONTAINERD_VERSION}/containerd-${CONTAINERD_VERSION}.linux-amd64.tar.gz \
- https://github.com/containernetworking/plugins/releases/download/v0.7.0/cni-plugins-amd64-v0.7.0.tgz
-
-sudo mkdir -p /etc/containerd /etc/cni/net.d /opt/cni/bin
-sudo tar -xvf cni-plugins-amd64-v0.7.0.tgz -C /opt/cni/bin/
-sudo tar -xvf containerd-${CONTAINERD_VERSION}.linux-amd64.tar.gz -C /
-
-cat <<EOF | sudo tee /etc/containerd/config.toml
-disabled_plugins = ["restart"]
-# Set to avoid port overlap on older versions of containerd where default is 10010.
-[plugins.cri]
- stream_server_port = "10011"
-EOF
-
-cat <<EOF | sudo tee /etc/cni/net.d/10-bridge.conf
-{
- "cniVersion": "0.3.1",
- "name": "bridge",
- "type": "bridge",
- "bridge": "cnio0",
- "isGateway": true,
- "ipMasq": true,
- "ipam": {
- "type": "host-local",
- "ranges": [
- [{"subnet": "10.200.0.0/24"}]
- ],
- "routes": [{"dst": "0.0.0.0/0"}]
- }
-}
-EOF
-cat <<EOF | sudo tee /etc/cni/net.d/99-loopback.conf
-{
- "cniVersion": "0.3.1",
- "type": "loopback"
-}
-EOF
-
-sudo PATH=$PATH containerd -log-level debug &>/tmp/containerd-cri.log &
diff --git a/test/shim/crictl-install.sh b/test/shim/crictl-install.sh
deleted file mode 100755
index 1d63c889b..000000000
--- a/test/shim/crictl-install.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-
-# A sample script for installing crictl.
-
-set -ex
-
-{ # Step 1: Download crictl
-wget https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.13.0/crictl-v1.13.0-linux-amd64.tar.gz
-tar xf crictl-v1.13.0-linux-amd64.tar.gz
-sudo mv crictl /usr/local/bin
-}
-
-{ # Step 2: Configure crictl
-cat <<EOF | sudo tee /etc/crictl.yaml
-runtime-endpoint: unix:///run/containerd/containerd.sock
-EOF
-}
diff --git a/test/shim/run-container.sh b/test/shim/run-container.sh
deleted file mode 100755
index 4595433c3..000000000
--- a/test/shim/run-container.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/bash
-
-# A sample script to run a container in an existing pod
-
-set -ex
-
-{ # Step 1: Create nginx container config
-cat <<EOF | tee container.json
-{
- "metadata": {
- "name": "nginx"
- },
- "image":{
- "image": "nginx"
- },
- "log_path":"nginx.0.log",
- "linux": {
- }
-}
-EOF
-}
-
-{ # Step 2: Create nginx container
-CONTAINER_ID=$(sudo crictl create ${SANDBOX_ID} container.json sandbox.json)
-}
-
-{ # Step 3: Start nginx container
-sudo crictl start ${CONTAINER_ID}
-}
-
diff --git a/test/shim/runsc-install.sh b/test/shim/runsc-install.sh
deleted file mode 100755
index 420fe01e9..000000000
--- a/test/shim/runsc-install.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-
-# Sample script to install runsc
-
-wget -q --https-only \
- https://storage.googleapis.com/gvisor/releases/${RUNSC_VERSION}/runsc
-chmod +x runsc
-sudo mv runsc /usr/local/bin/
diff --git a/test/shim/runtime-handler-shim-v2/install.sh b/test/shim/runtime-handler-shim-v2/install.sh
deleted file mode 100755
index af6b5be1e..000000000
--- a/test/shim/runtime-handler-shim-v2/install.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/bash
-
-# A sample script for installing and configuring the gvisor-containerd-shim to
-# use the containerd runtime handler.
-
-set -ex
-
-{ # Step 1: Create containerd config.toml
-cat <<EOF | sudo tee /etc/containerd/config.toml
-disabled_plugins = ["restart"]
-[plugins.linux]
- shim_debug = true
-[plugins.cri.containerd.runtimes.runsc]
- runtime_type = "io.containerd.runsc.v1"
-EOF
-}
-
-{ # Step 2: Restart containerd
-sudo pkill containerd
-sudo containerd -log-level debug &> /tmp/containerd-cri.log &
-}
diff --git a/test/shim/runtime-handler-shim-v2/test.sh b/test/shim/runtime-handler-shim-v2/test.sh
deleted file mode 100755
index e33655ec1..000000000
--- a/test/shim/runtime-handler-shim-v2/test.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/bash
-
-# Runs end-to-end tests for gvisor-containerd-shim to test the use of runtime
-# handler. This should work on containerd 1.2+
-
-# This is meant to be run in a VM as it makes a fairly invasive install of
-# containerd.
-
-set -ex
-
-# Install containerd
-. ./test/e2e/containerd-install.sh
-
-# Install gVisor
-. ./test/e2e/runsc-install.sh
-
-# Install gvisor-containerd-shim
-. ./test/e2e/shim-install.sh
-
-# Test installation/configuration
-. ./test/e2e/runtime-handler-shim-v2/install.sh
-
-# Install crictl
-. ./test/e2e/crictl-install.sh
-
-# Test usage (the same with runtime-handler)
-. ./test/e2e/runtime-handler/usage.sh
-
-# Run a container in the sandbox
-. ./test/e2e/run-container.sh
-
-# Validate the pod and container
-. ./test/e2e/validate.sh
-. ./test/e2e/runtime-handler-shim-v2/validate.sh
diff --git a/test/shim/runtime-handler-shim-v2/validate.sh b/test/shim/runtime-handler-shim-v2/validate.sh
deleted file mode 100755
index b74a059ef..000000000
--- a/test/shim/runtime-handler-shim-v2/validate.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-
-# A sample script to validating the running containerd-shim-runsc-v1.
-
-set -ex
-
-ps aux | grep [c]ontainerd-shim-runsc-v1
diff --git a/test/shim/runtime-handler/install.sh b/test/shim/runtime-handler/install.sh
deleted file mode 100755
index ebe9d3580..000000000
--- a/test/shim/runtime-handler/install.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/bash
-
-# A sample script for installing and configuring the gvisor-containerd-shim to
-# use the containerd runtime handler.
-
-set -ex
-
-{ # Step 1: Create containerd config.toml
-cat <<EOF | sudo tee /etc/containerd/config.toml
-disabled_plugins = ["restart"]
-[plugins.linux]
- shim = "/usr/local/bin/gvisor-containerd-shim"
- shim_debug = true
-[plugins.cri.containerd.runtimes.runsc]
- runtime_type = "io.containerd.runtime.v1.linux"
- runtime_engine = "/usr/local/bin/runsc"
- runtime_root = "/run/containerd/runsc"
-EOF
-}
-
-{ # Step 2: Restart containerd
-sudo pkill containerd
-sudo containerd -log-level debug &> /tmp/containerd-cri.log &
-}
diff --git a/test/shim/runtime-handler/test.sh b/test/shim/runtime-handler/test.sh
deleted file mode 100755
index 99f3565b6..000000000
--- a/test/shim/runtime-handler/test.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/bash
-
-# Runs end-to-end tests for gvisor-containerd-shim to test the use of runtime
-# handler. This should work on containerd 1.2+
-
-# This is meant to be run in a VM as it makes a fairly invasive install of
-# containerd.
-
-set -ex
-
-# Install containerd
-. ./test/e2e/containerd-install.sh
-
-# Install gVisor
-. ./test/e2e/runsc-install.sh
-
-# Install gvisor-containerd-shim
-. ./test/e2e/shim-install.sh
-
-# Test installation/configuration
-. ./test/e2e/runtime-handler/install.sh
-
-# Install crictl
-. ./test/e2e/crictl-install.sh
-
-# Test usage
-. ./test/e2e/runtime-handler/usage.sh
-
-# Run a container in the sandbox
-. ./test/e2e/run-container.sh
-
-# Validate the pod and container
-. ./test/e2e/validate.sh
diff --git a/test/shim/runtime-handler/usage.sh b/test/shim/runtime-handler/usage.sh
deleted file mode 100755
index 350c720c2..000000000
--- a/test/shim/runtime-handler/usage.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/bash
-
-# A sample script for testing the gvisor-containerd-shim
-# using runtime handler.
-
-set -ex
-
-{ # Step 1: Pull the nginx image
-sudo crictl pull nginx
-}
-
-{ # Step 2: Create sandbox.json
-cat <<EOF | tee sandbox.json
-{
- "metadata": {
- "name": "nginx-sandbox",
- "namespace": "default",
- "attempt": 1,
- "uid": "hdishd83djaidwnduwk28bcsb"
- },
- "linux": {
- },
- "log_directory": "/tmp"
-}
-EOF
-}
-
-{ # Step 3: Create the sandbox
-SANDBOX_ID=$(sudo crictl runp --runtime runsc sandbox.json)
-}
diff --git a/test/shim/runtimeclass-install.sh b/test/shim/runtimeclass-install.sh
deleted file mode 100755
index 28abbcd00..000000000
--- a/test/shim/runtimeclass-install.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/bash
-
-# A sample script to test installing a RuntimeClass
-
-set -ex
-
-{ # Step 1: Install a RuntimeClass
-cat <<EOF | kubectl apply -f -
-apiVersion: node.k8s.io/v1beta1
-kind: RuntimeClass
-metadata:
- name: gvisor
-handler: runsc
-EOF
-}
-
-{ # Step 2: Create a pod
-cat <<EOF | kubectl apply -f -
-apiVersion: v1
-kind: Pod
-metadata:
- name: nginx-gvisor
-spec:
- runtimeClassName: gvisor
- containers:
- - name: nginx
- image: nginx
-EOF
-}
-
-{ # Step 3: Get the pod
-kubectl get pod nginx-gvisor -o wide
-}
diff --git a/test/shim/shim-install.sh b/test/shim/shim-install.sh
deleted file mode 100755
index f98455d46..000000000
--- a/test/shim/shim-install.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/bash
-
-# A sample script to install gvisor-containerd-shim
-
-set -ex
-
-# Build gvisor-containerd-shim
-if [ "${INSTALL_LATEST}" == "1" ]; then
-{ # Step 1(release): Install gvisor-containerd-shim
-LATEST_RELEASE=$(wget -qO - https://api.github.com/repos/google/gvisor-containerd-shim/releases | grep -oP '(?<="browser_download_url": ")https://[^"]*gvisor-containerd-shim.linux-amd64' | head -1)
-wget -O gvisor-containerd-shim ${LATEST_RELEASE}
-chmod +x gvisor-containerd-shim
-sudo mv gvisor-containerd-shim /usr/local/bin/gvisor-containerd-shim
-}
-else
-{ # Step 1(dev): Build and install gvisor-containerd-shim and containerd-shim-runsc-v1
- make
- sudo make install
-}
-fi
-
-{ # Step 2: Create the gvisor-containerd-shim.toml
-cat <<EOF | sudo tee /etc/containerd/gvisor-containerd-shim.toml
-# This is the path to the default runc containerd-shim.
-runc_shim = "/usr/local/bin/containerd-shim"
-EOF
-}
-
diff --git a/test/shim/untrusted-workload/install.sh b/test/shim/untrusted-workload/install.sh
deleted file mode 100755
index c4538aed1..000000000
--- a/test/shim/untrusted-workload/install.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/bash
-
-# A sample script for installing and configuring the gvisor-containerd-shim to
-# use the untrusted workload extension.
-
-set -ex
-
-{ # Step 1: Create containerd config.toml
-cat <<EOF | sudo tee /etc/containerd/config.toml
-disabled_plugins = ["restart"]
-[plugins.linux]
- shim = "/usr/local/bin/gvisor-containerd-shim"
- shim_debug = true
-# Set to avoid port overlap on older versions of containerd where default is 10010.
-[plugins.cri]
- stream_server_port = "10011"
-[plugins.cri.containerd.untrusted_workload_runtime]
- runtime_type = "io.containerd.runtime.v1.linux"
- runtime_engine = "/usr/local/bin/runsc"
- runtime_root = "/run/containerd/runsc"
-EOF
-}
-
-{ # Step 2: Restart containerd
-sudo pkill containerd
-sudo containerd -log-level debug &>/tmp/containerd-cri.log &
-}
diff --git a/test/shim/untrusted-workload/test.sh b/test/shim/untrusted-workload/test.sh
deleted file mode 100755
index 6e312cf6d..000000000
--- a/test/shim/untrusted-workload/test.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/bash
-
-# Runs end-to-end tests for gvisor-containerd-shim to test using the
-# untrusted workload extension. This should work on containerd 1.1+
-
-# This is meant to be run in a VM as it makes a fairly invasive install of
-# containerd.
-
-set -ex
-
-# Install containerd
-. ./test/e2e/containerd-install.sh
-
-# Install gVisor
-. ./test/e2e/runsc-install.sh
-
-# Install gvisor-containerd-shim
-. ./test/e2e/shim-install.sh
-
-# Test installation/configuration
-. ./test/e2e/untrusted-workload/install.sh
-
-# Install crictl
-. ./test/e2e/crictl-install.sh
-
-# Test usage
-. ./test/e2e/untrusted-workload/usage.sh
-
-# Run a container in the sandbox
-. ./test/e2e/run-container.sh
-
-# Validate the pod and container
-. ./test/e2e/validate.sh
diff --git a/test/shim/untrusted-workload/usage.sh b/test/shim/untrusted-workload/usage.sh
deleted file mode 100755
index db8206964..000000000
--- a/test/shim/untrusted-workload/usage.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/bash
-
-# A sample script for testing the gvisor-containerd-shim # using untrusted
-# workload extension.
-
-set -ex
-
-{ # Step 1: Pull the nginx image
-sudo crictl pull nginx
-}
-
-{ # Step 2: Create sandbox.json
-cat <<EOF | tee sandbox.json
-{
- "metadata": {
- "name": "nginx-sandbox",
- "namespace": "default",
- "attempt": 1,
- "uid": "hdishd83djaidwnduwk28bcsb"
- },
- "annotations": {
- "io.kubernetes.cri.untrusted-workload": "true"
- },
- "linux": {
- },
- "log_directory": "/tmp"
-}
-EOF
-}
-
-{ # Step 3: Create the sandbox
-SANDBOX_ID=$(sudo crictl runp sandbox.json)
-}
diff --git a/test/shim/validate.sh b/test/shim/validate.sh
deleted file mode 100755
index b56b79d2a..000000000
--- a/test/shim/validate.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-
-# A sample script to validate a running nginx container.
-
-set -ex
-
-{ # Step 1: Inspect the pod
-sudo crictl inspectp ${SANDBOX_ID}
-}
-
-{ # Step 2: Inspect the container
-sudo crictl inspect ${CONTAINER_ID}
-}
-
-{ # Step 3: Check dmesg
-sudo crictl exec ${CONTAINER_ID} dmesg | grep -i gvisor
-}
diff --git a/tools/bazel.mk b/tools/bazel.mk
index 9f4a40669..9e02af8dc 100644
--- a/tools/bazel.mk
+++ b/tools/bazel.mk
@@ -109,7 +109,7 @@ copy: bazel-server
ifeq (,$(DESTINATION))
$(error Destination not provided.)
endif
- @$(call build_paths,cp -a {} $(DESTINATION))
+ @$(call build_paths,cp -fa {} $(DESTINATION))
run: bazel-server
@$(call build_paths,{} $(ARGS))
diff --git a/tools/installers/BUILD b/tools/installers/BUILD
index caa7b1983..017d8ca25 100644
--- a/tools/installers/BUILD
+++ b/tools/installers/BUILD
@@ -7,7 +7,11 @@ package(
filegroup(
name = "runsc",
- srcs = ["//runsc"],
+ srcs = [
+ "//runsc",
+ "//shim/v1:gvisor-containerd-shim",
+ "//shim/v2:containerd-shim-runsc-v1",
+ ],
)
sh_binary(
@@ -30,6 +34,6 @@ sh_binary(
)
sh_binary(
- name = "shim",
- srcs = ["shim.sh"],
+ name = "containerd",
+ srcs = ["containerd.sh"],
)
diff --git a/tools/installers/containerd.sh b/tools/installers/containerd.sh
new file mode 100755
index 000000000..6b7bb261c
--- /dev/null
+++ b/tools/installers/containerd.sh
@@ -0,0 +1,114 @@
+#!/bin/bash
+
+# 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
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -xeo pipefail
+
+declare -r CONTAINERD_VERSION=${CONTAINERD_VERSION:-1.3.0}
+declare -r CONTAINERD_MAJOR="$(echo ${CONTAINERD_VERSION} | awk -F '.' '{ print $1; }')"
+declare -r CONTAINERD_MINOR="$(echo ${CONTAINERD_VERSION} | awk -F '.' '{ print $2; }')"
+
+# Default to an older version for crictl for containerd <= 1.2.
+if [[ "${CONTAINERD_MAJOR}" -eq 1 ]] && [[ "${CONTAINERD_MINOR}" -le 2 ]]; then
+ declare -r CRITOOLS_VERSION=${CRITOOLS_VERSION:-1.13.0}
+else
+ declare -r CRITOOLS_VERSION=${CRITOOLS_VERSION:-1.18.0}
+fi
+
+# Helper for Go packages below.
+install_helper() {
+ PACKAGE="${1}"
+ TAG="${2}"
+
+ # Clone the repository.
+ mkdir -p "${GOPATH}"/src/$(dirname "${PACKAGE}") && \
+ git clone https://"${PACKAGE}" "${GOPATH}"/src/"${PACKAGE}"
+
+ # Checkout and build the repository.
+ (cd "${GOPATH}"/src/"${PACKAGE}" && \
+ git checkout "${TAG}" && \
+ make && \
+ make install)
+}
+
+# Install dependencies for the crictl tests.
+while true; do
+ if (apt-get update && apt-get install -y \
+ btrfs-tools \
+ libseccomp-dev); then
+ break
+ fi
+ result=$?
+ if [[ $result -ne 100 ]]; then
+ exit $result
+ fi
+done
+
+# Install containerd & cri-tools.
+declare -rx GOPATH=$(mktemp -d --tmpdir gopathXXXXX)
+install_helper github.com/containerd/containerd "v${CONTAINERD_VERSION}" "${GOPATH}"
+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"
+
+[runsc_config]
+ debug = "true"
+ debug-log = "/tmp/runsc-logs/"
+ strace = "true"
+ file-access = "shared"
+EOF
+fi
+
+# Configure CNI.
+(cd "${GOPATH}" && src/github.com/containerd/containerd/script/setup/install-cni)
+cat <<EOF | sudo tee /etc/cni/net.d/10-bridge.conf
+{
+ "cniVersion": "0.3.1",
+ "name": "bridge",
+ "type": "bridge",
+ "bridge": "cnio0",
+ "isGateway": true,
+ "ipMasq": true,
+ "ipam": {
+ "type": "host-local",
+ "ranges": [
+ [{"subnet": "10.200.0.0/24"}]
+ ],
+ "routes": [{"dst": "0.0.0.0/0"}]
+ }
+}
+EOF
+cat <<EOF | sudo tee /etc/cni/net.d/99-loopback.conf
+{
+ "cniVersion": "0.3.1",
+ "type": "loopback"
+}
+EOF
+
+# Configure crictl.
+cat <<EOF | sudo tee /etc/crictl.yaml
+runtime-endpoint: unix:///run/containerd/containerd.sock
+EOF
+
+# Cleanup.
+rm -rf "${GOPATH}"
diff --git a/tools/installers/head.sh b/tools/installers/head.sh
index 7fc566ebd..e6753f8a5 100755
--- a/tools/installers/head.sh
+++ b/tools/installers/head.sh
@@ -17,5 +17,11 @@
# Install our runtime.
$(find . -executable -type f -name runsc) install
+# Install all the shims.
+find . -executable -type f -executable -name containerd-shim-runsc-v1 -exec cp {} /usr/bin \;
+find . -executable -type f -executable -name gvisor-containerd-shim -exec cp {} /usr/bin \;
+
# Restart docker.
-service docker restart || true
+if service docker status 2>/dev/null; then
+ service docker restart
+fi
diff --git a/tools/vm/ubuntu1604/30_containerd.sh b/tools/vm/ubuntu1604/30_containerd.sh
deleted file mode 100755
index fb3699c12..000000000
--- a/tools/vm/ubuntu1604/30_containerd.sh
+++ /dev/null
@@ -1,86 +0,0 @@
-#!/bin/bash
-
-# 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
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-set -xeo pipefail
-
-# Helper for Go packages below.
-install_helper() {
- PACKAGE="${1}"
- TAG="${2}"
- GOPATH="${3}"
-
- # Clone the repository.
- mkdir -p "${GOPATH}"/src/$(dirname "${PACKAGE}") && \
- git clone https://"${PACKAGE}" "${GOPATH}"/src/"${PACKAGE}"
-
- # Checkout and build the repository.
- (cd "${GOPATH}"/src/"${PACKAGE}" && \
- git checkout "${TAG}" && \
- GOPATH="${GOPATH}" make && \
- GOPATH="${GOPATH}" make install)
-}
-
-# Install dependencies for the crictl tests.
-while true; do
- if (apt-get update && apt-get install -y \
- btrfs-tools \
- libseccomp-dev); then
- break
- fi
- result=$?
- if [[ $result -ne 100 ]]; then
- exit $result
- fi
-done
-
-# Install containerd & cri-tools.
-GOPATH=$(mktemp -d --tmpdir gopathXXXXX)
-install_helper github.com/containerd/containerd v1.2.2 "${GOPATH}"
-install_helper github.com/kubernetes-sigs/cri-tools v1.11.0 "${GOPATH}"
-
-# Install gvisor-containerd-shim.
-declare -r base="https://storage.googleapis.com/cri-containerd-staging/gvisor-containerd-shim"
-declare -r latest=$(mktemp --tmpdir gvisor-containerd-shim-latest.XXXXXX)
-declare -r shim_path=$(mktemp --tmpdir gvisor-containerd-shim.XXXXXX)
-wget --no-verbose "${base}"/latest -O ${latest}
-wget --no-verbose "${base}"/gvisor-containerd-shim-$(cat ${latest}) -O ${shim_path}
-chmod +x ${shim_path}
-mv ${shim_path} /usr/local/bin
-
-# Configure containerd-shim.
-declare -r shim_config_path=/etc/containerd
-declare -r shim_config_tmp_path=$(mktemp --tmpdir gvisor-containerd-shim.XXXXXX.toml)
-mkdir -p ${shim_config_path}
-cat > ${shim_config_tmp_path} <<-EOF
- runc_shim = "/usr/local/bin/containerd-shim"
-
-[runsc_config]
- debug = "true"
- debug-log = "/tmp/runsc-logs/"
- strace = "true"
- file-access = "shared"
-EOF
-mv ${shim_config_tmp_path} ${shim_config_path}
-
-# Configure CNI.
-(cd "${GOPATH}" && GOPATH="${GOPATH}" \
- src/github.com/containerd/containerd/script/setup/install-cni)
-
-# Cleanup the above.
-rm -rf "${GOPATH}"
-rm -rf "${latest}"
-rm -rf "${shim_path}"
-rm -rf "${shim_config_tmp_path}"
diff --git a/tools/vm/ubuntu1604/25_docker.sh b/tools/vm/ubuntu1604/30_docker.sh
index 53d8ca588..53d8ca588 100755
--- a/tools/vm/ubuntu1604/25_docker.sh
+++ b/tools/vm/ubuntu1604/30_docker.sh
diff --git a/website/BUILD b/website/BUILD
index 4488cb543..a1169739d 100644
--- a/website/BUILD
+++ b/website/BUILD
@@ -151,12 +151,15 @@ docs(
"//g3doc/user_guide:install",
"//g3doc/user_guide:networking",
"//g3doc/user_guide:platforms",
+ "//g3doc/user_guide:runtimeclass",
"//g3doc/user_guide/quick_start:docker",
"//g3doc/user_guide/quick_start:kubernetes",
"//g3doc/user_guide/quick_start:oci",
"//g3doc/user_guide/tutorials:cni",
"//g3doc/user_guide/tutorials:docker",
"//g3doc/user_guide/tutorials:kubernetes",
+ "//shim/v1:doc",
+ "//shim/v2:doc",
],
)