summaryrefslogtreecommitdiffhomepage
path: root/pkg/shim/v2
diff options
context:
space:
mode:
authorFabricio Voznika <fvoznika@google.com>2021-01-12 17:50:33 -0800
committergVisor bot <gvisor-bot@google.com>2021-01-12 17:54:10 -0800
commit8b0f0b4d11e0938eec8da411323b2ce35976ab56 (patch)
treeaab8e37ca51133da5bfa4a055ea0dfa0bda514cf /pkg/shim/v2
parentbe2b9d75d75e0e7371cd868589d57f4ddee44781 (diff)
Delete shim v1
gvisor-containerd-shim is not compatible with containerd 1.1 or earlier. Starting from containerd 1.2, shim v2 is the preferred interface. PiperOrigin-RevId: 351485556
Diffstat (limited to 'pkg/shim/v2')
-rw-r--r--pkg/shim/v2/BUILD47
-rw-r--r--pkg/shim/v2/api.go23
-rw-r--r--pkg/shim/v2/epoll.go129
-rw-r--r--pkg/shim/v2/options.go50
-rw-r--r--pkg/shim/v2/runtimeoptions/BUILD32
-rw-r--r--pkg/shim/v2/runtimeoptions/runtimeoptions.go17
-rw-r--r--pkg/shim/v2/runtimeoptions/runtimeoptions.proto25
-rw-r--r--pkg/shim/v2/runtimeoptions/runtimeoptions_cri.go383
-rw-r--r--pkg/shim/v2/runtimeoptions/runtimeoptions_test.go57
-rw-r--r--pkg/shim/v2/service.go953
-rw-r--r--pkg/shim/v2/service_linux.go108
-rw-r--r--pkg/shim/v2/state.go48
12 files changed, 0 insertions, 1872 deletions
diff --git a/pkg/shim/v2/BUILD b/pkg/shim/v2/BUILD
deleted file mode 100644
index b0e8daa51..000000000
--- a/pkg/shim/v2/BUILD
+++ /dev/null
@@ -1,47 +0,0 @@
-load("//tools:defs.bzl", "go_library")
-
-package(licenses = ["notice"])
-
-go_library(
- name = "v2",
- srcs = [
- "api.go",
- "epoll.go",
- "options.go",
- "service.go",
- "service_linux.go",
- "state.go",
- ],
- visibility = ["//shim:__subpackages__"],
- deps = [
- "//pkg/cleanup",
- "//pkg/shim/runsc",
- "//pkg/shim/v1/proc",
- "//pkg/shim/v1/utils",
- "//pkg/shim/v2/runtimeoptions",
- "//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//pkg/process:go_default_library",
- "@com_github_containerd_containerd//pkg/stdio:go_default_library",
- "@com_github_containerd_containerd//runtime:go_default_library",
- "@com_github_containerd_containerd//runtime/linux/runctypes:go_default_library",
- "@com_github_containerd_containerd//runtime/v2/shim:go_default_library",
- "@com_github_containerd_containerd//runtime/v2/task:go_default_library",
- "@com_github_containerd_containerd//sys/reaper:go_default_library",
- "@com_github_containerd_fifo//:go_default_library",
- "@com_github_containerd_typeurl//:go_default_library",
- "@com_github_gogo_protobuf//types:go_default_library",
- "@com_github_sirupsen_logrus//:go_default_library",
- "@org_golang_x_sys//unix:go_default_library",
- ],
-)
diff --git a/pkg/shim/v2/api.go b/pkg/shim/v2/api.go
deleted file mode 100644
index 5a60a04db..000000000
--- a/pkg/shim/v2/api.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2018 The containerd Authors.
-// Copyright 2018 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v2
-
-import (
- "github.com/containerd/containerd/api/events"
-)
-
-// TaskOOM is an alias for events.TaskOOM.
-type TaskOOM = events.TaskOOM
diff --git a/pkg/shim/v2/epoll.go b/pkg/shim/v2/epoll.go
deleted file mode 100644
index 41232cca8..000000000
--- a/pkg/shim/v2/epoll.go
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2018 The containerd Authors.
-// Copyright 2018 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build linux
-
-package v2
-
-import (
- "context"
- "fmt"
- "sync"
-
- "github.com/containerd/cgroups"
- "github.com/containerd/containerd/events"
- "github.com/containerd/containerd/runtime"
- "golang.org/x/sys/unix"
-)
-
-func newOOMEpoller(publisher events.Publisher) (*epoller, error) {
- fd, err := unix.EpollCreate1(unix.EPOLL_CLOEXEC)
- if err != nil {
- return nil, err
- }
- return &epoller{
- fd: fd,
- publisher: publisher,
- set: make(map[uintptr]*item),
- }, nil
-}
-
-type epoller struct {
- mu sync.Mutex
-
- fd int
- publisher events.Publisher
- set map[uintptr]*item
-}
-
-type item struct {
- id string
- cg cgroups.Cgroup
-}
-
-func (e *epoller) Close() error {
- return unix.Close(e.fd)
-}
-
-func (e *epoller) run(ctx context.Context) {
- var events [128]unix.EpollEvent
- for {
- select {
- case <-ctx.Done():
- e.Close()
- return
- default:
- n, err := unix.EpollWait(e.fd, events[:], -1)
- if err != nil {
- if err == unix.EINTR || err == unix.EAGAIN {
- continue
- }
- // Should not happen.
- panic(fmt.Errorf("cgroups: epoll wait: %w", err))
- }
- for i := 0; i < n; i++ {
- e.process(ctx, uintptr(events[i].Fd))
- }
- }
- }
-}
-
-func (e *epoller) add(id string, cg cgroups.Cgroup) error {
- e.mu.Lock()
- defer e.mu.Unlock()
- fd, err := cg.OOMEventFD()
- if err != nil {
- return err
- }
- e.set[fd] = &item{
- id: id,
- cg: cg,
- }
- event := unix.EpollEvent{
- Fd: int32(fd),
- Events: unix.EPOLLHUP | unix.EPOLLIN | unix.EPOLLERR,
- }
- return unix.EpollCtl(e.fd, unix.EPOLL_CTL_ADD, int(fd), &event)
-}
-
-func (e *epoller) process(ctx context.Context, fd uintptr) {
- flush(fd)
- e.mu.Lock()
- i, ok := e.set[fd]
- if !ok {
- e.mu.Unlock()
- return
- }
- e.mu.Unlock()
- if i.cg.State() == cgroups.Deleted {
- e.mu.Lock()
- delete(e.set, fd)
- e.mu.Unlock()
- unix.Close(int(fd))
- return
- }
- if err := e.publisher.Publish(ctx, runtime.TaskOOMEventTopic, &TaskOOM{
- ContainerID: i.id,
- }); err != nil {
- // Should not happen.
- panic(fmt.Errorf("publish OOM event: %w", err))
- }
-}
-
-func flush(fd uintptr) error {
- var buf [8]byte
- _, err := unix.Read(int(fd), buf[:])
- return err
-}
diff --git a/pkg/shim/v2/options.go b/pkg/shim/v2/options.go
deleted file mode 100644
index 9db33fd1f..000000000
--- a/pkg/shim/v2/options.go
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2018 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v2
-
-const optionsType = "io.containerd.runsc.v1.options"
-
-// options is runtime options for io.containerd.runsc.v1.
-type options struct {
- // ShimCgroup is the cgroup the shim should be in.
- ShimCgroup string `toml:"shim_cgroup" json:"shimCgroup"`
-
- // IoUID is the I/O's pipes uid.
- IoUID uint32 `toml:"io_uid" json:"ioUid"`
-
- // IoGID is the I/O's pipes gid.
- IoGID uint32 `toml:"io_gid" json:"ioGid"`
-
- // BinaryName is the binary name of the runsc binary.
- BinaryName string `toml:"binary_name" json:"binaryName"`
-
- // Root is the runsc root directory.
- Root string `toml:"root" json:"root"`
-
- // LogLevel sets the logging level. Some of the possible values are: debug,
- // info, warning.
- //
- // This configuration only applies when the shim is running as a service.
- LogLevel string `toml:"log_level" json:"logLevel"`
-
- // LogPath is the path to log directory. %ID% tags inside the string are
- // replaced with the container ID.
- //
- // This configuration only applies when the shim is running as a service.
- LogPath string `toml:"log_path" json:"logPath"`
-
- // RunscConfig is a key/value map of all runsc flags.
- RunscConfig map[string]string `toml:"runsc_config" json:"runscConfig"`
-}
diff --git a/pkg/shim/v2/runtimeoptions/BUILD b/pkg/shim/v2/runtimeoptions/BUILD
deleted file mode 100644
index abb8c3be3..000000000
--- a/pkg/shim/v2/runtimeoptions/BUILD
+++ /dev/null
@@ -1,32 +0,0 @@
-load("//tools:defs.bzl", "go_library", "go_test", "proto_library")
-
-package(licenses = ["notice"])
-
-proto_library(
- name = "api",
- srcs = [
- "runtimeoptions.proto",
- ],
-)
-
-go_library(
- name = "runtimeoptions",
- srcs = [
- "runtimeoptions.go",
- "runtimeoptions_cri.go",
- ],
- visibility = ["//pkg/shim/v2:__pkg__"],
- deps = ["@com_github_gogo_protobuf//proto:go_default_library"],
-)
-
-go_test(
- name = "runtimeoptions_test",
- size = "small",
- srcs = ["runtimeoptions_test.go"],
- library = ":runtimeoptions",
- deps = [
- "@com_github_containerd_containerd//runtime/v1/shim/v1:go_default_library",
- "@com_github_containerd_typeurl//:go_default_library",
- "@com_github_gogo_protobuf//proto:go_default_library",
- ],
-)
diff --git a/pkg/shim/v2/runtimeoptions/runtimeoptions.go b/pkg/shim/v2/runtimeoptions/runtimeoptions.go
deleted file mode 100644
index 072dd87f0..000000000
--- a/pkg/shim/v2/runtimeoptions/runtimeoptions.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2018 The containerd Authors.
-// Copyright 2018 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package runtimeoptions contains the runtimeoptions proto.
-package runtimeoptions
diff --git a/pkg/shim/v2/runtimeoptions/runtimeoptions.proto b/pkg/shim/v2/runtimeoptions/runtimeoptions.proto
deleted file mode 100644
index 057032e34..000000000
--- a/pkg/shim/v2/runtimeoptions/runtimeoptions.proto
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2020 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-syntax = "proto3";
-
-package cri.runtimeoptions.v1;
-
-// This is a version of the runtimeoptions CRI API that is vendored.
-//
-// Importing the full CRI package is a nightmare.
-message Options {
- string type_url = 1;
- string config_path = 2;
-}
diff --git a/pkg/shim/v2/runtimeoptions/runtimeoptions_cri.go b/pkg/shim/v2/runtimeoptions/runtimeoptions_cri.go
deleted file mode 100644
index e6102b4cf..000000000
--- a/pkg/shim/v2/runtimeoptions/runtimeoptions_cri.go
+++ /dev/null
@@ -1,383 +0,0 @@
-// Copyright 2018 The containerd Authors.
-// Copyright 2018 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package runtimeoptions
-
-import (
- "fmt"
- "io"
- "reflect"
- "strings"
-
- proto "github.com/gogo/protobuf/proto"
-)
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
-
-type Options struct {
- // TypeUrl specifies the type of the content inside the config file.
- TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl,proto3" json:"type_url,omitempty"`
- // ConfigPath specifies the filesystem location of the config file
- // used by the runtime.
- ConfigPath string `protobuf:"bytes,2,opt,name=config_path,json=configPath,proto3" json:"config_path,omitempty"`
-}
-
-func (m *Options) Reset() { *m = Options{} }
-func (*Options) ProtoMessage() {}
-func (*Options) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{0} }
-
-func (m *Options) GetTypeUrl() string {
- if m != nil {
- return m.TypeUrl
- }
- return ""
-}
-
-func (m *Options) GetConfigPath() string {
- if m != nil {
- return m.ConfigPath
- }
- return ""
-}
-
-func init() {
- proto.RegisterType((*Options)(nil), "cri.runtimeoptions.v1.Options")
-}
-
-func (m *Options) Marshal() (dAtA []byte, err error) {
- size := m.Size()
- dAtA = make([]byte, size)
- n, err := m.MarshalTo(dAtA)
- if err != nil {
- return nil, err
- }
- return dAtA[:n], nil
-}
-
-func (m *Options) MarshalTo(dAtA []byte) (int, error) {
- var i int
- _ = i
- var l int
- _ = l
- if len(m.TypeUrl) > 0 {
- dAtA[i] = 0xa
- i++
- i = encodeVarintApi(dAtA, i, uint64(len(m.TypeUrl)))
- i += copy(dAtA[i:], m.TypeUrl)
- }
- if len(m.ConfigPath) > 0 {
- dAtA[i] = 0x12
- i++
- i = encodeVarintApi(dAtA, i, uint64(len(m.ConfigPath)))
- i += copy(dAtA[i:], m.ConfigPath)
- }
- return i, nil
-}
-
-func encodeVarintApi(dAtA []byte, offset int, v uint64) int {
- for v >= 1<<7 {
- dAtA[offset] = uint8(v&0x7f | 0x80)
- v >>= 7
- offset++
- }
- dAtA[offset] = uint8(v)
- return offset + 1
-}
-
-func (m *Options) Size() (n int) {
- var l int
- _ = l
- l = len(m.TypeUrl)
- if l > 0 {
- n += 1 + l + sovApi(uint64(l))
- }
- l = len(m.ConfigPath)
- if l > 0 {
- n += 1 + l + sovApi(uint64(l))
- }
- return n
-}
-
-func sovApi(x uint64) (n int) {
- for {
- n++
- x >>= 7
- if x == 0 {
- break
- }
- }
- return n
-}
-
-func sozApi(x uint64) (n int) {
- return sovApi(uint64((x << 1) ^ uint64((int64(x) >> 63))))
-}
-
-func (this *Options) String() string {
- if this == nil {
- return "nil"
- }
- s := strings.Join([]string{`&Options{`,
- `TypeUrl:` + fmt.Sprintf("%v", this.TypeUrl) + `,`,
- `ConfigPath:` + fmt.Sprintf("%v", this.ConfigPath) + `,`,
- `}`,
- }, "")
- return s
-}
-
-func valueToStringApi(v interface{}) string {
- rv := reflect.ValueOf(v)
- if rv.IsNil() {
- return "nil"
- }
- pv := reflect.Indirect(rv).Interface()
- return fmt.Sprintf("*%v", pv)
-}
-
-func (m *Options) Unmarshal(dAtA []byte) error {
- l := len(dAtA)
- iNdEx := 0
- for iNdEx < l {
- preIndex := iNdEx
- var wire uint64
- for shift := uint(0); ; shift += 7 {
- if shift >= 64 {
- return ErrIntOverflowApi
- }
- if iNdEx >= l {
- return io.ErrUnexpectedEOF
- }
- b := dAtA[iNdEx]
- iNdEx++
- wire |= (uint64(b) & 0x7F) << shift
- if b < 0x80 {
- break
- }
- }
- fieldNum := int32(wire >> 3)
- wireType := int(wire & 0x7)
- if wireType == 4 {
- return fmt.Errorf("proto: Options: wiretype end group for non-group")
- }
- if fieldNum <= 0 {
- return fmt.Errorf("proto: Options: illegal tag %d (wire type %d)", fieldNum, wire)
- }
- switch fieldNum {
- case 1:
- if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field TypeUrl", wireType)
- }
- var stringLen uint64
- for shift := uint(0); ; shift += 7 {
- if shift >= 64 {
- return ErrIntOverflowApi
- }
- if iNdEx >= l {
- return io.ErrUnexpectedEOF
- }
- b := dAtA[iNdEx]
- iNdEx++
- stringLen |= (uint64(b) & 0x7F) << shift
- if b < 0x80 {
- break
- }
- }
- intStringLen := int(stringLen)
- if intStringLen < 0 {
- return ErrInvalidLengthApi
- }
- postIndex := iNdEx + intStringLen
- if postIndex > l {
- return io.ErrUnexpectedEOF
- }
- m.TypeUrl = string(dAtA[iNdEx:postIndex])
- iNdEx = postIndex
- case 2:
- if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field ConfigPath", wireType)
- }
- var stringLen uint64
- for shift := uint(0); ; shift += 7 {
- if shift >= 64 {
- return ErrIntOverflowApi
- }
- if iNdEx >= l {
- return io.ErrUnexpectedEOF
- }
- b := dAtA[iNdEx]
- iNdEx++
- stringLen |= (uint64(b) & 0x7F) << shift
- if b < 0x80 {
- break
- }
- }
- intStringLen := int(stringLen)
- if intStringLen < 0 {
- return ErrInvalidLengthApi
- }
- postIndex := iNdEx + intStringLen
- if postIndex > l {
- return io.ErrUnexpectedEOF
- }
- m.ConfigPath = string(dAtA[iNdEx:postIndex])
- iNdEx = postIndex
- default:
- iNdEx = preIndex
- skippy, err := skipApi(dAtA[iNdEx:])
- if err != nil {
- return err
- }
- if skippy < 0 {
- return ErrInvalidLengthApi
- }
- if (iNdEx + skippy) > l {
- return io.ErrUnexpectedEOF
- }
- iNdEx += skippy
- }
- }
-
- if iNdEx > l {
- return io.ErrUnexpectedEOF
- }
- return nil
-}
-
-func skipApi(dAtA []byte) (n int, err error) {
- l := len(dAtA)
- iNdEx := 0
- for iNdEx < l {
- var wire uint64
- for shift := uint(0); ; shift += 7 {
- if shift >= 64 {
- return 0, ErrIntOverflowApi
- }
- if iNdEx >= l {
- return 0, io.ErrUnexpectedEOF
- }
- b := dAtA[iNdEx]
- iNdEx++
- wire |= (uint64(b) & 0x7F) << shift
- if b < 0x80 {
- break
- }
- }
- wireType := int(wire & 0x7)
- switch wireType {
- case 0:
- for shift := uint(0); ; shift += 7 {
- if shift >= 64 {
- return 0, ErrIntOverflowApi
- }
- if iNdEx >= l {
- return 0, io.ErrUnexpectedEOF
- }
- iNdEx++
- if dAtA[iNdEx-1] < 0x80 {
- break
- }
- }
- return iNdEx, nil
- case 1:
- iNdEx += 8
- return iNdEx, nil
- case 2:
- var length int
- for shift := uint(0); ; shift += 7 {
- if shift >= 64 {
- return 0, ErrIntOverflowApi
- }
- if iNdEx >= l {
- return 0, io.ErrUnexpectedEOF
- }
- b := dAtA[iNdEx]
- iNdEx++
- length |= (int(b) & 0x7F) << shift
- if b < 0x80 {
- break
- }
- }
- iNdEx += length
- if length < 0 {
- return 0, ErrInvalidLengthApi
- }
- return iNdEx, nil
- case 3:
- for {
- var innerWire uint64
- var start int = iNdEx
- for shift := uint(0); ; shift += 7 {
- if shift >= 64 {
- return 0, ErrIntOverflowApi
- }
- if iNdEx >= l {
- return 0, io.ErrUnexpectedEOF
- }
- b := dAtA[iNdEx]
- iNdEx++
- innerWire |= (uint64(b) & 0x7F) << shift
- if b < 0x80 {
- break
- }
- }
- innerWireType := int(innerWire & 0x7)
- if innerWireType == 4 {
- break
- }
- next, err := skipApi(dAtA[start:])
- if err != nil {
- return 0, err
- }
- iNdEx = start + next
- }
- return iNdEx, nil
- case 4:
- return iNdEx, nil
- case 5:
- iNdEx += 4
- return iNdEx, nil
- default:
- return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
- }
- }
- panic("unreachable")
-}
-
-var (
- ErrInvalidLengthApi = fmt.Errorf("proto: negative length found during unmarshaling")
- ErrIntOverflowApi = fmt.Errorf("proto: integer overflow")
-)
-
-func init() { proto.RegisterFile("api.proto", fileDescriptorApi) }
-
-var fileDescriptorApi = []byte{
- // 183 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4c, 0x2c, 0xc8, 0xd4,
- 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x4d, 0x2e, 0xca, 0xd4, 0x2b, 0x2a, 0xcd, 0x2b, 0xc9,
- 0xcc, 0x4d, 0xcd, 0x2f, 0x28, 0xc9, 0xcc, 0xcf, 0x2b, 0xd6, 0x2b, 0x33, 0x94, 0xd2, 0x4d, 0xcf,
- 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0x4f, 0xcf, 0xd7, 0x07, 0xab,
- 0x4e, 0x2a, 0x4d, 0x03, 0xf3, 0xc0, 0x1c, 0x30, 0x0b, 0x62, 0x8a, 0x92, 0x2b, 0x17, 0xbb, 0x3f,
- 0x44, 0xb3, 0x90, 0x24, 0x17, 0x47, 0x49, 0x65, 0x41, 0x6a, 0x7c, 0x69, 0x51, 0x8e, 0x04, 0xa3,
- 0x02, 0xa3, 0x06, 0x67, 0x10, 0x3b, 0x88, 0x1f, 0x5a, 0x94, 0x23, 0x24, 0xcf, 0xc5, 0x9d, 0x9c,
- 0x9f, 0x97, 0x96, 0x99, 0x1e, 0x5f, 0x90, 0x58, 0x92, 0x21, 0xc1, 0x04, 0x96, 0xe5, 0x82, 0x08,
- 0x05, 0x24, 0x96, 0x64, 0x38, 0xc9, 0x9c, 0x78, 0x28, 0xc7, 0x78, 0xe3, 0xa1, 0x1c, 0x43, 0xc3,
- 0x23, 0x39, 0xc6, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71,
- 0xc2, 0x63, 0x39, 0x86, 0x24, 0x36, 0xb0, 0x5d, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x07,
- 0x00, 0xf2, 0x18, 0xbe, 0x00, 0x00, 0x00,
-}
diff --git a/pkg/shim/v2/runtimeoptions/runtimeoptions_test.go b/pkg/shim/v2/runtimeoptions/runtimeoptions_test.go
deleted file mode 100644
index c59a2400e..000000000
--- a/pkg/shim/v2/runtimeoptions/runtimeoptions_test.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2020 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package runtimeoptions
-
-import (
- "bytes"
- "testing"
-
- shim "github.com/containerd/containerd/runtime/v1/shim/v1"
- "github.com/containerd/typeurl"
- "github.com/gogo/protobuf/proto"
-)
-
-func TestCreateTaskRequest(t *testing.T) {
- // Serialize the top-level message.
- const encodedText = `options: <
- type_url: "cri.runtimeoptions.v1.Options"
- value: "\n\010type_url\022\013config_path"
->`
- got := &shim.CreateTaskRequest{} // Should have raw options.
- if err := proto.UnmarshalText(encodedText, got); err != nil {
- t.Fatalf("unable to unmarshal text: %v", err)
- }
- var textBuffer bytes.Buffer
- if err := proto.MarshalText(&textBuffer, got); err != nil {
- t.Errorf("unable to marshal text: %v", err)
- }
- t.Logf("got: %s", string(textBuffer.Bytes()))
-
- // Check the options.
- wantOptions := &Options{}
- wantOptions.TypeUrl = "type_url"
- wantOptions.ConfigPath = "config_path"
- gotMessage, err := typeurl.UnmarshalAny(got.Options)
- if err != nil {
- t.Fatalf("unable to unmarshal any: %v", err)
- }
- gotOptions, ok := gotMessage.(*Options)
- if !ok {
- t.Fatalf("got %v, want %v", gotMessage, wantOptions)
- }
- if !proto.Equal(gotOptions, wantOptions) {
- t.Fatalf("got %v, want %v", gotOptions, wantOptions)
- }
-}
diff --git a/pkg/shim/v2/service.go b/pkg/shim/v2/service.go
deleted file mode 100644
index 6aaf5fab8..000000000
--- a/pkg/shim/v2/service.go
+++ /dev/null
@@ -1,953 +0,0 @@
-// Copyright 2018 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package v2 implements Containerd Shim v2 interface.
-package v2
-
-import (
- "context"
- "fmt"
- "io"
- "os"
- "os/exec"
- "path/filepath"
- "sync"
- "syscall"
- "time"
-
- "github.com/BurntSushi/toml"
- "github.com/containerd/cgroups"
- cgroupsstats "github.com/containerd/cgroups/stats/v1"
- "github.com/containerd/console"
- "github.com/containerd/containerd/api/events"
- "github.com/containerd/containerd/api/types/task"
- "github.com/containerd/containerd/errdefs"
- "github.com/containerd/containerd/log"
- "github.com/containerd/containerd/mount"
- "github.com/containerd/containerd/namespaces"
- "github.com/containerd/containerd/pkg/process"
- "github.com/containerd/containerd/pkg/stdio"
- "github.com/containerd/containerd/runtime"
- "github.com/containerd/containerd/runtime/linux/runctypes"
- "github.com/containerd/containerd/runtime/v2/shim"
- taskAPI "github.com/containerd/containerd/runtime/v2/task"
- "github.com/containerd/containerd/sys/reaper"
- "github.com/containerd/typeurl"
- "github.com/gogo/protobuf/types"
- "github.com/sirupsen/logrus"
- "golang.org/x/sys/unix"
- "gvisor.dev/gvisor/pkg/cleanup"
-
- "gvisor.dev/gvisor/pkg/shim/runsc"
- "gvisor.dev/gvisor/pkg/shim/v1/proc"
- "gvisor.dev/gvisor/pkg/shim/v1/utils"
- "gvisor.dev/gvisor/pkg/shim/v2/runtimeoptions"
- "gvisor.dev/gvisor/runsc/specutils"
-)
-
-var (
- empty = &types.Empty{}
- bufPool = sync.Pool{
- New: func() interface{} {
- buffer := make([]byte, 32<<10)
- return &buffer
- },
- }
-)
-
-var _ = (taskAPI.TaskService)(&service{})
-
-const (
- // configFile is the default config file name. For containerd 1.2,
- // we assume that a config.toml should exist in the runtime root.
- configFile = "config.toml"
-
- // shimAddressPath is the relative path to a file that contains the address
- // to the shim UDS. See service.shimAddress.
- shimAddressPath = "address"
-)
-
-// New returns a new shim service that can be used via GRPC.
-func New(ctx context.Context, id string, publisher shim.Publisher, cancel func()) (shim.Shim, error) {
- log.L.Debugf("service.New, id: %s", id)
-
- var opts shim.Opts
- if ctxOpts := ctx.Value(shim.OptsKey{}); ctxOpts != nil {
- opts = ctxOpts.(shim.Opts)
- }
-
- ep, err := newOOMEpoller(publisher)
- if err != nil {
- return nil, err
- }
- go ep.run(ctx)
- s := &service{
- id: id,
- processes: make(map[string]process.Process),
- events: make(chan interface{}, 128),
- ec: proc.ExitCh,
- oomPoller: ep,
- cancel: cancel,
- genericOptions: opts,
- }
- go s.processExits(ctx)
- runsc.Monitor = &runsc.LogMonitor{Next: reaper.Default}
- if err := s.initPlatform(); err != nil {
- cancel()
- return nil, fmt.Errorf("failed to initialized platform behavior: %w", err)
- }
- go s.forward(ctx, publisher)
-
- if address, err := shim.ReadAddress(shimAddressPath); err == nil {
- s.shimAddress = address
- }
-
- return s, nil
-}
-
-// service is the shim implementation of a remote shim over GRPC. It runs in 2
-// different modes:
-// 1. Service: process runs for the life time of the container and receives
-// calls described in shimapi.TaskService interface.
-// 2. Tool: process is short lived and runs only to perform the requested
-// operations and then exits. It implements the direct functions in
-// shim.Shim interface.
-//
-// When the service is running, it saves a json file with state information so
-// that commands sent to the tool can load the state and perform the operation.
-type service struct {
- mu sync.Mutex
-
- // id is the container ID.
- id string
-
- // bundle is a path provided by the caller on container creation. Store
- // because it's needed in commands that don't receive bundle in the request.
- bundle string
-
- // task is the main process that is running the container.
- task *proc.Init
-
- // processes maps ExecId to processes running through exec.
- processes map[string]process.Process
-
- events chan interface{}
-
- // platform handles operations related to the console.
- platform stdio.Platform
-
- // genericOptions are options that come from the shim interface and are common
- // to all shims.
- genericOptions shim.Opts
-
- // opts are configuration options specific for this shim.
- opts options
-
- // ex gets notified whenever the container init process or an exec'd process
- // exits from inside the sandbox.
- ec chan proc.Exit
-
- // oomPoller monitors the sandbox's cgroup for OOM notifications.
- oomPoller *epoller
-
- // cancel is a function that needs to be called before the shim stops. The
- // function is provided by the caller to New().
- cancel func()
-
- // shimAddress is the location of the UDS used to communicate to containerd.
- shimAddress string
-}
-
-func (s *service) newCommand(ctx context.Context, containerdBinary, containerdAddress string) (*exec.Cmd, error) {
- ns, err := namespaces.NamespaceRequired(ctx)
- if err != nil {
- return nil, err
- }
- self, err := os.Executable()
- if err != nil {
- return nil, err
- }
- cwd, err := os.Getwd()
- if err != nil {
- return nil, err
- }
- args := []string{
- "-namespace", ns,
- "-address", containerdAddress,
- "-publish-binary", containerdBinary,
- }
- if s.genericOptions.Debug {
- args = append(args, "-debug")
- }
- cmd := exec.Command(self, args...)
- cmd.Dir = cwd
- cmd.Env = append(os.Environ(), "GOMAXPROCS=2")
- cmd.SysProcAttr = &syscall.SysProcAttr{
- Setpgid: true,
- }
- return cmd, nil
-}
-
-func (s *service) StartShim(ctx context.Context, id, containerdBinary, containerdAddress, containerdTTRPCAddress string) (string, error) {
- log.L.Debugf("StartShim, id: %s, binary: %q, address: %q", id, containerdBinary, containerdAddress)
-
- cmd, err := s.newCommand(ctx, containerdBinary, containerdAddress)
- if err != nil {
- return "", err
- }
- address, err := shim.SocketAddress(ctx, containerdAddress, id)
- if err != nil {
- return "", err
- }
- socket, err := shim.NewSocket(address)
- if err != nil {
- // The only time where this would happen is if there is a bug and the socket
- // was not cleaned up in the cleanup method of the shim or we are using the
- // grouping functionality where the new process should be run with the same
- // shim as an existing container.
- if !shim.SocketEaddrinuse(err) {
- return "", fmt.Errorf("create new shim socket: %w", err)
- }
- if shim.CanConnect(address) {
- if err := shim.WriteAddress(shimAddressPath, address); err != nil {
- return "", fmt.Errorf("write existing socket for shim: %w", err)
- }
- return address, nil
- }
- if err := shim.RemoveSocket(address); err != nil {
- return "", fmt.Errorf("remove pre-existing socket: %w", err)
- }
- if socket, err = shim.NewSocket(address); err != nil {
- return "", fmt.Errorf("try create new shim socket 2x: %w", err)
- }
- }
- cu := cleanup.Make(func() {
- socket.Close()
- _ = shim.RemoveSocket(address)
- })
- defer cu.Clean()
-
- f, err := socket.File()
- if err != nil {
- return "", err
- }
-
- cmd.ExtraFiles = append(cmd.ExtraFiles, f)
-
- log.L.Debugf("Executing: %q %s", cmd.Path, cmd.Args)
- if err := cmd.Start(); err != nil {
- f.Close()
- return "", err
- }
- cu.Add(func() { cmd.Process.Kill() })
-
- // make sure to wait after start
- go cmd.Wait()
- if err := shim.WritePidFile("shim.pid", cmd.Process.Pid); err != nil {
- return "", err
- }
- if err := shim.WriteAddress(shimAddressPath, address); err != nil {
- return "", err
- }
- if err := shim.SetScore(cmd.Process.Pid); err != nil {
- return "", fmt.Errorf("failed to set OOM Score on shim: %w", err)
- }
- cu.Release()
- return address, nil
-}
-
-// Cleanup is called from another process (need to reload state) to stop the
-// container and undo all operations done in Create().
-func (s *service) Cleanup(ctx context.Context) (*taskAPI.DeleteResponse, error) {
- log.L.Debugf("Cleanup")
-
- path, err := os.Getwd()
- if err != nil {
- return nil, err
- }
- ns, err := namespaces.NamespaceRequired(ctx)
- if err != nil {
- return nil, err
- }
- var st state
- if err := st.load(path); err != nil {
- return nil, err
- }
- r := proc.NewRunsc(s.opts.Root, path, ns, st.Options.BinaryName, nil)
-
- if err := r.Delete(ctx, s.id, &runsc.DeleteOpts{
- Force: true,
- }); err != nil {
- log.L.Infof("failed to remove runc container: %v", err)
- }
- if err := mount.UnmountAll(st.Rootfs, 0); err != nil {
- log.L.Infof("failed to cleanup rootfs mount: %v", err)
- }
- return &taskAPI.DeleteResponse{
- ExitedAt: time.Now(),
- ExitStatus: 128 + uint32(unix.SIGKILL),
- }, nil
-}
-
-// 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, error) {
- log.L.Debugf("Create, id: %s, bundle: %q", r.ID, r.Bundle)
-
- s.mu.Lock()
- defer s.mu.Unlock()
-
- // Save the main task id and bundle to the shim for additional requests.
- s.id = r.ID
- s.bundle = r.Bundle
-
- ns, err := namespaces.NamespaceRequired(ctx)
- if err != nil {
- return nil, fmt.Errorf("create namespace: %w", err)
- }
-
- // Read from root for now.
- if r.Options != nil {
- v, err := typeurl.UnmarshalAny(r.Options)
- if err != nil {
- return nil, err
- }
- var path string
- switch o := v.(type) {
- case *runctypes.CreateOptions: // containerd 1.2.x
- s.opts.IoUID = o.IoUid
- s.opts.IoGID = o.IoGid
- s.opts.ShimCgroup = o.ShimCgroup
- case *runctypes.RuncOptions: // containerd 1.2.x
- root := proc.RunscRoot
- if o.RuntimeRoot != "" {
- root = o.RuntimeRoot
- }
-
- s.opts.BinaryName = o.Runtime
-
- path = filepath.Join(root, configFile)
- if _, err := os.Stat(path); err != nil {
- if !os.IsNotExist(err) {
- return nil, fmt.Errorf("stat config file %q: %w", path, err)
- }
- // A config file in runtime root is not required.
- path = ""
- }
- case *runtimeoptions.Options: // containerd 1.3.x+
- if o.ConfigPath == "" {
- break
- }
- if o.TypeUrl != optionsType {
- return nil, fmt.Errorf("unsupported option type %q", o.TypeUrl)
- }
- path = o.ConfigPath
- default:
- return nil, fmt.Errorf("unsupported option type %q", r.Options.TypeUrl)
- }
- if path != "" {
- if _, err = toml.DecodeFile(path, &s.opts); err != nil {
- return nil, fmt.Errorf("decode config file %q: %w", path, err)
- }
- }
- }
-
- if len(s.opts.LogLevel) != 0 {
- lvl, err := logrus.ParseLevel(s.opts.LogLevel)
- if err != nil {
- return nil, err
- }
- logrus.SetLevel(lvl)
- }
- if len(s.opts.LogPath) != 0 {
- logPath := runsc.FormatShimLogPath(s.opts.LogPath, s.id)
- if err := os.MkdirAll(filepath.Dir(logPath), 0777); err != nil {
- return nil, fmt.Errorf("failed to create log dir: %w", err)
- }
- logFile, err := os.Create(logPath)
- if err != nil {
- return nil, fmt.Errorf("failed to create log file: %w", err)
- }
- log.L.Debugf("Starting mirror log at %q", logPath)
- std := logrus.StandardLogger()
- std.SetOutput(io.MultiWriter(std.Out, logFile))
-
- log.L.Debugf("Create shim")
- log.L.Debugf("***************************")
- log.L.Debugf("Args: %s", os.Args)
- log.L.Debugf("PID: %d", os.Getpid())
- log.L.Debugf("ID: %s", s.id)
- log.L.Debugf("Options: %+v", s.opts)
- log.L.Debugf("Bundle: %s", r.Bundle)
- log.L.Debugf("Terminal: %t", r.Terminal)
- log.L.Debugf("stdin: %s", r.Stdin)
- log.L.Debugf("stdout: %s", r.Stdout)
- log.L.Debugf("stderr: %s", r.Stderr)
- log.L.Debugf("***************************")
- }
-
- // Save state before any action is taken to ensure Cleanup() will have all
- // the information it needs to undo the operations.
- st := state{
- Rootfs: filepath.Join(r.Bundle, "rootfs"),
- Options: s.opts,
- }
- if err := st.save(r.Bundle); err != nil {
- return nil, err
- }
-
- if err := os.Mkdir(st.Rootfs, 0711); err != nil && !os.IsExist(err) {
- return nil, err
- }
-
- // Convert from types.Mount to proc.Mount.
- var mounts []proc.Mount
- for _, m := range r.Rootfs {
- mounts = append(mounts, proc.Mount{
- Type: m.Type,
- Source: m.Source,
- Target: m.Target,
- Options: m.Options,
- })
- }
-
- // Cleans up all mounts in case of failure.
- cu := cleanup.Make(func() {
- if err := mount.UnmountAll(st.Rootfs, 0); err != nil {
- log.L.Infof("failed to cleanup rootfs mount: %v", err)
- }
- })
- defer cu.Clean()
- for _, rm := range mounts {
- m := &mount.Mount{
- Type: rm.Type,
- Source: rm.Source,
- Options: rm.Options,
- }
- if err := m.Mount(st.Rootfs); err != nil {
- return nil, fmt.Errorf("failed to mount rootfs component %v: %w", m, err)
- }
- }
-
- config := &proc.CreateConfig{
- ID: r.ID,
- Bundle: r.Bundle,
- Runtime: s.opts.BinaryName,
- Rootfs: mounts,
- Terminal: r.Terminal,
- Stdin: r.Stdin,
- Stdout: r.Stdout,
- Stderr: r.Stderr,
- }
- process, err := newInit(r.Bundle, filepath.Join(r.Bundle, "work"), ns, s.platform, config, &s.opts, st.Rootfs)
- if err != nil {
- return nil, errdefs.ToGRPC(err)
- }
- if err := process.Create(ctx, config); err != nil {
- return nil, errdefs.ToGRPC(err)
- }
-
- // 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, fmt.Errorf("loading cgroup for %d: %w", pid, err)
- }
- if err := s.oomPoller.add(s.id, cg); err != nil {
- return nil, fmt.Errorf("add cg to OOM monitor: %w", err)
- }
- }
-
- // Success
- cu.Release()
- s.task = process
- return &taskAPI.CreateTaskResponse{
- Pid: uint32(process.Pid()),
- }, nil
-}
-
-// Start starts a process.
-func (s *service) Start(ctx context.Context, r *taskAPI.StartRequest) (*taskAPI.StartResponse, error) {
- log.L.Debugf("Start, id: %s, execID: %s", r.ID, r.ExecID)
-
- p, err := s.getProcess(r.ExecID)
- if err != nil {
- return nil, err
- }
- if err := p.Start(ctx); err != nil {
- return nil, err
- }
- // TODO: Set the cgroup and oom notifications on restore.
- // https://github.com/google/gvisor-containerd-shim/issues/58
- return &taskAPI.StartResponse{
- Pid: uint32(p.Pid()),
- }, nil
-}
-
-// Delete deletes the initial process and container.
-func (s *service) Delete(ctx context.Context, r *taskAPI.DeleteRequest) (*taskAPI.DeleteResponse, error) {
- log.L.Debugf("Delete, id: %s, execID: %s", r.ID, r.ExecID)
-
- p, err := s.getProcess(r.ExecID)
- if err != nil {
- return nil, err
- }
- if p == nil {
- return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created")
- }
- if err := p.Delete(ctx); err != nil {
- return nil, err
- }
- if len(r.ExecID) != 0 {
- s.mu.Lock()
- delete(s.processes, r.ExecID)
- s.mu.Unlock()
- } else if s.platform != nil {
- s.platform.Close()
- }
- return &taskAPI.DeleteResponse{
- ExitStatus: uint32(p.ExitStatus()),
- ExitedAt: p.ExitedAt(),
- Pid: uint32(p.Pid()),
- }, nil
-}
-
-// Exec spawns an additional process inside the container.
-func (s *service) Exec(ctx context.Context, r *taskAPI.ExecProcessRequest) (*types.Empty, error) {
- log.L.Debugf("Exec, id: %s, execID: %s", r.ID, r.ExecID)
-
- s.mu.Lock()
- p := s.processes[r.ExecID]
- s.mu.Unlock()
- if p != nil {
- return nil, errdefs.ToGRPCf(errdefs.ErrAlreadyExists, "id %s", r.ExecID)
- }
- if s.task == nil {
- return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created")
- }
- process, err := s.task.Exec(ctx, s.bundle, &proc.ExecConfig{
- ID: r.ExecID,
- Terminal: r.Terminal,
- Stdin: r.Stdin,
- Stdout: r.Stdout,
- Stderr: r.Stderr,
- Spec: r.Spec,
- })
- if err != nil {
- return nil, errdefs.ToGRPC(err)
- }
- s.mu.Lock()
- s.processes[r.ExecID] = process
- s.mu.Unlock()
- return empty, nil
-}
-
-// ResizePty resizes the terminal of a process.
-func (s *service) ResizePty(ctx context.Context, r *taskAPI.ResizePtyRequest) (*types.Empty, error) {
- log.L.Debugf("ResizePty, id: %s, execID: %s, dimension: %dx%d", r.ID, r.ExecID, r.Height, r.Width)
-
- p, err := s.getProcess(r.ExecID)
- if err != nil {
- return nil, err
- }
- ws := console.WinSize{
- Width: uint16(r.Width),
- Height: uint16(r.Height),
- }
- if err := p.Resize(ws); err != nil {
- return nil, errdefs.ToGRPC(err)
- }
- return empty, nil
-}
-
-// State returns runtime state information for a process.
-func (s *service) State(ctx context.Context, r *taskAPI.StateRequest) (*taskAPI.StateResponse, error) {
- log.L.Debugf("State, id: %s, execID: %s", r.ID, r.ExecID)
-
- p, err := s.getProcess(r.ExecID)
- if err != nil {
- return nil, err
- }
- st, err := p.Status(ctx)
- if err != nil {
- return nil, err
- }
- status := task.StatusUnknown
- switch st {
- case "created":
- status = task.StatusCreated
- case "running":
- status = task.StatusRunning
- case "stopped":
- status = task.StatusStopped
- }
- sio := p.Stdio()
- return &taskAPI.StateResponse{
- ID: p.ID(),
- Bundle: s.bundle,
- Pid: uint32(p.Pid()),
- Status: status,
- Stdin: sio.Stdin,
- Stdout: sio.Stdout,
- Stderr: sio.Stderr,
- Terminal: sio.Terminal,
- ExitStatus: uint32(p.ExitStatus()),
- ExitedAt: p.ExitedAt(),
- }, nil
-}
-
-// Pause the container.
-func (s *service) Pause(ctx context.Context, r *taskAPI.PauseRequest) (*types.Empty, error) {
- log.L.Debugf("Pause, id: %s", r.ID)
- return empty, errdefs.ToGRPC(errdefs.ErrNotImplemented)
-}
-
-// Resume the container.
-func (s *service) Resume(ctx context.Context, r *taskAPI.ResumeRequest) (*types.Empty, error) {
- log.L.Debugf("Resume, id: %s", r.ID)
- return empty, errdefs.ToGRPC(errdefs.ErrNotImplemented)
-}
-
-// Kill a process with the provided signal.
-func (s *service) Kill(ctx context.Context, r *taskAPI.KillRequest) (*types.Empty, error) {
- log.L.Debugf("Kill, id: %s, execID: %s, signal: %d, all: %t", r.ID, r.ExecID, r.Signal, r.All)
-
- p, err := s.getProcess(r.ExecID)
- if err != nil {
- return nil, err
- }
- if p == nil {
- return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created")
- }
- if err := p.Kill(ctx, r.Signal, r.All); err != nil {
- return nil, errdefs.ToGRPC(err)
- }
- return empty, nil
-}
-
-// Pids returns all pids inside the container.
-func (s *service) Pids(ctx context.Context, r *taskAPI.PidsRequest) (*taskAPI.PidsResponse, error) {
- log.L.Debugf("Pids, id: %s", r.ID)
-
- pids, err := s.getContainerPids(ctx, r.ID)
- if err != nil {
- return nil, errdefs.ToGRPC(err)
- }
- var processes []*task.ProcessInfo
- for _, pid := range pids {
- pInfo := task.ProcessInfo{
- Pid: pid,
- }
- for _, p := range s.processes {
- if p.Pid() == int(pid) {
- d := &runctypes.ProcessDetails{
- ExecID: p.ID(),
- }
- a, err := typeurl.MarshalAny(d)
- if err != nil {
- return nil, fmt.Errorf("failed to marshal process %d info: %w", pid, err)
- }
- pInfo.Info = a
- break
- }
- }
- processes = append(processes, &pInfo)
- }
- return &taskAPI.PidsResponse{
- Processes: processes,
- }, nil
-}
-
-// CloseIO closes the I/O context of a process.
-func (s *service) CloseIO(ctx context.Context, r *taskAPI.CloseIORequest) (*types.Empty, error) {
- log.L.Debugf("CloseIO, id: %s, execID: %s, stdin: %t", r.ID, r.ExecID, r.Stdin)
-
- p, err := s.getProcess(r.ExecID)
- if err != nil {
- return nil, err
- }
- if stdin := p.Stdin(); stdin != nil {
- if err := stdin.Close(); err != nil {
- return nil, fmt.Errorf("close stdin: %w", err)
- }
- }
- return empty, nil
-}
-
-// Checkpoint checkpoints the container.
-func (s *service) Checkpoint(ctx context.Context, r *taskAPI.CheckpointTaskRequest) (*types.Empty, error) {
- log.L.Debugf("Checkpoint, id: %s", r.ID)
- return empty, errdefs.ToGRPC(errdefs.ErrNotImplemented)
-}
-
-// Connect returns shim information such as the shim's pid.
-func (s *service) Connect(ctx context.Context, r *taskAPI.ConnectRequest) (*taskAPI.ConnectResponse, error) {
- log.L.Debugf("Connect, id: %s", r.ID)
-
- var pid int
- if s.task != nil {
- pid = s.task.Pid()
- }
- return &taskAPI.ConnectResponse{
- ShimPid: uint32(os.Getpid()),
- TaskPid: uint32(pid),
- }, nil
-}
-
-func (s *service) Shutdown(ctx context.Context, r *taskAPI.ShutdownRequest) (*types.Empty, error) {
- log.L.Debugf("Shutdown, id: %s", r.ID)
- s.cancel()
- if s.shimAddress != "" {
- _ = shim.RemoveSocket(s.shimAddress)
- }
- os.Exit(0)
- panic("Should not get here")
-}
-
-func (s *service) Stats(ctx context.Context, r *taskAPI.StatsRequest) (*taskAPI.StatsResponse, error) {
- log.L.Debugf("Stats, id: %s", r.ID)
- if s.task == nil {
- log.L.Debugf("Stats error, id: %s: container not created", r.ID)
- return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created")
- }
- stats, err := s.task.Runtime().Stats(ctx, s.id)
- if err != nil {
- log.L.Debugf("Stats error, id: %s: %v", r.ID, err)
- return nil, err
- }
-
- // 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
- // as runc.
- //
- // [0]: https://github.com/google/gvisor/blob/277a0d5a1fbe8272d4729c01ee4c6e374d047ebc/runsc/boot/events.go#L61-L81
- metrics := &cgroupsstats.Metrics{
- CPU: &cgroupsstats.CPUStat{
- Usage: &cgroupsstats.CPUUsage{
- Total: stats.Cpu.Usage.Total,
- Kernel: stats.Cpu.Usage.Kernel,
- User: stats.Cpu.Usage.User,
- PerCPU: stats.Cpu.Usage.Percpu,
- },
- Throttling: &cgroupsstats.Throttle{
- Periods: stats.Cpu.Throttling.Periods,
- ThrottledPeriods: stats.Cpu.Throttling.ThrottledPeriods,
- ThrottledTime: stats.Cpu.Throttling.ThrottledTime,
- },
- },
- Memory: &cgroupsstats.MemoryStat{
- Cache: stats.Memory.Cache,
- Usage: &cgroupsstats.MemoryEntry{
- Limit: stats.Memory.Usage.Limit,
- Usage: stats.Memory.Usage.Usage,
- Max: stats.Memory.Usage.Max,
- Failcnt: stats.Memory.Usage.Failcnt,
- },
- Swap: &cgroupsstats.MemoryEntry{
- Limit: stats.Memory.Swap.Limit,
- Usage: stats.Memory.Swap.Usage,
- Max: stats.Memory.Swap.Max,
- Failcnt: stats.Memory.Swap.Failcnt,
- },
- Kernel: &cgroupsstats.MemoryEntry{
- Limit: stats.Memory.Kernel.Limit,
- Usage: stats.Memory.Kernel.Usage,
- Max: stats.Memory.Kernel.Max,
- Failcnt: stats.Memory.Kernel.Failcnt,
- },
- KernelTCP: &cgroupsstats.MemoryEntry{
- Limit: stats.Memory.KernelTCP.Limit,
- Usage: stats.Memory.KernelTCP.Usage,
- Max: stats.Memory.KernelTCP.Max,
- Failcnt: stats.Memory.KernelTCP.Failcnt,
- },
- },
- Pids: &cgroupsstats.PidsStat{
- Current: stats.Pids.Current,
- Limit: stats.Pids.Limit,
- },
- }
- data, err := typeurl.MarshalAny(metrics)
- if err != nil {
- log.L.Debugf("Stats error, id: %s: %v", r.ID, err)
- return nil, err
- }
- log.L.Debugf("Stats success, id: %s: %+v", r.ID, data)
- return &taskAPI.StatsResponse{
- Stats: data,
- }, nil
-}
-
-// Update updates a running container.
-func (s *service) Update(ctx context.Context, r *taskAPI.UpdateTaskRequest) (*types.Empty, error) {
- return empty, errdefs.ToGRPC(errdefs.ErrNotImplemented)
-}
-
-// Wait waits for a process to exit.
-func (s *service) Wait(ctx context.Context, r *taskAPI.WaitRequest) (*taskAPI.WaitResponse, error) {
- log.L.Debugf("Wait, id: %s, execID: %s", r.ID, r.ExecID)
-
- p, err := s.getProcess(r.ExecID)
- if err != nil {
- return nil, err
- }
- if p == nil {
- return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created")
- }
- p.Wait()
-
- return &taskAPI.WaitResponse{
- ExitStatus: uint32(p.ExitStatus()),
- ExitedAt: p.ExitedAt(),
- }, nil
-}
-
-func (s *service) processExits(ctx context.Context) {
- for e := range s.ec {
- s.checkProcesses(ctx, e)
- }
-}
-
-func (s *service) checkProcesses(ctx context.Context, e proc.Exit) {
- // TODO(random-liu): Add `shouldKillAll` logic if container pid
- // namespace is supported.
- for _, p := range s.allProcesses() {
- if p.ID() == e.ID {
- if ip, ok := p.(*proc.Init); ok {
- // Ensure all children are killed.
- log.L.Debugf("Container init process exited, killing all container processes")
- if err := ip.KillAll(ctx); err != nil {
- log.G(ctx).WithError(err).WithField("id", ip.ID()).
- Error("failed to kill init's children")
- }
- }
- p.SetExited(e.Status)
- s.events <- &events.TaskExit{
- ContainerID: s.id,
- ID: p.ID(),
- Pid: uint32(p.Pid()),
- ExitStatus: uint32(e.Status),
- ExitedAt: p.ExitedAt(),
- }
- return
- }
- }
-}
-
-func (s *service) allProcesses() (o []process.Process) {
- s.mu.Lock()
- defer s.mu.Unlock()
- for _, p := range s.processes {
- o = append(o, p)
- }
- if s.task != nil {
- o = append(o, s.task)
- }
- return o
-}
-
-func (s *service) getContainerPids(ctx context.Context, id string) ([]uint32, error) {
- s.mu.Lock()
- p := s.task
- s.mu.Unlock()
- if p == nil {
- return nil, fmt.Errorf("container must be created: %w", errdefs.ErrFailedPrecondition)
- }
- ps, err := p.Runtime().Ps(ctx, id)
- if err != nil {
- return nil, err
- }
- pids := make([]uint32, 0, len(ps))
- for _, pid := range ps {
- pids = append(pids, uint32(pid))
- }
- return pids, nil
-}
-
-func (s *service) forward(ctx context.Context, publisher shim.Publisher) {
- for e := range s.events {
- err := publisher.Publish(ctx, getTopic(e), e)
- if err != nil {
- // Should not happen.
- panic(fmt.Errorf("post event: %w", err))
- }
- }
-}
-
-func (s *service) getProcess(execID string) (process.Process, error) {
- s.mu.Lock()
- defer s.mu.Unlock()
- if execID == "" {
- return s.task, nil
- }
- p := s.processes[execID]
- if p == nil {
- return nil, errdefs.ToGRPCf(errdefs.ErrNotFound, "process does not exist %s", execID)
- }
- return p, nil
-}
-
-func getTopic(e interface{}) string {
- switch e.(type) {
- case *events.TaskCreate:
- return runtime.TaskCreateEventTopic
- case *events.TaskStart:
- return runtime.TaskStartEventTopic
- case *events.TaskOOM:
- return runtime.TaskOOMEventTopic
- case *events.TaskExit:
- return runtime.TaskExitEventTopic
- case *events.TaskDelete:
- return runtime.TaskDeleteEventTopic
- case *events.TaskExecAdded:
- return runtime.TaskExecAddedEventTopic
- case *events.TaskExecStarted:
- return runtime.TaskExecStartedEventTopic
- default:
- log.L.Infof("no topic for type %#v", e)
- }
- return runtime.TaskUnknownTopic
-}
-
-func newInit(path, workDir, namespace string, platform stdio.Platform, r *proc.CreateConfig, options *options, rootfs string) (*proc.Init, error) {
- spec, err := utils.ReadSpec(r.Bundle)
- if err != nil {
- return nil, fmt.Errorf("read oci spec: %w", err)
- }
- if err := utils.UpdateVolumeAnnotations(r.Bundle, spec); err != nil {
- return nil, fmt.Errorf("update volume annotations: %w", err)
- }
- runsc.FormatRunscLogPath(r.ID, options.RunscConfig)
- runtime := proc.NewRunsc(options.Root, path, namespace, options.BinaryName, options.RunscConfig)
- p := proc.New(r.ID, runtime, stdio.Stdio{
- Stdin: r.Stdin,
- Stdout: r.Stdout,
- Stderr: r.Stderr,
- Terminal: r.Terminal,
- })
- p.Bundle = r.Bundle
- p.Platform = platform
- p.Rootfs = rootfs
- p.WorkDir = workDir
- p.IoUID = int(options.IoUID)
- p.IoGID = int(options.IoGID)
- p.Sandbox = specutils.SpecContainerType(spec) == specutils.ContainerTypeSandbox
- p.UserLog = utils.UserLogPath(spec)
- p.Monitor = reaper.Default
- return p, nil
-}
diff --git a/pkg/shim/v2/service_linux.go b/pkg/shim/v2/service_linux.go
deleted file mode 100644
index 1800ab90b..000000000
--- a/pkg/shim/v2/service_linux.go
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2018 The containerd Authors.
-// Copyright 2018 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build linux
-
-package v2
-
-import (
- "context"
- "fmt"
- "io"
- "sync"
- "syscall"
-
- "github.com/containerd/console"
- "github.com/containerd/fifo"
-)
-
-type linuxPlatform struct {
- epoller *console.Epoller
-}
-
-func (p *linuxPlatform) CopyConsole(ctx context.Context, console console.Console, stdin, stdout, stderr string, wg *sync.WaitGroup) (console.Console, error) {
- if p.epoller == nil {
- return nil, fmt.Errorf("uninitialized epoller")
- }
-
- epollConsole, err := p.epoller.Add(console)
- if err != nil {
- return nil, err
- }
-
- if stdin != "" {
- in, err := fifo.OpenFifo(context.Background(), stdin, syscall.O_RDONLY|syscall.O_NONBLOCK, 0)
- if err != nil {
- return nil, err
- }
- go func() {
- p := bufPool.Get().(*[]byte)
- defer bufPool.Put(p)
- io.CopyBuffer(epollConsole, in, *p)
- }()
- }
-
- outw, err := fifo.OpenFifo(ctx, stdout, syscall.O_WRONLY, 0)
- if err != nil {
- return nil, err
- }
- outr, err := fifo.OpenFifo(ctx, stdout, syscall.O_RDONLY, 0)
- if err != nil {
- return nil, err
- }
- wg.Add(1)
- go func() {
- p := bufPool.Get().(*[]byte)
- defer bufPool.Put(p)
- io.CopyBuffer(outw, epollConsole, *p)
- epollConsole.Close()
- outr.Close()
- outw.Close()
- wg.Done()
- }()
- return epollConsole, nil
-}
-
-func (p *linuxPlatform) ShutdownConsole(ctx context.Context, cons console.Console) error {
- if p.epoller == nil {
- return fmt.Errorf("uninitialized epoller")
- }
- epollConsole, ok := cons.(*console.EpollConsole)
- if !ok {
- return fmt.Errorf("expected EpollConsole, got %#v", cons)
- }
- return epollConsole.Shutdown(p.epoller.CloseConsole)
-}
-
-func (p *linuxPlatform) Close() error {
- return p.epoller.Close()
-}
-
-// initialize a single epoll fd to manage our consoles. `initPlatform` should
-// only be called once.
-func (s *service) initPlatform() error {
- if s.platform != nil {
- return nil
- }
- epoller, err := console.NewEpoller()
- if err != nil {
- return fmt.Errorf("failed to initialize epoller: %w", err)
- }
- s.platform = &linuxPlatform{
- epoller: epoller,
- }
- go epoller.Wait()
- return nil
-}
diff --git a/pkg/shim/v2/state.go b/pkg/shim/v2/state.go
deleted file mode 100644
index 1f4be33d3..000000000
--- a/pkg/shim/v2/state.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2020 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v2
-
-import (
- "encoding/json"
- "io/ioutil"
- "path/filepath"
-)
-
-const filename = "state.json"
-
-// state holds information needed between shim invocations.
-type state struct {
- // Rootfs is the full path to the location rootfs was mounted.
- Rootfs string `json:"rootfs"`
-
- // Options is the configuration loaded from config.toml.
- Options options `json:"options"`
-}
-
-func (s state) load(path string) error {
- data, err := ioutil.ReadFile(filepath.Join(path, filename))
- if err != nil {
- return err
- }
- return json.Unmarshal(data, &s)
-}
-
-func (s state) save(path string) error {
- data, err := json.Marshal(&s)
- if err != nil {
- return err
- }
- return ioutil.WriteFile(filepath.Join(path, filename), data, 0644)
-}