From e115b52ce2516ead331522c965fab93b62d4041e Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Mon, 7 Nov 2016 13:10:09 -0800 Subject: [PATCH] Remove containerd files Signed-off-by: Michael Crosby --- api/container/container.pb.go | 136 -- api/container/container.proto | 162 --- api/container/gen.go | 3 - api/grpc/server/server.go | 437 ------ api/grpc/server/server_linux.go | 56 - api/grpc/server/server_solaris.go | 14 - api/grpc/types/api.pb.go | 1607 ---------------------- api/grpc/types/api.proto | 342 ----- api/image/gen.go | 3 - api/image/image.pb.go | 295 ---- api/image/image.proto | 83 -- api/pprof/pprof.go | 18 - api/types/mount/gen.go | 5 - api/types/mount/mount.pb.go | 71 - api/types/mount/mount.proto | 27 - api/types/types.go | 2 - containerd/main.go | 161 --- containerd/utils.go | 71 - ctr/Makefile | 2 - ctr/checkpoint.go | 165 --- ctr/const.go | 10 - ctr/container.go | 684 --------- ctr/container_linux.go | 28 - ctr/container_solaris.go | 9 - ctr/events.go | 63 - ctr/main.go | 90 -- ctr/sort.go | 27 - docs/api.md | 6 - docs/attach.md | 36 - docs/bundle-changes.md | 12 - docs/bundle.md | 208 --- docs/cli.md | 159 --- docs/daemon.md | 27 - docs/telemetry.md | 31 - hack/benchmark.go | 75 - {example => hack/example}/main.go | 0 {example => hack/example}/utils.go | 0 integration-test/bundle_utils_test.go | 111 -- integration-test/check_test.go | 278 ---- integration-test/container_utils_test.go | 321 ----- integration-test/events_test.go | 63 - integration-test/exec_test.go | 187 --- integration-test/start_test.go | 538 -------- runtime/container.go | 738 ---------- runtime/container_linux.go | 174 --- runtime/container_solaris.go | 19 - runtime/process.go | 467 ------- runtime/runtime.go | 130 -- runtime/runtime_test.go | 180 --- runtime/stats.go | 87 -- specs/spec_linux.go | 12 - specs/spec_solaris.go | 8 - supervisor/add_process.go | 43 - supervisor/checkpoint.go | 37 - supervisor/create.go | 63 - supervisor/create_solaris.go | 8 - supervisor/delete.go | 44 - supervisor/errors.go | 28 - supervisor/exit.go | 87 -- supervisor/get_containers.go | 47 - supervisor/machine.go | 28 - supervisor/machine_solaris.go | 15 - supervisor/oom.go | 23 - supervisor/signal.go | 28 - supervisor/sort.go | 27 - supervisor/sort_test.go | 89 -- supervisor/stats.go | 28 - supervisor/supervisor.go | 310 ----- supervisor/task.go | 33 - supervisor/types.go | 12 - supervisor/update.go | 95 -- supervisor/utils.go | 101 -- supervisor/worker.go | 103 -- testutils/testutils.go | 70 - 74 files changed, 9757 deletions(-) delete mode 100644 api/container/container.pb.go delete mode 100644 api/container/container.proto delete mode 100644 api/container/gen.go delete mode 100644 api/grpc/server/server.go delete mode 100644 api/grpc/server/server_linux.go delete mode 100644 api/grpc/server/server_solaris.go delete mode 100644 api/grpc/types/api.pb.go delete mode 100644 api/grpc/types/api.proto delete mode 100644 api/image/gen.go delete mode 100644 api/image/image.pb.go delete mode 100644 api/image/image.proto delete mode 100644 api/pprof/pprof.go delete mode 100644 api/types/mount/gen.go delete mode 100644 api/types/mount/mount.pb.go delete mode 100644 api/types/mount/mount.proto delete mode 100644 api/types/types.go delete mode 100644 containerd/main.go delete mode 100644 containerd/utils.go delete mode 100644 ctr/Makefile delete mode 100644 ctr/checkpoint.go delete mode 100644 ctr/const.go delete mode 100644 ctr/container.go delete mode 100644 ctr/container_linux.go delete mode 100644 ctr/container_solaris.go delete mode 100644 ctr/events.go delete mode 100644 ctr/main.go delete mode 100644 ctr/sort.go delete mode 100644 docs/api.md delete mode 100644 docs/attach.md delete mode 100644 docs/bundle-changes.md delete mode 100644 docs/bundle.md delete mode 100644 docs/cli.md delete mode 100644 docs/daemon.md delete mode 100644 docs/telemetry.md delete mode 100644 hack/benchmark.go rename {example => hack/example}/main.go (100%) rename {example => hack/example}/utils.go (100%) delete mode 100644 integration-test/bundle_utils_test.go delete mode 100644 integration-test/check_test.go delete mode 100644 integration-test/container_utils_test.go delete mode 100644 integration-test/events_test.go delete mode 100644 integration-test/exec_test.go delete mode 100644 integration-test/start_test.go delete mode 100644 runtime/container.go delete mode 100644 runtime/container_linux.go delete mode 100644 runtime/container_solaris.go delete mode 100644 runtime/process.go delete mode 100644 runtime/runtime.go delete mode 100644 runtime/runtime_test.go delete mode 100644 runtime/stats.go delete mode 100644 specs/spec_linux.go delete mode 100644 specs/spec_solaris.go delete mode 100644 supervisor/add_process.go delete mode 100644 supervisor/checkpoint.go delete mode 100644 supervisor/create.go delete mode 100644 supervisor/create_solaris.go delete mode 100644 supervisor/delete.go delete mode 100644 supervisor/errors.go delete mode 100644 supervisor/exit.go delete mode 100644 supervisor/get_containers.go delete mode 100644 supervisor/machine.go delete mode 100644 supervisor/machine_solaris.go delete mode 100644 supervisor/oom.go delete mode 100644 supervisor/signal.go delete mode 100644 supervisor/sort.go delete mode 100644 supervisor/sort_test.go delete mode 100644 supervisor/stats.go delete mode 100644 supervisor/supervisor.go delete mode 100644 supervisor/task.go delete mode 100644 supervisor/types.go delete mode 100644 supervisor/update.go delete mode 100644 supervisor/utils.go delete mode 100644 supervisor/worker.go delete mode 100644 testutils/testutils.go diff --git a/api/container/container.pb.go b/api/container/container.pb.go deleted file mode 100644 index 4d9c36f..0000000 --- a/api/container/container.pb.go +++ /dev/null @@ -1,136 +0,0 @@ -// Code generated by protoc-gen-gogo. -// source: container.proto -// DO NOT EDIT! - -/* -Package container is a generated protocol buffer package. - -It is generated from these files: - container.proto - -It has these top-level messages: - Container - ContainerSpec -*/ -package container - -import proto "github.com/gogo/protobuf/proto" -import fmt "fmt" -import math "math" -import _ "github.com/gogo/protobuf/gogoproto" -import docker_containerkit_types "github.com/docker/containerkit/api/types/mount" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -const _ = proto.GoGoProtoPackageIsVersion1 - -type Container struct { - Container *ContainerSpec `protobuf:"bytes,1,opt,name=container" json:"container,omitempty"` -} - -func (m *Container) Reset() { *m = Container{} } -func (m *Container) String() string { return proto.CompactTextString(m) } -func (*Container) ProtoMessage() {} -func (*Container) Descriptor() ([]byte, []int) { return fileDescriptorContainer, []int{0} } - -func (m *Container) GetContainer() *ContainerSpec { - if m != nil { - return m.Container - } - return nil -} - -// Container specifies runtime parameters for a container. -type ContainerSpec struct { - // name must be a unique name to identify the container. - // - // This can be used as a system identifier external to ContainerKit services. - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // Labels defines labels to be added to the container at creation time. If - // collisions with system labels occur, these labels will be overridden. - // - // This field *must* remain compatible with the Labels field of - // Annotations. - Labels map[string]string `protobuf:"bytes,2,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - Mounts []docker_containerkit_types.Mount `protobuf:"bytes,3,rep,name=mounts" json:"mounts"` - // Command to run the the container. The first element is a path to the - // executable and the following elements are treated as arguments. - // - // If command is empty, execution will fall back to the image's entrypoint. - // - // Command should only be used when overriding entrypoint. - Command []string `protobuf:"bytes,4,rep,name=command" json:"command,omitempty"` - // Args specifies arguments provided to the image's entrypoint. - // - // If Command and Args are provided, Args will be appended to Command. - Args []string `protobuf:"bytes,5,rep,name=args" json:"args,omitempty"` - // Env specifies the environment variables for the container in NAME=VALUE - // format. These must be compliant with [IEEE Std - // 1003.1-2001](http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html). - Env []string `protobuf:"bytes,6,rep,name=env" json:"env,omitempty"` - // Dir defines the working directory to set for the container process. - Dir string `protobuf:"bytes,7,opt,name=dir,proto3" json:"dir,omitempty"` - // User specifies the user that should be employed to run the container. - // - // Note that the primary group may be specified by appending the group name - // or id to the user name, separated by a `:`. This syntax is - // `:`. - User string `protobuf:"bytes,8,opt,name=user,proto3" json:"user,omitempty"` - // Groups specifies supplementary groups available to the user. - Groups []string `protobuf:"bytes,9,rep,name=groups" json:"groups,omitempty"` -} - -func (m *ContainerSpec) Reset() { *m = ContainerSpec{} } -func (m *ContainerSpec) String() string { return proto.CompactTextString(m) } -func (*ContainerSpec) ProtoMessage() {} -func (*ContainerSpec) Descriptor() ([]byte, []int) { return fileDescriptorContainer, []int{1} } - -func (m *ContainerSpec) GetLabels() map[string]string { - if m != nil { - return m.Labels - } - return nil -} - -func (m *ContainerSpec) GetMounts() []docker_containerkit_types.Mount { - if m != nil { - return m.Mounts - } - return nil -} - -func init() { - proto.RegisterType((*Container)(nil), "docker.containerkit.v1.Container") - proto.RegisterType((*ContainerSpec)(nil), "docker.containerkit.v1.ContainerSpec") -} - -var fileDescriptorContainer = []byte{ - // 344 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x8c, 0x91, 0xc1, 0x4a, 0xf3, 0x40, - 0x14, 0x85, 0xff, 0x26, 0x6d, 0xfa, 0xe7, 0x16, 0x51, 0x06, 0x29, 0x43, 0x37, 0x86, 0x82, 0xd0, - 0x8d, 0x13, 0x5a, 0x37, 0xda, 0x85, 0x0b, 0x8b, 0x0b, 0x41, 0x41, 0xe2, 0x13, 0x4c, 0xd2, 0x31, - 0x86, 0x36, 0x33, 0x61, 0x32, 0x29, 0xf4, 0x0d, 0x7d, 0x0a, 0xb7, 0xbe, 0x86, 0xcc, 0x9d, 0xb4, - 0x56, 0xe8, 0xc2, 0x4d, 0x38, 0xe7, 0xe4, 0x9e, 0x2f, 0x73, 0x27, 0x70, 0x9a, 0x29, 0x69, 0x78, - 0x21, 0x85, 0x66, 0x95, 0x56, 0x46, 0x91, 0xe1, 0x52, 0x65, 0x2b, 0xa1, 0xd9, 0x3e, 0x5f, 0x15, - 0x86, 0x6d, 0xa6, 0xa3, 0xab, 0xbc, 0x30, 0xef, 0x4d, 0xca, 0x32, 0x55, 0xc6, 0xb9, 0xca, 0x55, - 0x8c, 0xe3, 0x69, 0xf3, 0x86, 0x0e, 0x0d, 0x2a, 0x87, 0x19, 0xcd, 0x0f, 0xc6, 0x1d, 0x31, 0x3e, - 0x24, 0xc6, 0xbc, 0x2a, 0x62, 0xb3, 0xad, 0x44, 0x1d, 0x97, 0xaa, 0x91, 0xc6, 0x3d, 0x5d, 0x77, - 0xfc, 0x02, 0xe1, 0x62, 0x37, 0x4b, 0x16, 0x10, 0xee, 0x8b, 0xb4, 0x13, 0x75, 0x26, 0x83, 0xd9, - 0x25, 0x3b, 0x7e, 0x46, 0xb6, 0x6f, 0xbd, 0x56, 0x22, 0x4b, 0x7e, 0x7a, 0xe3, 0x2f, 0x0f, 0x4e, - 0x7e, 0xbd, 0x24, 0x04, 0xba, 0x92, 0x97, 0x02, 0x89, 0x61, 0x82, 0x9a, 0x3c, 0x42, 0xb0, 0xe6, - 0xa9, 0x58, 0xd7, 0xd4, 0x8b, 0xfc, 0xc9, 0x60, 0x36, 0xfd, 0xd3, 0x77, 0xd8, 0x13, 0x76, 0x1e, - 0xa4, 0xd1, 0xdb, 0xa4, 0x05, 0x90, 0x3b, 0x08, 0x70, 0xa3, 0x9a, 0xfa, 0x88, 0x8a, 0x8e, 0xa2, - 0xf0, 0x02, 0xd8, 0xb3, 0x1d, 0xbc, 0xef, 0x7e, 0x7c, 0x5e, 0xfc, 0x4b, 0xda, 0x16, 0xa1, 0xd0, - 0xcf, 0x54, 0x59, 0x72, 0xb9, 0xa4, 0xdd, 0xc8, 0x9f, 0x84, 0xc9, 0xce, 0xda, 0x83, 0x73, 0x9d, - 0xd7, 0xb4, 0x87, 0x31, 0x6a, 0x72, 0x06, 0xbe, 0x90, 0x1b, 0x1a, 0x60, 0x64, 0xa5, 0x4d, 0x96, - 0x85, 0xa6, 0x7d, 0xdc, 0xce, 0x4a, 0xdb, 0x6b, 0x6a, 0xa1, 0xe9, 0x7f, 0xb7, 0xb0, 0xd5, 0x64, - 0x08, 0x41, 0xae, 0x55, 0x53, 0xd5, 0x34, 0xc4, 0x6a, 0xeb, 0x46, 0xb7, 0x30, 0x38, 0x58, 0xca, - 0xc2, 0x56, 0x62, 0xdb, 0x5e, 0x95, 0x95, 0xe4, 0x1c, 0x7a, 0x1b, 0xbe, 0x6e, 0x04, 0xf5, 0x30, - 0x73, 0x66, 0xee, 0xdd, 0x74, 0xd2, 0x00, 0x7f, 0xe1, 0xf5, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x4a, 0x36, 0x9c, 0x33, 0x58, 0x02, 0x00, 0x00, -} diff --git a/api/container/container.proto b/api/container/container.proto deleted file mode 100644 index 9ce76fe..0000000 --- a/api/container/container.proto +++ /dev/null @@ -1,162 +0,0 @@ -syntax = "proto3"; - -package docker.containerkit.v1; - -import "github.com/gogo/protobuf/gogoproto/gogo.proto"; -import "github.com/docker/containerkit/api/types/mount/mount.proto"; - -service Containers { - rpc Create(CreateRequest) returns (CreateResponse); - rpc Start(StartRequest) returns (StartResponse); - rpc Stop(StopRequest) returns (StopResponse); - rpc Delete(DeleteRequest) returns (DeleteResponse); - rpc List(ListRequest) returns (ListResponse); - rpc State(StateRequest) returns (StateResponse); - rpc Exec(ExecRequest) returns (ExecResponse); - rpc Update(UpdateRequest) returns (UpdateResponse); -} - -message Container { - ContainerSpec container = 1; - // Runtime properties go here. -} - -// Container specifies runtime parameters for a container. -message ContainerSpec { - // name must be a unique name to identify the container. - // - // This can be used as a system identifier external to ContainerKit services. - string name = 1; - - // Labels defines labels to be added to the container at creation time. If - // collisions with system labels occur, these labels will be overridden. - // - // This field *must* remain compatible with the Labels field of - // Annotations. - map labels = 2; - - repeated types.Mount mounts = 3 [(gogoproto.nullable) = false]; - - // Command to run the the container. The first element is a path to the - // executable and the following elements are treated as arguments. - // - // If command is empty, execution will fall back to the image's entrypoint. - // - // Command should only be used when overriding entrypoint. - repeated string command = 4; - - // Args specifies arguments provided to the image's entrypoint. - // - // If Command and Args are provided, Args will be appended to Command. - repeated string args = 5; - - // Env specifies the environment variables for the container in NAME=VALUE - // format. These must be compliant with [IEEE Std - // 1003.1-2001](http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html). - repeated string env = 6; - - // Dir defines the working directory to set for the container process. - string dir = 7; - - // User specifies the user that should be employed to run the container. - // - // Note that the primary group may be specified by appending the group name - // or id to the user name, separated by a `:`. This syntax is - // `:`. - string user = 8; - - // Groups specifies supplementary groups available to the user. - repeated string groups = 9; -} - -message Rlimit { - string type = 1; - uint64 soft = 2; - uint64 hard = 3; -} - -message User { - uint32 uid = 1; - uint32 gid = 2; - repeated uint32 additionalGids = 3; -} - -message CreateRequest { - string id = 1; - string image = 2; - repeated string args = 3; - repeated string env = 4; -} - -message CreateResponse { - Container container = 1; -} - -message StartRequest { - string id = 1; -} - -message StartResponse { - -} - -message StopRequest { - string id = 1; - uint32 signal = 2; - uint32 timeout = 3; -} - -message StopResponse { - -} - -message DeleteRequest { - string id = 1; -} - -message DeleteResponse { - -} - -message ListRequest { - -} - -message ListResponse { - repeated Container containers = 1; -} - -message StateRequest { - string id = 1; -} - -message StateResponse { - Container container = 1; -} - -message ExecRequest { - string id = 1; - bool terminal = 2; - User user = 3; - repeated string args = 4; - repeated string env = 5; - string cwd = 6; - string pid = 7; - repeated string capabilities = 8; - string apparmorProfile = 9; - string selinuxLabel = 10; - bool noNewPrivileges = 11; - repeated Rlimit rlimits = 12; -} - -message ExecResponse { - -} - -message UpdateRequest { - string id = 1; -} - -message UpdateResponse { - -} diff --git a/api/container/gen.go b/api/container/gen.go deleted file mode 100644 index a8df800..0000000 --- a/api/container/gen.go +++ /dev/null @@ -1,3 +0,0 @@ -package container - -//go:generate protoc -I .:../../..:$GOPATH/src --gogo_out=plugins=grpc,import_path=github.com/docker/containerkit/api/container:. container.proto diff --git a/api/grpc/server/server.go b/api/grpc/server/server.go deleted file mode 100644 index bcc7e13..0000000 --- a/api/grpc/server/server.go +++ /dev/null @@ -1,437 +0,0 @@ -package server - -import ( - "errors" - "fmt" - "syscall" - "time" - - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - - "github.com/docker/containerd" - "github.com/docker/containerd/api/grpc/types" - "github.com/docker/containerd/osutils" - "github.com/docker/containerd/runtime" - "github.com/docker/containerd/supervisor" - "github.com/golang/protobuf/ptypes" - "golang.org/x/net/context" -) - -type apiServer struct { - sv *supervisor.Supervisor -} - -// NewServer returns grpc server instance -func NewServer(sv *supervisor.Supervisor) types.APIServer { - return &apiServer{ - sv: sv, - } -} - -func (s *apiServer) GetServerVersion(ctx context.Context, c *types.GetServerVersionRequest) (*types.GetServerVersionResponse, error) { - return &types.GetServerVersionResponse{ - Major: containerd.VersionMajor, - Minor: containerd.VersionMinor, - Patch: containerd.VersionPatch, - Revision: containerd.GitCommit, - }, nil -} - -func (s *apiServer) CreateContainer(ctx context.Context, c *types.CreateContainerRequest) (*types.CreateContainerResponse, error) { - if c.BundlePath == "" { - return nil, errors.New("empty bundle path") - } - e := &supervisor.StartTask{} - e.ID = c.Id - e.BundlePath = c.BundlePath - e.Stdin = c.Stdin - e.Stdout = c.Stdout - e.Stderr = c.Stderr - e.Labels = c.Labels - e.NoPivotRoot = c.NoPivotRoot - e.Runtime = c.Runtime - e.RuntimeArgs = c.RuntimeArgs - e.StartResponse = make(chan supervisor.StartResponse, 1) - if c.Checkpoint != "" { - e.CheckpointDir = c.CheckpointDir - e.Checkpoint = &runtime.Checkpoint{ - Name: c.Checkpoint, - } - } - s.sv.SendTask(e) - if err := <-e.ErrorCh(); err != nil { - return nil, err - } - r := <-e.StartResponse - apiC, err := createAPIContainer(r.Container, false) - if err != nil { - return nil, err - } - return &types.CreateContainerResponse{ - Container: apiC, - }, nil -} - -func (s *apiServer) CreateCheckpoint(ctx context.Context, r *types.CreateCheckpointRequest) (*types.CreateCheckpointResponse, error) { - e := &supervisor.CreateCheckpointTask{} - e.ID = r.Id - e.CheckpointDir = r.CheckpointDir - e.Checkpoint = &runtime.Checkpoint{ - Name: r.Checkpoint.Name, - Exit: r.Checkpoint.Exit, - TCP: r.Checkpoint.Tcp, - UnixSockets: r.Checkpoint.UnixSockets, - Shell: r.Checkpoint.Shell, - EmptyNS: r.Checkpoint.EmptyNS, - } - - s.sv.SendTask(e) - if err := <-e.ErrorCh(); err != nil { - return nil, err - } - return &types.CreateCheckpointResponse{}, nil -} - -func (s *apiServer) DeleteCheckpoint(ctx context.Context, r *types.DeleteCheckpointRequest) (*types.DeleteCheckpointResponse, error) { - if r.Name == "" { - return nil, errors.New("checkpoint name cannot be empty") - } - e := &supervisor.DeleteCheckpointTask{} - e.ID = r.Id - e.CheckpointDir = r.CheckpointDir - e.Checkpoint = &runtime.Checkpoint{ - Name: r.Name, - } - s.sv.SendTask(e) - if err := <-e.ErrorCh(); err != nil { - return nil, err - } - return &types.DeleteCheckpointResponse{}, nil -} - -func (s *apiServer) ListCheckpoint(ctx context.Context, r *types.ListCheckpointRequest) (*types.ListCheckpointResponse, error) { - e := &supervisor.GetContainersTask{} - s.sv.SendTask(e) - if err := <-e.ErrorCh(); err != nil { - return nil, err - } - var container runtime.Container - for _, c := range e.Containers { - if c.ID() == r.Id { - container = c - break - } - } - if container == nil { - return nil, grpc.Errorf(codes.NotFound, "no such containers") - } - var out []*types.Checkpoint - checkpoints, err := container.Checkpoints(r.CheckpointDir) - if err != nil { - return nil, err - } - for _, c := range checkpoints { - out = append(out, &types.Checkpoint{ - Name: c.Name, - Tcp: c.TCP, - Shell: c.Shell, - UnixSockets: c.UnixSockets, - // TODO: figure out timestamp - //Timestamp: c.Timestamp, - }) - } - return &types.ListCheckpointResponse{Checkpoints: out}, nil -} - -func (s *apiServer) Signal(ctx context.Context, r *types.SignalRequest) (*types.SignalResponse, error) { - e := &supervisor.SignalTask{} - e.ID = r.Id - e.PID = r.Pid - e.Signal = syscall.Signal(int(r.Signal)) - s.sv.SendTask(e) - if err := <-e.ErrorCh(); err != nil { - return nil, err - } - return &types.SignalResponse{}, nil -} - -func (s *apiServer) State(ctx context.Context, r *types.StateRequest) (*types.StateResponse, error) { - - getState := func(c runtime.Container) (interface{}, error) { - return createAPIContainer(c, true) - } - - e := &supervisor.GetContainersTask{} - e.ID = r.Id - e.GetState = getState - s.sv.SendTask(e) - if err := <-e.ErrorCh(); err != nil { - return nil, err - } - m := s.sv.Machine() - state := &types.StateResponse{ - Machine: &types.Machine{ - Cpus: uint32(m.Cpus), - Memory: uint64(m.Memory), - }, - } - for idx := range e.Containers { - state.Containers = append(state.Containers, e.States[idx].(*types.Container)) - } - return state, nil -} - -func createAPIContainer(c runtime.Container, getPids bool) (*types.Container, error) { - processes, err := c.Processes() - if err != nil { - return nil, grpc.Errorf(codes.Internal, "get processes for container: "+err.Error()) - } - var procs []*types.Process - for _, p := range processes { - oldProc := p.Spec() - stdio := p.Stdio() - proc := &types.Process{ - Pid: p.ID(), - SystemPid: uint32(p.SystemPid()), - Terminal: oldProc.Terminal, - Args: oldProc.Args, - Env: oldProc.Env, - Cwd: oldProc.Cwd, - Stdin: stdio.Stdin, - Stdout: stdio.Stdout, - Stderr: stdio.Stderr, - } - proc.User = &types.User{ - Uid: oldProc.User.UID, - Gid: oldProc.User.GID, - AdditionalGids: oldProc.User.AdditionalGids, - } - proc.Capabilities = oldProc.Capabilities - proc.ApparmorProfile = oldProc.ApparmorProfile - proc.SelinuxLabel = oldProc.SelinuxLabel - proc.NoNewPrivileges = oldProc.NoNewPrivileges - for _, rl := range oldProc.Rlimits { - proc.Rlimits = append(proc.Rlimits, &types.Rlimit{ - Type: rl.Type, - Soft: rl.Soft, - Hard: rl.Hard, - }) - } - procs = append(procs, proc) - } - var pids []int - state := c.State() - if getPids && (state == runtime.Running || state == runtime.Paused) { - if pids, err = c.Pids(); err != nil { - return nil, grpc.Errorf(codes.Internal, "get all pids for container: "+err.Error()) - } - } - return &types.Container{ - Id: c.ID(), - BundlePath: c.Path(), - Processes: procs, - Labels: c.Labels(), - Status: string(state), - Pids: toUint32(pids), - Runtime: c.Runtime(), - }, nil -} - -func toUint32(its []int) []uint32 { - o := []uint32{} - for _, i := range its { - o = append(o, uint32(i)) - } - return o -} - -func (s *apiServer) UpdateContainer(ctx context.Context, r *types.UpdateContainerRequest) (*types.UpdateContainerResponse, error) { - e := &supervisor.UpdateTask{} - e.ID = r.Id - e.State = runtime.State(r.Status) - if r.Resources != nil { - rs := r.Resources - e.Resources = &runtime.Resource{} - if rs.CpuShares != 0 { - e.Resources.CPUShares = int64(rs.CpuShares) - } - if rs.BlkioWeight != 0 { - e.Resources.BlkioWeight = uint16(rs.BlkioWeight) - } - if rs.CpuPeriod != 0 { - e.Resources.CPUPeriod = int64(rs.CpuPeriod) - } - if rs.CpuQuota != 0 { - e.Resources.CPUQuota = int64(rs.CpuQuota) - } - if rs.CpusetCpus != "" { - e.Resources.CpusetCpus = rs.CpusetCpus - } - if rs.CpusetMems != "" { - e.Resources.CpusetMems = rs.CpusetMems - } - if rs.KernelMemoryLimit != 0 { - e.Resources.KernelMemory = int64(rs.KernelMemoryLimit) - } - if rs.KernelTCPMemoryLimit != 0 { - e.Resources.KernelTCPMemory = int64(rs.KernelTCPMemoryLimit) - } - if rs.MemoryLimit != 0 { - e.Resources.Memory = int64(rs.MemoryLimit) - } - if rs.MemoryReservation != 0 { - e.Resources.MemoryReservation = int64(rs.MemoryReservation) - } - if rs.MemorySwap != 0 { - e.Resources.MemorySwap = int64(rs.MemorySwap) - } - } - s.sv.SendTask(e) - if err := <-e.ErrorCh(); err != nil { - return nil, err - } - return &types.UpdateContainerResponse{}, nil -} - -func (s *apiServer) UpdateProcess(ctx context.Context, r *types.UpdateProcessRequest) (*types.UpdateProcessResponse, error) { - e := &supervisor.UpdateProcessTask{} - e.ID = r.Id - e.PID = r.Pid - e.Height = int(r.Height) - e.Width = int(r.Width) - e.CloseStdin = r.CloseStdin - s.sv.SendTask(e) - if err := <-e.ErrorCh(); err != nil { - return nil, err - } - return &types.UpdateProcessResponse{}, nil -} - -func (s *apiServer) Events(r *types.EventsRequest, stream types.API_EventsServer) error { - t := time.Time{} - if r.Timestamp != nil { - from, err := ptypes.Timestamp(r.Timestamp) - if err != nil { - return err - } - t = from - } - if r.StoredOnly && t.IsZero() { - return fmt.Errorf("invalid parameter: StoredOnly cannot be specified without setting a valid Timestamp") - } - events := s.sv.Events(t, r.StoredOnly, r.Id) - defer s.sv.Unsubscribe(events) - for e := range events { - tsp, err := ptypes.TimestampProto(e.Timestamp) - if err != nil { - return err - } - if r.Id == "" || e.ID == r.Id { - if err := stream.Send(&types.Event{ - Id: e.ID, - Type: e.Type, - Timestamp: tsp, - Pid: e.PID, - Status: uint32(e.Status), - }); err != nil { - return err - } - } - } - return nil -} - -func convertToPb(st *runtime.Stat) *types.StatsResponse { - tsp, _ := ptypes.TimestampProto(st.Timestamp) - pbSt := &types.StatsResponse{ - Timestamp: tsp, - CgroupStats: &types.CgroupStats{}, - } - systemUsage, _ := osutils.GetSystemCPUUsage() - pbSt.CgroupStats.CpuStats = &types.CpuStats{ - CpuUsage: &types.CpuUsage{ - TotalUsage: st.CPU.Usage.Total, - PercpuUsage: st.CPU.Usage.Percpu, - UsageInKernelmode: st.CPU.Usage.Kernel, - UsageInUsermode: st.CPU.Usage.User, - }, - ThrottlingData: &types.ThrottlingData{ - Periods: st.CPU.Throttling.Periods, - ThrottledPeriods: st.CPU.Throttling.ThrottledPeriods, - ThrottledTime: st.CPU.Throttling.ThrottledTime, - }, - SystemUsage: systemUsage, - } - pbSt.CgroupStats.MemoryStats = &types.MemoryStats{ - Cache: st.Memory.Cache, - Usage: &types.MemoryData{ - Usage: st.Memory.Usage.Usage, - MaxUsage: st.Memory.Usage.Max, - Failcnt: st.Memory.Usage.Failcnt, - Limit: st.Memory.Usage.Limit, - }, - SwapUsage: &types.MemoryData{ - Usage: st.Memory.Swap.Usage, - MaxUsage: st.Memory.Swap.Max, - Failcnt: st.Memory.Swap.Failcnt, - Limit: st.Memory.Swap.Limit, - }, - KernelUsage: &types.MemoryData{ - Usage: st.Memory.Kernel.Usage, - MaxUsage: st.Memory.Kernel.Max, - Failcnt: st.Memory.Kernel.Failcnt, - Limit: st.Memory.Kernel.Limit, - }, - Stats: st.Memory.Raw, - } - pbSt.CgroupStats.BlkioStats = &types.BlkioStats{ - IoServiceBytesRecursive: convertBlkioEntryToPb(st.Blkio.IoServiceBytesRecursive), - IoServicedRecursive: convertBlkioEntryToPb(st.Blkio.IoServicedRecursive), - IoQueuedRecursive: convertBlkioEntryToPb(st.Blkio.IoQueuedRecursive), - IoServiceTimeRecursive: convertBlkioEntryToPb(st.Blkio.IoServiceTimeRecursive), - IoWaitTimeRecursive: convertBlkioEntryToPb(st.Blkio.IoWaitTimeRecursive), - IoMergedRecursive: convertBlkioEntryToPb(st.Blkio.IoMergedRecursive), - IoTimeRecursive: convertBlkioEntryToPb(st.Blkio.IoTimeRecursive), - SectorsRecursive: convertBlkioEntryToPb(st.Blkio.SectorsRecursive), - } - pbSt.CgroupStats.HugetlbStats = make(map[string]*types.HugetlbStats) - for k, st := range st.Hugetlb { - pbSt.CgroupStats.HugetlbStats[k] = &types.HugetlbStats{ - Usage: st.Usage, - MaxUsage: st.Max, - Failcnt: st.Failcnt, - } - } - pbSt.CgroupStats.PidsStats = &types.PidsStats{ - Current: st.Pids.Current, - Limit: st.Pids.Limit, - } - return pbSt -} - -func convertBlkioEntryToPb(b []runtime.BlkioEntry) []*types.BlkioStatsEntry { - var pbEs []*types.BlkioStatsEntry - for _, e := range b { - pbEs = append(pbEs, &types.BlkioStatsEntry{ - Major: e.Major, - Minor: e.Minor, - Op: e.Op, - Value: e.Value, - }) - } - return pbEs -} - -func (s *apiServer) Stats(ctx context.Context, r *types.StatsRequest) (*types.StatsResponse, error) { - e := &supervisor.StatsTask{} - e.ID = r.Id - e.Stat = make(chan *runtime.Stat, 1) - s.sv.SendTask(e) - if err := <-e.ErrorCh(); err != nil { - return nil, err - } - stats := <-e.Stat - t := convertToPb(stats) - return t, nil -} diff --git a/api/grpc/server/server_linux.go b/api/grpc/server/server_linux.go deleted file mode 100644 index 4e9b43b..0000000 --- a/api/grpc/server/server_linux.go +++ /dev/null @@ -1,56 +0,0 @@ -package server - -import ( - "fmt" - - "github.com/docker/containerd/api/grpc/types" - "github.com/docker/containerd/specs" - "github.com/docker/containerd/supervisor" - ocs "github.com/opencontainers/runtime-spec/specs-go" - "golang.org/x/net/context" -) - -func (s *apiServer) AddProcess(ctx context.Context, r *types.AddProcessRequest) (*types.AddProcessResponse, error) { - process := &specs.ProcessSpec{ - Terminal: r.Terminal, - Args: r.Args, - Env: r.Env, - Cwd: r.Cwd, - } - process.User = ocs.User{ - UID: r.User.Uid, - GID: r.User.Gid, - AdditionalGids: r.User.AdditionalGids, - } - process.Capabilities = r.Capabilities - process.ApparmorProfile = r.ApparmorProfile - process.SelinuxLabel = r.SelinuxLabel - process.NoNewPrivileges = r.NoNewPrivileges - for _, rl := range r.Rlimits { - process.Rlimits = append(process.Rlimits, ocs.Rlimit{ - Type: rl.Type, - Soft: rl.Soft, - Hard: rl.Hard, - }) - } - if r.Id == "" { - return nil, fmt.Errorf("container id cannot be empty") - } - if r.Pid == "" { - return nil, fmt.Errorf("process id cannot be empty") - } - e := &supervisor.AddProcessTask{} - e.ID = r.Id - e.PID = r.Pid - e.ProcessSpec = process - e.Stdin = r.Stdin - e.Stdout = r.Stdout - e.Stderr = r.Stderr - e.StartResponse = make(chan supervisor.StartResponse, 1) - s.sv.SendTask(e) - if err := <-e.ErrorCh(); err != nil { - return nil, err - } - <-e.StartResponse - return &types.AddProcessResponse{}, nil -} diff --git a/api/grpc/server/server_solaris.go b/api/grpc/server/server_solaris.go deleted file mode 100644 index bf64b9a..0000000 --- a/api/grpc/server/server_solaris.go +++ /dev/null @@ -1,14 +0,0 @@ -package server - -import ( - "errors" - - "github.com/docker/containerd/api/grpc/types" - "golang.org/x/net/context" -) - -var clockTicksPerSecond uint64 - -func (s *apiServer) AddProcess(ctx context.Context, r *types.AddProcessRequest) (*types.AddProcessResponse, error) { - return &types.AddProcessResponse{}, errors.New("apiServer AddProcess() not implemented on Solaris") -} diff --git a/api/grpc/types/api.pb.go b/api/grpc/types/api.pb.go deleted file mode 100644 index 2d09d51..0000000 --- a/api/grpc/types/api.pb.go +++ /dev/null @@ -1,1607 +0,0 @@ -// Code generated by protoc-gen-go. -// source: api.proto -// DO NOT EDIT! - -/* -Package types is a generated protocol buffer package. - -It is generated from these files: - api.proto - -It has these top-level messages: - GetServerVersionRequest - GetServerVersionResponse - UpdateProcessRequest - UpdateProcessResponse - CreateContainerRequest - CreateContainerResponse - SignalRequest - SignalResponse - AddProcessRequest - Rlimit - User - AddProcessResponse - CreateCheckpointRequest - CreateCheckpointResponse - DeleteCheckpointRequest - DeleteCheckpointResponse - ListCheckpointRequest - Checkpoint - ListCheckpointResponse - StateRequest - ContainerState - Process - Container - Machine - StateResponse - UpdateContainerRequest - UpdateResource - BlockIODevice - WeightDevice - ThrottleDevice - UpdateContainerResponse - EventsRequest - Event - NetworkStats - CpuUsage - ThrottlingData - CpuStats - PidsStats - MemoryData - MemoryStats - BlkioStatsEntry - BlkioStats - HugetlbStats - CgroupStats - StatsResponse - StatsRequest -*/ -package types - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import google_protobuf "github.com/golang/protobuf/ptypes/timestamp" - -import ( - context "golang.org/x/net/context" - grpc "google.golang.org/grpc" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// 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.ProtoPackageIsVersion2 // please upgrade the proto package - -type GetServerVersionRequest struct { -} - -func (m *GetServerVersionRequest) Reset() { *m = GetServerVersionRequest{} } -func (m *GetServerVersionRequest) String() string { return proto.CompactTextString(m) } -func (*GetServerVersionRequest) ProtoMessage() {} -func (*GetServerVersionRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } - -type GetServerVersionResponse struct { - Major uint32 `protobuf:"varint,1,opt,name=major" json:"major,omitempty"` - Minor uint32 `protobuf:"varint,2,opt,name=minor" json:"minor,omitempty"` - Patch uint32 `protobuf:"varint,3,opt,name=patch" json:"patch,omitempty"` - Revision string `protobuf:"bytes,4,opt,name=revision" json:"revision,omitempty"` -} - -func (m *GetServerVersionResponse) Reset() { *m = GetServerVersionResponse{} } -func (m *GetServerVersionResponse) String() string { return proto.CompactTextString(m) } -func (*GetServerVersionResponse) ProtoMessage() {} -func (*GetServerVersionResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } - -type UpdateProcessRequest struct { - Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - Pid string `protobuf:"bytes,2,opt,name=pid" json:"pid,omitempty"` - CloseStdin bool `protobuf:"varint,3,opt,name=closeStdin" json:"closeStdin,omitempty"` - Width uint32 `protobuf:"varint,4,opt,name=width" json:"width,omitempty"` - Height uint32 `protobuf:"varint,5,opt,name=height" json:"height,omitempty"` -} - -func (m *UpdateProcessRequest) Reset() { *m = UpdateProcessRequest{} } -func (m *UpdateProcessRequest) String() string { return proto.CompactTextString(m) } -func (*UpdateProcessRequest) ProtoMessage() {} -func (*UpdateProcessRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } - -type UpdateProcessResponse struct { -} - -func (m *UpdateProcessResponse) Reset() { *m = UpdateProcessResponse{} } -func (m *UpdateProcessResponse) String() string { return proto.CompactTextString(m) } -func (*UpdateProcessResponse) ProtoMessage() {} -func (*UpdateProcessResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } - -type CreateContainerRequest struct { - Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - BundlePath string `protobuf:"bytes,2,opt,name=bundlePath" json:"bundlePath,omitempty"` - Checkpoint string `protobuf:"bytes,3,opt,name=checkpoint" json:"checkpoint,omitempty"` - Stdin string `protobuf:"bytes,4,opt,name=stdin" json:"stdin,omitempty"` - Stdout string `protobuf:"bytes,5,opt,name=stdout" json:"stdout,omitempty"` - Stderr string `protobuf:"bytes,6,opt,name=stderr" json:"stderr,omitempty"` - Labels []string `protobuf:"bytes,7,rep,name=labels" json:"labels,omitempty"` - NoPivotRoot bool `protobuf:"varint,8,opt,name=noPivotRoot" json:"noPivotRoot,omitempty"` - Runtime string `protobuf:"bytes,9,opt,name=runtime" json:"runtime,omitempty"` - RuntimeArgs []string `protobuf:"bytes,10,rep,name=runtimeArgs" json:"runtimeArgs,omitempty"` - CheckpointDir string `protobuf:"bytes,11,opt,name=checkpointDir" json:"checkpointDir,omitempty"` -} - -func (m *CreateContainerRequest) Reset() { *m = CreateContainerRequest{} } -func (m *CreateContainerRequest) String() string { return proto.CompactTextString(m) } -func (*CreateContainerRequest) ProtoMessage() {} -func (*CreateContainerRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } - -type CreateContainerResponse struct { - Container *Container `protobuf:"bytes,1,opt,name=container" json:"container,omitempty"` -} - -func (m *CreateContainerResponse) Reset() { *m = CreateContainerResponse{} } -func (m *CreateContainerResponse) String() string { return proto.CompactTextString(m) } -func (*CreateContainerResponse) ProtoMessage() {} -func (*CreateContainerResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } - -func (m *CreateContainerResponse) GetContainer() *Container { - if m != nil { - return m.Container - } - return nil -} - -type SignalRequest struct { - Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - Pid string `protobuf:"bytes,2,opt,name=pid" json:"pid,omitempty"` - Signal uint32 `protobuf:"varint,3,opt,name=signal" json:"signal,omitempty"` -} - -func (m *SignalRequest) Reset() { *m = SignalRequest{} } -func (m *SignalRequest) String() string { return proto.CompactTextString(m) } -func (*SignalRequest) ProtoMessage() {} -func (*SignalRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } - -type SignalResponse struct { -} - -func (m *SignalResponse) Reset() { *m = SignalResponse{} } -func (m *SignalResponse) String() string { return proto.CompactTextString(m) } -func (*SignalResponse) ProtoMessage() {} -func (*SignalResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } - -type AddProcessRequest struct { - Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - Terminal bool `protobuf:"varint,2,opt,name=terminal" json:"terminal,omitempty"` - User *User `protobuf:"bytes,3,opt,name=user" json:"user,omitempty"` - Args []string `protobuf:"bytes,4,rep,name=args" json:"args,omitempty"` - Env []string `protobuf:"bytes,5,rep,name=env" json:"env,omitempty"` - Cwd string `protobuf:"bytes,6,opt,name=cwd" json:"cwd,omitempty"` - Pid string `protobuf:"bytes,7,opt,name=pid" json:"pid,omitempty"` - Stdin string `protobuf:"bytes,8,opt,name=stdin" json:"stdin,omitempty"` - Stdout string `protobuf:"bytes,9,opt,name=stdout" json:"stdout,omitempty"` - Stderr string `protobuf:"bytes,10,opt,name=stderr" json:"stderr,omitempty"` - Capabilities []string `protobuf:"bytes,11,rep,name=capabilities" json:"capabilities,omitempty"` - ApparmorProfile string `protobuf:"bytes,12,opt,name=apparmorProfile" json:"apparmorProfile,omitempty"` - SelinuxLabel string `protobuf:"bytes,13,opt,name=selinuxLabel" json:"selinuxLabel,omitempty"` - NoNewPrivileges bool `protobuf:"varint,14,opt,name=noNewPrivileges" json:"noNewPrivileges,omitempty"` - Rlimits []*Rlimit `protobuf:"bytes,15,rep,name=rlimits" json:"rlimits,omitempty"` -} - -func (m *AddProcessRequest) Reset() { *m = AddProcessRequest{} } -func (m *AddProcessRequest) String() string { return proto.CompactTextString(m) } -func (*AddProcessRequest) ProtoMessage() {} -func (*AddProcessRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } - -func (m *AddProcessRequest) GetUser() *User { - if m != nil { - return m.User - } - return nil -} - -func (m *AddProcessRequest) GetRlimits() []*Rlimit { - if m != nil { - return m.Rlimits - } - return nil -} - -type Rlimit struct { - Type string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"` - Soft uint64 `protobuf:"varint,2,opt,name=soft" json:"soft,omitempty"` - Hard uint64 `protobuf:"varint,3,opt,name=hard" json:"hard,omitempty"` -} - -func (m *Rlimit) Reset() { *m = Rlimit{} } -func (m *Rlimit) String() string { return proto.CompactTextString(m) } -func (*Rlimit) ProtoMessage() {} -func (*Rlimit) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } - -type User struct { - Uid uint32 `protobuf:"varint,1,opt,name=uid" json:"uid,omitempty"` - Gid uint32 `protobuf:"varint,2,opt,name=gid" json:"gid,omitempty"` - AdditionalGids []uint32 `protobuf:"varint,3,rep,packed,name=additionalGids" json:"additionalGids,omitempty"` -} - -func (m *User) Reset() { *m = User{} } -func (m *User) String() string { return proto.CompactTextString(m) } -func (*User) ProtoMessage() {} -func (*User) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } - -type AddProcessResponse struct { -} - -func (m *AddProcessResponse) Reset() { *m = AddProcessResponse{} } -func (m *AddProcessResponse) String() string { return proto.CompactTextString(m) } -func (*AddProcessResponse) ProtoMessage() {} -func (*AddProcessResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } - -type CreateCheckpointRequest struct { - Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - Checkpoint *Checkpoint `protobuf:"bytes,2,opt,name=checkpoint" json:"checkpoint,omitempty"` - CheckpointDir string `protobuf:"bytes,3,opt,name=checkpointDir" json:"checkpointDir,omitempty"` -} - -func (m *CreateCheckpointRequest) Reset() { *m = CreateCheckpointRequest{} } -func (m *CreateCheckpointRequest) String() string { return proto.CompactTextString(m) } -func (*CreateCheckpointRequest) ProtoMessage() {} -func (*CreateCheckpointRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } - -func (m *CreateCheckpointRequest) GetCheckpoint() *Checkpoint { - if m != nil { - return m.Checkpoint - } - return nil -} - -type CreateCheckpointResponse struct { -} - -func (m *CreateCheckpointResponse) Reset() { *m = CreateCheckpointResponse{} } -func (m *CreateCheckpointResponse) String() string { return proto.CompactTextString(m) } -func (*CreateCheckpointResponse) ProtoMessage() {} -func (*CreateCheckpointResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } - -type DeleteCheckpointRequest struct { - Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` - CheckpointDir string `protobuf:"bytes,3,opt,name=checkpointDir" json:"checkpointDir,omitempty"` -} - -func (m *DeleteCheckpointRequest) Reset() { *m = DeleteCheckpointRequest{} } -func (m *DeleteCheckpointRequest) String() string { return proto.CompactTextString(m) } -func (*DeleteCheckpointRequest) ProtoMessage() {} -func (*DeleteCheckpointRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} } - -type DeleteCheckpointResponse struct { -} - -func (m *DeleteCheckpointResponse) Reset() { *m = DeleteCheckpointResponse{} } -func (m *DeleteCheckpointResponse) String() string { return proto.CompactTextString(m) } -func (*DeleteCheckpointResponse) ProtoMessage() {} -func (*DeleteCheckpointResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} } - -type ListCheckpointRequest struct { - Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - CheckpointDir string `protobuf:"bytes,2,opt,name=checkpointDir" json:"checkpointDir,omitempty"` -} - -func (m *ListCheckpointRequest) Reset() { *m = ListCheckpointRequest{} } -func (m *ListCheckpointRequest) String() string { return proto.CompactTextString(m) } -func (*ListCheckpointRequest) ProtoMessage() {} -func (*ListCheckpointRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} } - -type Checkpoint struct { - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - Exit bool `protobuf:"varint,2,opt,name=exit" json:"exit,omitempty"` - Tcp bool `protobuf:"varint,3,opt,name=tcp" json:"tcp,omitempty"` - UnixSockets bool `protobuf:"varint,4,opt,name=unixSockets" json:"unixSockets,omitempty"` - Shell bool `protobuf:"varint,5,opt,name=shell" json:"shell,omitempty"` - EmptyNS []string `protobuf:"bytes,6,rep,name=emptyNS" json:"emptyNS,omitempty"` -} - -func (m *Checkpoint) Reset() { *m = Checkpoint{} } -func (m *Checkpoint) String() string { return proto.CompactTextString(m) } -func (*Checkpoint) ProtoMessage() {} -func (*Checkpoint) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} } - -type ListCheckpointResponse struct { - Checkpoints []*Checkpoint `protobuf:"bytes,1,rep,name=checkpoints" json:"checkpoints,omitempty"` -} - -func (m *ListCheckpointResponse) Reset() { *m = ListCheckpointResponse{} } -func (m *ListCheckpointResponse) String() string { return proto.CompactTextString(m) } -func (*ListCheckpointResponse) ProtoMessage() {} -func (*ListCheckpointResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} } - -func (m *ListCheckpointResponse) GetCheckpoints() []*Checkpoint { - if m != nil { - return m.Checkpoints - } - return nil -} - -type StateRequest struct { - Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` -} - -func (m *StateRequest) Reset() { *m = StateRequest{} } -func (m *StateRequest) String() string { return proto.CompactTextString(m) } -func (*StateRequest) ProtoMessage() {} -func (*StateRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} } - -type ContainerState struct { - Status string `protobuf:"bytes,1,opt,name=status" json:"status,omitempty"` -} - -func (m *ContainerState) Reset() { *m = ContainerState{} } -func (m *ContainerState) String() string { return proto.CompactTextString(m) } -func (*ContainerState) ProtoMessage() {} -func (*ContainerState) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} } - -type Process struct { - Pid string `protobuf:"bytes,1,opt,name=pid" json:"pid,omitempty"` - Terminal bool `protobuf:"varint,2,opt,name=terminal" json:"terminal,omitempty"` - User *User `protobuf:"bytes,3,opt,name=user" json:"user,omitempty"` - Args []string `protobuf:"bytes,4,rep,name=args" json:"args,omitempty"` - Env []string `protobuf:"bytes,5,rep,name=env" json:"env,omitempty"` - Cwd string `protobuf:"bytes,6,opt,name=cwd" json:"cwd,omitempty"` - SystemPid uint32 `protobuf:"varint,7,opt,name=systemPid" json:"systemPid,omitempty"` - Stdin string `protobuf:"bytes,8,opt,name=stdin" json:"stdin,omitempty"` - Stdout string `protobuf:"bytes,9,opt,name=stdout" json:"stdout,omitempty"` - Stderr string `protobuf:"bytes,10,opt,name=stderr" json:"stderr,omitempty"` - Capabilities []string `protobuf:"bytes,11,rep,name=capabilities" json:"capabilities,omitempty"` - ApparmorProfile string `protobuf:"bytes,12,opt,name=apparmorProfile" json:"apparmorProfile,omitempty"` - SelinuxLabel string `protobuf:"bytes,13,opt,name=selinuxLabel" json:"selinuxLabel,omitempty"` - NoNewPrivileges bool `protobuf:"varint,14,opt,name=noNewPrivileges" json:"noNewPrivileges,omitempty"` - Rlimits []*Rlimit `protobuf:"bytes,15,rep,name=rlimits" json:"rlimits,omitempty"` -} - -func (m *Process) Reset() { *m = Process{} } -func (m *Process) String() string { return proto.CompactTextString(m) } -func (*Process) ProtoMessage() {} -func (*Process) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{21} } - -func (m *Process) GetUser() *User { - if m != nil { - return m.User - } - return nil -} - -func (m *Process) GetRlimits() []*Rlimit { - if m != nil { - return m.Rlimits - } - return nil -} - -type Container struct { - Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - BundlePath string `protobuf:"bytes,2,opt,name=bundlePath" json:"bundlePath,omitempty"` - Processes []*Process `protobuf:"bytes,3,rep,name=processes" json:"processes,omitempty"` - Status string `protobuf:"bytes,4,opt,name=status" json:"status,omitempty"` - Labels []string `protobuf:"bytes,5,rep,name=labels" json:"labels,omitempty"` - Pids []uint32 `protobuf:"varint,6,rep,packed,name=pids" json:"pids,omitempty"` - Runtime string `protobuf:"bytes,7,opt,name=runtime" json:"runtime,omitempty"` -} - -func (m *Container) Reset() { *m = Container{} } -func (m *Container) String() string { return proto.CompactTextString(m) } -func (*Container) ProtoMessage() {} -func (*Container) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22} } - -func (m *Container) GetProcesses() []*Process { - if m != nil { - return m.Processes - } - return nil -} - -// Machine is information about machine on which containerd is run -type Machine struct { - Cpus uint32 `protobuf:"varint,1,opt,name=cpus" json:"cpus,omitempty"` - Memory uint64 `protobuf:"varint,2,opt,name=memory" json:"memory,omitempty"` -} - -func (m *Machine) Reset() { *m = Machine{} } -func (m *Machine) String() string { return proto.CompactTextString(m) } -func (*Machine) ProtoMessage() {} -func (*Machine) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} } - -// StateResponse is information about containerd daemon -type StateResponse struct { - Containers []*Container `protobuf:"bytes,1,rep,name=containers" json:"containers,omitempty"` - Machine *Machine `protobuf:"bytes,2,opt,name=machine" json:"machine,omitempty"` -} - -func (m *StateResponse) Reset() { *m = StateResponse{} } -func (m *StateResponse) String() string { return proto.CompactTextString(m) } -func (*StateResponse) ProtoMessage() {} -func (*StateResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} } - -func (m *StateResponse) GetContainers() []*Container { - if m != nil { - return m.Containers - } - return nil -} - -func (m *StateResponse) GetMachine() *Machine { - if m != nil { - return m.Machine - } - return nil -} - -type UpdateContainerRequest struct { - Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - Pid string `protobuf:"bytes,2,opt,name=pid" json:"pid,omitempty"` - Status string `protobuf:"bytes,3,opt,name=status" json:"status,omitempty"` - Resources *UpdateResource `protobuf:"bytes,4,opt,name=resources" json:"resources,omitempty"` -} - -func (m *UpdateContainerRequest) Reset() { *m = UpdateContainerRequest{} } -func (m *UpdateContainerRequest) String() string { return proto.CompactTextString(m) } -func (*UpdateContainerRequest) ProtoMessage() {} -func (*UpdateContainerRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{25} } - -func (m *UpdateContainerRequest) GetResources() *UpdateResource { - if m != nil { - return m.Resources - } - return nil -} - -type UpdateResource struct { - BlkioWeight uint64 `protobuf:"varint,1,opt,name=blkioWeight" json:"blkioWeight,omitempty"` - CpuShares uint64 `protobuf:"varint,2,opt,name=cpuShares" json:"cpuShares,omitempty"` - CpuPeriod uint64 `protobuf:"varint,3,opt,name=cpuPeriod" json:"cpuPeriod,omitempty"` - CpuQuota uint64 `protobuf:"varint,4,opt,name=cpuQuota" json:"cpuQuota,omitempty"` - CpusetCpus string `protobuf:"bytes,5,opt,name=cpusetCpus" json:"cpusetCpus,omitempty"` - CpusetMems string `protobuf:"bytes,6,opt,name=cpusetMems" json:"cpusetMems,omitempty"` - MemoryLimit uint64 `protobuf:"varint,7,opt,name=memoryLimit" json:"memoryLimit,omitempty"` - MemorySwap uint64 `protobuf:"varint,8,opt,name=memorySwap" json:"memorySwap,omitempty"` - MemoryReservation uint64 `protobuf:"varint,9,opt,name=memoryReservation" json:"memoryReservation,omitempty"` - KernelMemoryLimit uint64 `protobuf:"varint,10,opt,name=kernelMemoryLimit" json:"kernelMemoryLimit,omitempty"` - KernelTCPMemoryLimit uint64 `protobuf:"varint,11,opt,name=kernelTCPMemoryLimit" json:"kernelTCPMemoryLimit,omitempty"` - BlkioLeafWeight uint64 `protobuf:"varint,12,opt,name=blkioLeafWeight" json:"blkioLeafWeight,omitempty"` - BlkioWeightDevice []*WeightDevice `protobuf:"bytes,13,rep,name=blkioWeightDevice" json:"blkioWeightDevice,omitempty"` - BlkioThrottleReadBpsDevice []*ThrottleDevice `protobuf:"bytes,14,rep,name=blkioThrottleReadBpsDevice" json:"blkioThrottleReadBpsDevice,omitempty"` - BlkioThrottleWriteBpsDevice []*ThrottleDevice `protobuf:"bytes,15,rep,name=blkioThrottleWriteBpsDevice" json:"blkioThrottleWriteBpsDevice,omitempty"` - BlkioThrottleReadIopsDevice []*ThrottleDevice `protobuf:"bytes,16,rep,name=blkioThrottleReadIopsDevice" json:"blkioThrottleReadIopsDevice,omitempty"` - BlkioThrottleWriteIopsDevice []*ThrottleDevice `protobuf:"bytes,17,rep,name=blkioThrottleWriteIopsDevice" json:"blkioThrottleWriteIopsDevice,omitempty"` -} - -func (m *UpdateResource) Reset() { *m = UpdateResource{} } -func (m *UpdateResource) String() string { return proto.CompactTextString(m) } -func (*UpdateResource) ProtoMessage() {} -func (*UpdateResource) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{26} } - -func (m *UpdateResource) GetBlkioWeightDevice() []*WeightDevice { - if m != nil { - return m.BlkioWeightDevice - } - return nil -} - -func (m *UpdateResource) GetBlkioThrottleReadBpsDevice() []*ThrottleDevice { - if m != nil { - return m.BlkioThrottleReadBpsDevice - } - return nil -} - -func (m *UpdateResource) GetBlkioThrottleWriteBpsDevice() []*ThrottleDevice { - if m != nil { - return m.BlkioThrottleWriteBpsDevice - } - return nil -} - -func (m *UpdateResource) GetBlkioThrottleReadIopsDevice() []*ThrottleDevice { - if m != nil { - return m.BlkioThrottleReadIopsDevice - } - return nil -} - -func (m *UpdateResource) GetBlkioThrottleWriteIopsDevice() []*ThrottleDevice { - if m != nil { - return m.BlkioThrottleWriteIopsDevice - } - return nil -} - -type BlockIODevice struct { - Major int64 `protobuf:"varint,1,opt,name=major" json:"major,omitempty"` - Minor int64 `protobuf:"varint,2,opt,name=minor" json:"minor,omitempty"` -} - -func (m *BlockIODevice) Reset() { *m = BlockIODevice{} } -func (m *BlockIODevice) String() string { return proto.CompactTextString(m) } -func (*BlockIODevice) ProtoMessage() {} -func (*BlockIODevice) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{27} } - -type WeightDevice struct { - BlkIODevice *BlockIODevice `protobuf:"bytes,1,opt,name=blkIODevice" json:"blkIODevice,omitempty"` - Weight uint32 `protobuf:"varint,2,opt,name=weight" json:"weight,omitempty"` - LeafWeight uint32 `protobuf:"varint,3,opt,name=leafWeight" json:"leafWeight,omitempty"` -} - -func (m *WeightDevice) Reset() { *m = WeightDevice{} } -func (m *WeightDevice) String() string { return proto.CompactTextString(m) } -func (*WeightDevice) ProtoMessage() {} -func (*WeightDevice) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{28} } - -func (m *WeightDevice) GetBlkIODevice() *BlockIODevice { - if m != nil { - return m.BlkIODevice - } - return nil -} - -type ThrottleDevice struct { - BlkIODevice *BlockIODevice `protobuf:"bytes,1,opt,name=blkIODevice" json:"blkIODevice,omitempty"` - Rate uint64 `protobuf:"varint,2,opt,name=rate" json:"rate,omitempty"` -} - -func (m *ThrottleDevice) Reset() { *m = ThrottleDevice{} } -func (m *ThrottleDevice) String() string { return proto.CompactTextString(m) } -func (*ThrottleDevice) ProtoMessage() {} -func (*ThrottleDevice) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{29} } - -func (m *ThrottleDevice) GetBlkIODevice() *BlockIODevice { - if m != nil { - return m.BlkIODevice - } - return nil -} - -type UpdateContainerResponse struct { -} - -func (m *UpdateContainerResponse) Reset() { *m = UpdateContainerResponse{} } -func (m *UpdateContainerResponse) String() string { return proto.CompactTextString(m) } -func (*UpdateContainerResponse) ProtoMessage() {} -func (*UpdateContainerResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{30} } - -type EventsRequest struct { - // Tag 1 is deprecated (old uint64 timestamp) - Timestamp *google_protobuf.Timestamp `protobuf:"bytes,2,opt,name=timestamp" json:"timestamp,omitempty"` - StoredOnly bool `protobuf:"varint,3,opt,name=storedOnly" json:"storedOnly,omitempty"` - Id string `protobuf:"bytes,4,opt,name=id" json:"id,omitempty"` -} - -func (m *EventsRequest) Reset() { *m = EventsRequest{} } -func (m *EventsRequest) String() string { return proto.CompactTextString(m) } -func (*EventsRequest) ProtoMessage() {} -func (*EventsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{31} } - -func (m *EventsRequest) GetTimestamp() *google_protobuf.Timestamp { - if m != nil { - return m.Timestamp - } - return nil -} - -type Event struct { - Type string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"` - Id string `protobuf:"bytes,2,opt,name=id" json:"id,omitempty"` - Status uint32 `protobuf:"varint,3,opt,name=status" json:"status,omitempty"` - Pid string `protobuf:"bytes,4,opt,name=pid" json:"pid,omitempty"` - // Tag 5 is deprecated (old uint64 timestamp) - Timestamp *google_protobuf.Timestamp `protobuf:"bytes,6,opt,name=timestamp" json:"timestamp,omitempty"` -} - -func (m *Event) Reset() { *m = Event{} } -func (m *Event) String() string { return proto.CompactTextString(m) } -func (*Event) ProtoMessage() {} -func (*Event) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{32} } - -func (m *Event) GetTimestamp() *google_protobuf.Timestamp { - if m != nil { - return m.Timestamp - } - return nil -} - -type NetworkStats struct { - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - RxBytes uint64 `protobuf:"varint,2,opt,name=rx_bytes,json=rxBytes" json:"rx_bytes,omitempty"` - Rx_Packets uint64 `protobuf:"varint,3,opt,name=rx_Packets,json=rxPackets" json:"rx_Packets,omitempty"` - RxErrors uint64 `protobuf:"varint,4,opt,name=Rx_errors,json=rxErrors" json:"Rx_errors,omitempty"` - RxDropped uint64 `protobuf:"varint,5,opt,name=Rx_dropped,json=rxDropped" json:"Rx_dropped,omitempty"` - TxBytes uint64 `protobuf:"varint,6,opt,name=Tx_bytes,json=txBytes" json:"Tx_bytes,omitempty"` - TxPackets uint64 `protobuf:"varint,7,opt,name=Tx_packets,json=txPackets" json:"Tx_packets,omitempty"` - TxErrors uint64 `protobuf:"varint,8,opt,name=Tx_errors,json=txErrors" json:"Tx_errors,omitempty"` - TxDropped uint64 `protobuf:"varint,9,opt,name=Tx_dropped,json=txDropped" json:"Tx_dropped,omitempty"` -} - -func (m *NetworkStats) Reset() { *m = NetworkStats{} } -func (m *NetworkStats) String() string { return proto.CompactTextString(m) } -func (*NetworkStats) ProtoMessage() {} -func (*NetworkStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33} } - -type CpuUsage struct { - TotalUsage uint64 `protobuf:"varint,1,opt,name=total_usage,json=totalUsage" json:"total_usage,omitempty"` - PercpuUsage []uint64 `protobuf:"varint,2,rep,packed,name=percpu_usage,json=percpuUsage" json:"percpu_usage,omitempty"` - UsageInKernelmode uint64 `protobuf:"varint,3,opt,name=usage_in_kernelmode,json=usageInKernelmode" json:"usage_in_kernelmode,omitempty"` - UsageInUsermode uint64 `protobuf:"varint,4,opt,name=usage_in_usermode,json=usageInUsermode" json:"usage_in_usermode,omitempty"` -} - -func (m *CpuUsage) Reset() { *m = CpuUsage{} } -func (m *CpuUsage) String() string { return proto.CompactTextString(m) } -func (*CpuUsage) ProtoMessage() {} -func (*CpuUsage) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{34} } - -type ThrottlingData struct { - Periods uint64 `protobuf:"varint,1,opt,name=periods" json:"periods,omitempty"` - ThrottledPeriods uint64 `protobuf:"varint,2,opt,name=throttled_periods,json=throttledPeriods" json:"throttled_periods,omitempty"` - ThrottledTime uint64 `protobuf:"varint,3,opt,name=throttled_time,json=throttledTime" json:"throttled_time,omitempty"` -} - -func (m *ThrottlingData) Reset() { *m = ThrottlingData{} } -func (m *ThrottlingData) String() string { return proto.CompactTextString(m) } -func (*ThrottlingData) ProtoMessage() {} -func (*ThrottlingData) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{35} } - -type CpuStats struct { - CpuUsage *CpuUsage `protobuf:"bytes,1,opt,name=cpu_usage,json=cpuUsage" json:"cpu_usage,omitempty"` - ThrottlingData *ThrottlingData `protobuf:"bytes,2,opt,name=throttling_data,json=throttlingData" json:"throttling_data,omitempty"` - SystemUsage uint64 `protobuf:"varint,3,opt,name=system_usage,json=systemUsage" json:"system_usage,omitempty"` -} - -func (m *CpuStats) Reset() { *m = CpuStats{} } -func (m *CpuStats) String() string { return proto.CompactTextString(m) } -func (*CpuStats) ProtoMessage() {} -func (*CpuStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{36} } - -func (m *CpuStats) GetCpuUsage() *CpuUsage { - if m != nil { - return m.CpuUsage - } - return nil -} - -func (m *CpuStats) GetThrottlingData() *ThrottlingData { - if m != nil { - return m.ThrottlingData - } - return nil -} - -type PidsStats struct { - Current uint64 `protobuf:"varint,1,opt,name=current" json:"current,omitempty"` - Limit uint64 `protobuf:"varint,2,opt,name=limit" json:"limit,omitempty"` -} - -func (m *PidsStats) Reset() { *m = PidsStats{} } -func (m *PidsStats) String() string { return proto.CompactTextString(m) } -func (*PidsStats) ProtoMessage() {} -func (*PidsStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{37} } - -type MemoryData struct { - Usage uint64 `protobuf:"varint,1,opt,name=usage" json:"usage,omitempty"` - MaxUsage uint64 `protobuf:"varint,2,opt,name=max_usage,json=maxUsage" json:"max_usage,omitempty"` - Failcnt uint64 `protobuf:"varint,3,opt,name=failcnt" json:"failcnt,omitempty"` - Limit uint64 `protobuf:"varint,4,opt,name=limit" json:"limit,omitempty"` -} - -func (m *MemoryData) Reset() { *m = MemoryData{} } -func (m *MemoryData) String() string { return proto.CompactTextString(m) } -func (*MemoryData) ProtoMessage() {} -func (*MemoryData) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{38} } - -type MemoryStats struct { - Cache uint64 `protobuf:"varint,1,opt,name=cache" json:"cache,omitempty"` - Usage *MemoryData `protobuf:"bytes,2,opt,name=usage" json:"usage,omitempty"` - SwapUsage *MemoryData `protobuf:"bytes,3,opt,name=swap_usage,json=swapUsage" json:"swap_usage,omitempty"` - KernelUsage *MemoryData `protobuf:"bytes,4,opt,name=kernel_usage,json=kernelUsage" json:"kernel_usage,omitempty"` - Stats map[string]uint64 `protobuf:"bytes,5,rep,name=stats" json:"stats,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` -} - -func (m *MemoryStats) Reset() { *m = MemoryStats{} } -func (m *MemoryStats) String() string { return proto.CompactTextString(m) } -func (*MemoryStats) ProtoMessage() {} -func (*MemoryStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{39} } - -func (m *MemoryStats) GetUsage() *MemoryData { - if m != nil { - return m.Usage - } - return nil -} - -func (m *MemoryStats) GetSwapUsage() *MemoryData { - if m != nil { - return m.SwapUsage - } - return nil -} - -func (m *MemoryStats) GetKernelUsage() *MemoryData { - if m != nil { - return m.KernelUsage - } - return nil -} - -func (m *MemoryStats) GetStats() map[string]uint64 { - if m != nil { - return m.Stats - } - return nil -} - -type BlkioStatsEntry struct { - Major uint64 `protobuf:"varint,1,opt,name=major" json:"major,omitempty"` - Minor uint64 `protobuf:"varint,2,opt,name=minor" json:"minor,omitempty"` - Op string `protobuf:"bytes,3,opt,name=op" json:"op,omitempty"` - Value uint64 `protobuf:"varint,4,opt,name=value" json:"value,omitempty"` -} - -func (m *BlkioStatsEntry) Reset() { *m = BlkioStatsEntry{} } -func (m *BlkioStatsEntry) String() string { return proto.CompactTextString(m) } -func (*BlkioStatsEntry) ProtoMessage() {} -func (*BlkioStatsEntry) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{40} } - -type BlkioStats struct { - IoServiceBytesRecursive []*BlkioStatsEntry `protobuf:"bytes,1,rep,name=io_service_bytes_recursive,json=ioServiceBytesRecursive" json:"io_service_bytes_recursive,omitempty"` - IoServicedRecursive []*BlkioStatsEntry `protobuf:"bytes,2,rep,name=io_serviced_recursive,json=ioServicedRecursive" json:"io_serviced_recursive,omitempty"` - IoQueuedRecursive []*BlkioStatsEntry `protobuf:"bytes,3,rep,name=io_queued_recursive,json=ioQueuedRecursive" json:"io_queued_recursive,omitempty"` - IoServiceTimeRecursive []*BlkioStatsEntry `protobuf:"bytes,4,rep,name=io_service_time_recursive,json=ioServiceTimeRecursive" json:"io_service_time_recursive,omitempty"` - IoWaitTimeRecursive []*BlkioStatsEntry `protobuf:"bytes,5,rep,name=io_wait_time_recursive,json=ioWaitTimeRecursive" json:"io_wait_time_recursive,omitempty"` - IoMergedRecursive []*BlkioStatsEntry `protobuf:"bytes,6,rep,name=io_merged_recursive,json=ioMergedRecursive" json:"io_merged_recursive,omitempty"` - IoTimeRecursive []*BlkioStatsEntry `protobuf:"bytes,7,rep,name=io_time_recursive,json=ioTimeRecursive" json:"io_time_recursive,omitempty"` - SectorsRecursive []*BlkioStatsEntry `protobuf:"bytes,8,rep,name=sectors_recursive,json=sectorsRecursive" json:"sectors_recursive,omitempty"` -} - -func (m *BlkioStats) Reset() { *m = BlkioStats{} } -func (m *BlkioStats) String() string { return proto.CompactTextString(m) } -func (*BlkioStats) ProtoMessage() {} -func (*BlkioStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{41} } - -func (m *BlkioStats) GetIoServiceBytesRecursive() []*BlkioStatsEntry { - if m != nil { - return m.IoServiceBytesRecursive - } - return nil -} - -func (m *BlkioStats) GetIoServicedRecursive() []*BlkioStatsEntry { - if m != nil { - return m.IoServicedRecursive - } - return nil -} - -func (m *BlkioStats) GetIoQueuedRecursive() []*BlkioStatsEntry { - if m != nil { - return m.IoQueuedRecursive - } - return nil -} - -func (m *BlkioStats) GetIoServiceTimeRecursive() []*BlkioStatsEntry { - if m != nil { - return m.IoServiceTimeRecursive - } - return nil -} - -func (m *BlkioStats) GetIoWaitTimeRecursive() []*BlkioStatsEntry { - if m != nil { - return m.IoWaitTimeRecursive - } - return nil -} - -func (m *BlkioStats) GetIoMergedRecursive() []*BlkioStatsEntry { - if m != nil { - return m.IoMergedRecursive - } - return nil -} - -func (m *BlkioStats) GetIoTimeRecursive() []*BlkioStatsEntry { - if m != nil { - return m.IoTimeRecursive - } - return nil -} - -func (m *BlkioStats) GetSectorsRecursive() []*BlkioStatsEntry { - if m != nil { - return m.SectorsRecursive - } - return nil -} - -type HugetlbStats struct { - Usage uint64 `protobuf:"varint,1,opt,name=usage" json:"usage,omitempty"` - MaxUsage uint64 `protobuf:"varint,2,opt,name=max_usage,json=maxUsage" json:"max_usage,omitempty"` - Failcnt uint64 `protobuf:"varint,3,opt,name=failcnt" json:"failcnt,omitempty"` - Limit uint64 `protobuf:"varint,4,opt,name=limit" json:"limit,omitempty"` -} - -func (m *HugetlbStats) Reset() { *m = HugetlbStats{} } -func (m *HugetlbStats) String() string { return proto.CompactTextString(m) } -func (*HugetlbStats) ProtoMessage() {} -func (*HugetlbStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{42} } - -type CgroupStats struct { - CpuStats *CpuStats `protobuf:"bytes,1,opt,name=cpu_stats,json=cpuStats" json:"cpu_stats,omitempty"` - MemoryStats *MemoryStats `protobuf:"bytes,2,opt,name=memory_stats,json=memoryStats" json:"memory_stats,omitempty"` - BlkioStats *BlkioStats `protobuf:"bytes,3,opt,name=blkio_stats,json=blkioStats" json:"blkio_stats,omitempty"` - HugetlbStats map[string]*HugetlbStats `protobuf:"bytes,4,rep,name=hugetlb_stats,json=hugetlbStats" json:"hugetlb_stats,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` - PidsStats *PidsStats `protobuf:"bytes,5,opt,name=pids_stats,json=pidsStats" json:"pids_stats,omitempty"` -} - -func (m *CgroupStats) Reset() { *m = CgroupStats{} } -func (m *CgroupStats) String() string { return proto.CompactTextString(m) } -func (*CgroupStats) ProtoMessage() {} -func (*CgroupStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{43} } - -func (m *CgroupStats) GetCpuStats() *CpuStats { - if m != nil { - return m.CpuStats - } - return nil -} - -func (m *CgroupStats) GetMemoryStats() *MemoryStats { - if m != nil { - return m.MemoryStats - } - return nil -} - -func (m *CgroupStats) GetBlkioStats() *BlkioStats { - if m != nil { - return m.BlkioStats - } - return nil -} - -func (m *CgroupStats) GetHugetlbStats() map[string]*HugetlbStats { - if m != nil { - return m.HugetlbStats - } - return nil -} - -func (m *CgroupStats) GetPidsStats() *PidsStats { - if m != nil { - return m.PidsStats - } - return nil -} - -type StatsResponse struct { - NetworkStats []*NetworkStats `protobuf:"bytes,1,rep,name=network_stats,json=networkStats" json:"network_stats,omitempty"` - CgroupStats *CgroupStats `protobuf:"bytes,2,opt,name=cgroup_stats,json=cgroupStats" json:"cgroup_stats,omitempty"` - // Tag 3 is deprecated (old uint64 timestamp) - Timestamp *google_protobuf.Timestamp `protobuf:"bytes,4,opt,name=timestamp" json:"timestamp,omitempty"` -} - -func (m *StatsResponse) Reset() { *m = StatsResponse{} } -func (m *StatsResponse) String() string { return proto.CompactTextString(m) } -func (*StatsResponse) ProtoMessage() {} -func (*StatsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{44} } - -func (m *StatsResponse) GetNetworkStats() []*NetworkStats { - if m != nil { - return m.NetworkStats - } - return nil -} - -func (m *StatsResponse) GetCgroupStats() *CgroupStats { - if m != nil { - return m.CgroupStats - } - return nil -} - -func (m *StatsResponse) GetTimestamp() *google_protobuf.Timestamp { - if m != nil { - return m.Timestamp - } - return nil -} - -type StatsRequest struct { - Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` -} - -func (m *StatsRequest) Reset() { *m = StatsRequest{} } -func (m *StatsRequest) String() string { return proto.CompactTextString(m) } -func (*StatsRequest) ProtoMessage() {} -func (*StatsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{45} } - -func init() { - proto.RegisterType((*GetServerVersionRequest)(nil), "types.GetServerVersionRequest") - proto.RegisterType((*GetServerVersionResponse)(nil), "types.GetServerVersionResponse") - proto.RegisterType((*UpdateProcessRequest)(nil), "types.UpdateProcessRequest") - proto.RegisterType((*UpdateProcessResponse)(nil), "types.UpdateProcessResponse") - proto.RegisterType((*CreateContainerRequest)(nil), "types.CreateContainerRequest") - proto.RegisterType((*CreateContainerResponse)(nil), "types.CreateContainerResponse") - proto.RegisterType((*SignalRequest)(nil), "types.SignalRequest") - proto.RegisterType((*SignalResponse)(nil), "types.SignalResponse") - proto.RegisterType((*AddProcessRequest)(nil), "types.AddProcessRequest") - proto.RegisterType((*Rlimit)(nil), "types.Rlimit") - proto.RegisterType((*User)(nil), "types.User") - proto.RegisterType((*AddProcessResponse)(nil), "types.AddProcessResponse") - proto.RegisterType((*CreateCheckpointRequest)(nil), "types.CreateCheckpointRequest") - proto.RegisterType((*CreateCheckpointResponse)(nil), "types.CreateCheckpointResponse") - proto.RegisterType((*DeleteCheckpointRequest)(nil), "types.DeleteCheckpointRequest") - proto.RegisterType((*DeleteCheckpointResponse)(nil), "types.DeleteCheckpointResponse") - proto.RegisterType((*ListCheckpointRequest)(nil), "types.ListCheckpointRequest") - proto.RegisterType((*Checkpoint)(nil), "types.Checkpoint") - proto.RegisterType((*ListCheckpointResponse)(nil), "types.ListCheckpointResponse") - proto.RegisterType((*StateRequest)(nil), "types.StateRequest") - proto.RegisterType((*ContainerState)(nil), "types.ContainerState") - proto.RegisterType((*Process)(nil), "types.Process") - proto.RegisterType((*Container)(nil), "types.Container") - proto.RegisterType((*Machine)(nil), "types.Machine") - proto.RegisterType((*StateResponse)(nil), "types.StateResponse") - proto.RegisterType((*UpdateContainerRequest)(nil), "types.UpdateContainerRequest") - proto.RegisterType((*UpdateResource)(nil), "types.UpdateResource") - proto.RegisterType((*BlockIODevice)(nil), "types.BlockIODevice") - proto.RegisterType((*WeightDevice)(nil), "types.WeightDevice") - proto.RegisterType((*ThrottleDevice)(nil), "types.ThrottleDevice") - proto.RegisterType((*UpdateContainerResponse)(nil), "types.UpdateContainerResponse") - proto.RegisterType((*EventsRequest)(nil), "types.EventsRequest") - proto.RegisterType((*Event)(nil), "types.Event") - proto.RegisterType((*NetworkStats)(nil), "types.NetworkStats") - proto.RegisterType((*CpuUsage)(nil), "types.CpuUsage") - proto.RegisterType((*ThrottlingData)(nil), "types.ThrottlingData") - proto.RegisterType((*CpuStats)(nil), "types.CpuStats") - proto.RegisterType((*PidsStats)(nil), "types.PidsStats") - proto.RegisterType((*MemoryData)(nil), "types.MemoryData") - proto.RegisterType((*MemoryStats)(nil), "types.MemoryStats") - proto.RegisterType((*BlkioStatsEntry)(nil), "types.BlkioStatsEntry") - proto.RegisterType((*BlkioStats)(nil), "types.BlkioStats") - proto.RegisterType((*HugetlbStats)(nil), "types.HugetlbStats") - proto.RegisterType((*CgroupStats)(nil), "types.CgroupStats") - proto.RegisterType((*StatsResponse)(nil), "types.StatsResponse") - proto.RegisterType((*StatsRequest)(nil), "types.StatsRequest") -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion3 - -// Client API for API service - -type APIClient interface { - GetServerVersion(ctx context.Context, in *GetServerVersionRequest, opts ...grpc.CallOption) (*GetServerVersionResponse, error) - CreateContainer(ctx context.Context, in *CreateContainerRequest, opts ...grpc.CallOption) (*CreateContainerResponse, error) - UpdateContainer(ctx context.Context, in *UpdateContainerRequest, opts ...grpc.CallOption) (*UpdateContainerResponse, error) - Signal(ctx context.Context, in *SignalRequest, opts ...grpc.CallOption) (*SignalResponse, error) - UpdateProcess(ctx context.Context, in *UpdateProcessRequest, opts ...grpc.CallOption) (*UpdateProcessResponse, error) - AddProcess(ctx context.Context, in *AddProcessRequest, opts ...grpc.CallOption) (*AddProcessResponse, error) - CreateCheckpoint(ctx context.Context, in *CreateCheckpointRequest, opts ...grpc.CallOption) (*CreateCheckpointResponse, error) - DeleteCheckpoint(ctx context.Context, in *DeleteCheckpointRequest, opts ...grpc.CallOption) (*DeleteCheckpointResponse, error) - ListCheckpoint(ctx context.Context, in *ListCheckpointRequest, opts ...grpc.CallOption) (*ListCheckpointResponse, error) - State(ctx context.Context, in *StateRequest, opts ...grpc.CallOption) (*StateResponse, error) - Events(ctx context.Context, in *EventsRequest, opts ...grpc.CallOption) (API_EventsClient, error) - Stats(ctx context.Context, in *StatsRequest, opts ...grpc.CallOption) (*StatsResponse, error) -} - -type aPIClient struct { - cc *grpc.ClientConn -} - -func NewAPIClient(cc *grpc.ClientConn) APIClient { - return &aPIClient{cc} -} - -func (c *aPIClient) GetServerVersion(ctx context.Context, in *GetServerVersionRequest, opts ...grpc.CallOption) (*GetServerVersionResponse, error) { - out := new(GetServerVersionResponse) - err := grpc.Invoke(ctx, "/types.API/GetServerVersion", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *aPIClient) CreateContainer(ctx context.Context, in *CreateContainerRequest, opts ...grpc.CallOption) (*CreateContainerResponse, error) { - out := new(CreateContainerResponse) - err := grpc.Invoke(ctx, "/types.API/CreateContainer", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *aPIClient) UpdateContainer(ctx context.Context, in *UpdateContainerRequest, opts ...grpc.CallOption) (*UpdateContainerResponse, error) { - out := new(UpdateContainerResponse) - err := grpc.Invoke(ctx, "/types.API/UpdateContainer", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *aPIClient) Signal(ctx context.Context, in *SignalRequest, opts ...grpc.CallOption) (*SignalResponse, error) { - out := new(SignalResponse) - err := grpc.Invoke(ctx, "/types.API/Signal", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *aPIClient) UpdateProcess(ctx context.Context, in *UpdateProcessRequest, opts ...grpc.CallOption) (*UpdateProcessResponse, error) { - out := new(UpdateProcessResponse) - err := grpc.Invoke(ctx, "/types.API/UpdateProcess", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *aPIClient) AddProcess(ctx context.Context, in *AddProcessRequest, opts ...grpc.CallOption) (*AddProcessResponse, error) { - out := new(AddProcessResponse) - err := grpc.Invoke(ctx, "/types.API/AddProcess", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *aPIClient) CreateCheckpoint(ctx context.Context, in *CreateCheckpointRequest, opts ...grpc.CallOption) (*CreateCheckpointResponse, error) { - out := new(CreateCheckpointResponse) - err := grpc.Invoke(ctx, "/types.API/CreateCheckpoint", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *aPIClient) DeleteCheckpoint(ctx context.Context, in *DeleteCheckpointRequest, opts ...grpc.CallOption) (*DeleteCheckpointResponse, error) { - out := new(DeleteCheckpointResponse) - err := grpc.Invoke(ctx, "/types.API/DeleteCheckpoint", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *aPIClient) ListCheckpoint(ctx context.Context, in *ListCheckpointRequest, opts ...grpc.CallOption) (*ListCheckpointResponse, error) { - out := new(ListCheckpointResponse) - err := grpc.Invoke(ctx, "/types.API/ListCheckpoint", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *aPIClient) State(ctx context.Context, in *StateRequest, opts ...grpc.CallOption) (*StateResponse, error) { - out := new(StateResponse) - err := grpc.Invoke(ctx, "/types.API/State", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *aPIClient) Events(ctx context.Context, in *EventsRequest, opts ...grpc.CallOption) (API_EventsClient, error) { - stream, err := grpc.NewClientStream(ctx, &_API_serviceDesc.Streams[0], c.cc, "/types.API/Events", opts...) - if err != nil { - return nil, err - } - x := &aPIEventsClient{stream} - if err := x.ClientStream.SendMsg(in); err != nil { - return nil, err - } - if err := x.ClientStream.CloseSend(); err != nil { - return nil, err - } - return x, nil -} - -type API_EventsClient interface { - Recv() (*Event, error) - grpc.ClientStream -} - -type aPIEventsClient struct { - grpc.ClientStream -} - -func (x *aPIEventsClient) Recv() (*Event, error) { - m := new(Event) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -func (c *aPIClient) Stats(ctx context.Context, in *StatsRequest, opts ...grpc.CallOption) (*StatsResponse, error) { - out := new(StatsResponse) - err := grpc.Invoke(ctx, "/types.API/Stats", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for API service - -type APIServer interface { - GetServerVersion(context.Context, *GetServerVersionRequest) (*GetServerVersionResponse, error) - CreateContainer(context.Context, *CreateContainerRequest) (*CreateContainerResponse, error) - UpdateContainer(context.Context, *UpdateContainerRequest) (*UpdateContainerResponse, error) - Signal(context.Context, *SignalRequest) (*SignalResponse, error) - UpdateProcess(context.Context, *UpdateProcessRequest) (*UpdateProcessResponse, error) - AddProcess(context.Context, *AddProcessRequest) (*AddProcessResponse, error) - CreateCheckpoint(context.Context, *CreateCheckpointRequest) (*CreateCheckpointResponse, error) - DeleteCheckpoint(context.Context, *DeleteCheckpointRequest) (*DeleteCheckpointResponse, error) - ListCheckpoint(context.Context, *ListCheckpointRequest) (*ListCheckpointResponse, error) - State(context.Context, *StateRequest) (*StateResponse, error) - Events(*EventsRequest, API_EventsServer) error - Stats(context.Context, *StatsRequest) (*StatsResponse, error) -} - -func RegisterAPIServer(s *grpc.Server, srv APIServer) { - s.RegisterService(&_API_serviceDesc, srv) -} - -func _API_GetServerVersion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetServerVersionRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(APIServer).GetServerVersion(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/types.API/GetServerVersion", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(APIServer).GetServerVersion(ctx, req.(*GetServerVersionRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _API_CreateContainer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CreateContainerRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(APIServer).CreateContainer(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/types.API/CreateContainer", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(APIServer).CreateContainer(ctx, req.(*CreateContainerRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _API_UpdateContainer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(UpdateContainerRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(APIServer).UpdateContainer(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/types.API/UpdateContainer", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(APIServer).UpdateContainer(ctx, req.(*UpdateContainerRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _API_Signal_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SignalRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(APIServer).Signal(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/types.API/Signal", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(APIServer).Signal(ctx, req.(*SignalRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _API_UpdateProcess_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(UpdateProcessRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(APIServer).UpdateProcess(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/types.API/UpdateProcess", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(APIServer).UpdateProcess(ctx, req.(*UpdateProcessRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _API_AddProcess_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(AddProcessRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(APIServer).AddProcess(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/types.API/AddProcess", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(APIServer).AddProcess(ctx, req.(*AddProcessRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _API_CreateCheckpoint_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CreateCheckpointRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(APIServer).CreateCheckpoint(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/types.API/CreateCheckpoint", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(APIServer).CreateCheckpoint(ctx, req.(*CreateCheckpointRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _API_DeleteCheckpoint_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(DeleteCheckpointRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(APIServer).DeleteCheckpoint(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/types.API/DeleteCheckpoint", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(APIServer).DeleteCheckpoint(ctx, req.(*DeleteCheckpointRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _API_ListCheckpoint_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ListCheckpointRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(APIServer).ListCheckpoint(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/types.API/ListCheckpoint", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(APIServer).ListCheckpoint(ctx, req.(*ListCheckpointRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _API_State_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(StateRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(APIServer).State(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/types.API/State", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(APIServer).State(ctx, req.(*StateRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _API_Events_Handler(srv interface{}, stream grpc.ServerStream) error { - m := new(EventsRequest) - if err := stream.RecvMsg(m); err != nil { - return err - } - return srv.(APIServer).Events(m, &aPIEventsServer{stream}) -} - -type API_EventsServer interface { - Send(*Event) error - grpc.ServerStream -} - -type aPIEventsServer struct { - grpc.ServerStream -} - -func (x *aPIEventsServer) Send(m *Event) error { - return x.ServerStream.SendMsg(m) -} - -func _API_Stats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(StatsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(APIServer).Stats(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/types.API/Stats", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(APIServer).Stats(ctx, req.(*StatsRequest)) - } - return interceptor(ctx, in, info, handler) -} - -var _API_serviceDesc = grpc.ServiceDesc{ - ServiceName: "types.API", - HandlerType: (*APIServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "GetServerVersion", - Handler: _API_GetServerVersion_Handler, - }, - { - MethodName: "CreateContainer", - Handler: _API_CreateContainer_Handler, - }, - { - MethodName: "UpdateContainer", - Handler: _API_UpdateContainer_Handler, - }, - { - MethodName: "Signal", - Handler: _API_Signal_Handler, - }, - { - MethodName: "UpdateProcess", - Handler: _API_UpdateProcess_Handler, - }, - { - MethodName: "AddProcess", - Handler: _API_AddProcess_Handler, - }, - { - MethodName: "CreateCheckpoint", - Handler: _API_CreateCheckpoint_Handler, - }, - { - MethodName: "DeleteCheckpoint", - Handler: _API_DeleteCheckpoint_Handler, - }, - { - MethodName: "ListCheckpoint", - Handler: _API_ListCheckpoint_Handler, - }, - { - MethodName: "State", - Handler: _API_State_Handler, - }, - { - MethodName: "Stats", - Handler: _API_Stats_Handler, - }, - }, - Streams: []grpc.StreamDesc{ - { - StreamName: "Events", - Handler: _API_Events_Handler, - ServerStreams: true, - }, - }, - Metadata: fileDescriptor0, -} - -func init() { proto.RegisterFile("api.proto", fileDescriptor0) } - -var fileDescriptor0 = []byte{ - // 2604 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xec, 0x59, 0x4b, 0x6f, 0x1c, 0x5b, - 0xf1, 0xcf, 0x3c, 0x3c, 0xf6, 0xd4, 0x3c, 0xec, 0xe9, 0x38, 0xce, 0x64, 0xf2, 0xfc, 0xb7, 0xee, - 0x1f, 0x02, 0x5c, 0x39, 0xc1, 0xb9, 0x17, 0x22, 0x90, 0x90, 0x12, 0x3b, 0x5c, 0xcc, 0xcd, 0xc3, - 0x69, 0x3b, 0x44, 0x48, 0x48, 0xa3, 0xf6, 0xcc, 0xc9, 0x4c, 0xe3, 0x9e, 0xee, 0xbe, 0xdd, 0x67, - 0xfc, 0xd8, 0xb0, 0x60, 0x01, 0x3b, 0xd8, 0x22, 0xb1, 0x64, 0xc7, 0x9e, 0x05, 0x7c, 0x01, 0x24, - 0x3e, 0x08, 0x3b, 0xf6, 0x2c, 0xa9, 0x53, 0xe7, 0xd1, 0xa7, 0xe7, 0xe1, 0x24, 0x48, 0x88, 0x0d, - 0x9b, 0x51, 0x57, 0x9d, 0x3a, 0x55, 0x75, 0xea, 0x54, 0xfd, 0x4e, 0x9d, 0x33, 0x50, 0xf7, 0x93, - 0x60, 0x3b, 0x49, 0x63, 0x1e, 0x3b, 0x2b, 0xfc, 0x22, 0x61, 0x59, 0xef, 0xee, 0x28, 0x8e, 0x47, - 0x21, 0x7b, 0x40, 0xcc, 0xe3, 0xe9, 0xbb, 0x07, 0x3c, 0x98, 0xb0, 0x8c, 0xfb, 0x93, 0x44, 0xca, - 0xb9, 0x37, 0xe0, 0xfa, 0x17, 0x8c, 0x1f, 0xb2, 0xf4, 0x94, 0xa5, 0x3f, 0x61, 0x69, 0x16, 0xc4, - 0x91, 0xc7, 0xbe, 0x9a, 0xa2, 0x8c, 0x7b, 0x0e, 0xdd, 0xf9, 0xa1, 0x2c, 0x89, 0xa3, 0x8c, 0x39, - 0x9b, 0xb0, 0x32, 0xf1, 0x7f, 0x1e, 0xa7, 0xdd, 0xd2, 0xbd, 0xd2, 0xfd, 0x96, 0x27, 0x09, 0xe2, - 0x06, 0x11, 0x72, 0xcb, 0x8a, 0x2b, 0x08, 0xc1, 0x4d, 0x7c, 0x3e, 0x18, 0x77, 0x2b, 0x92, 0x4b, - 0x84, 0xd3, 0x83, 0xb5, 0x94, 0x9d, 0x06, 0x42, 0x6b, 0xb7, 0x8a, 0x03, 0x75, 0xcf, 0xd0, 0xee, - 0xaf, 0x4a, 0xb0, 0xf9, 0x26, 0x19, 0xfa, 0x9c, 0x1d, 0xa4, 0xf1, 0x80, 0x65, 0x99, 0x72, 0xc9, - 0x69, 0x43, 0x39, 0x18, 0x92, 0xcd, 0xba, 0x87, 0x5f, 0xce, 0x06, 0x54, 0x12, 0x64, 0x94, 0x89, - 0x21, 0x3e, 0x9d, 0x3b, 0x00, 0x83, 0x30, 0xce, 0xd8, 0x21, 0x1f, 0x06, 0x11, 0x59, 0x5c, 0xf3, - 0x2c, 0x8e, 0x70, 0xe6, 0x2c, 0x18, 0xf2, 0x31, 0xd9, 0x44, 0x67, 0x88, 0x70, 0xb6, 0xa0, 0x36, - 0x66, 0xc1, 0x68, 0xcc, 0xbb, 0x2b, 0xc4, 0x56, 0x94, 0x7b, 0x1d, 0xae, 0xcd, 0xf8, 0x21, 0xd7, - 0xef, 0xfe, 0xad, 0x0c, 0x5b, 0xbb, 0x29, 0xc3, 0x91, 0xdd, 0x38, 0xe2, 0x7e, 0x10, 0xb1, 0x74, - 0x99, 0x8f, 0xe8, 0xd1, 0xf1, 0x34, 0x1a, 0x86, 0xec, 0xc0, 0x47, 0xb3, 0xd2, 0x55, 0x8b, 0x43, - 0x1e, 0x8f, 0xd9, 0xe0, 0x24, 0x89, 0x83, 0x88, 0x93, 0xc7, 0x38, 0x9e, 0x73, 0x84, 0xc7, 0x19, - 0x2d, 0x46, 0x46, 0x49, 0x12, 0xc2, 0x63, 0xfc, 0x88, 0xa7, 0xd2, 0xe3, 0xba, 0xa7, 0x28, 0xc5, - 0x67, 0x69, 0xda, 0xad, 0x19, 0x3e, 0x52, 0x82, 0x1f, 0xfa, 0xc7, 0x2c, 0xcc, 0xba, 0xab, 0xf7, - 0x2a, 0x82, 0x2f, 0x29, 0xe7, 0x1e, 0x34, 0xa2, 0xf8, 0x20, 0x38, 0x8d, 0xb9, 0x17, 0xc7, 0xbc, - 0xbb, 0x46, 0x01, 0xb3, 0x59, 0x4e, 0x17, 0x56, 0xd3, 0x69, 0x24, 0xf2, 0xa6, 0x5b, 0x27, 0x95, - 0x9a, 0x14, 0x73, 0xd5, 0xe7, 0x93, 0x74, 0x94, 0x75, 0x81, 0x14, 0xdb, 0x2c, 0xe7, 0x13, 0x68, - 0xe5, 0x2b, 0xd9, 0x0b, 0xd2, 0x6e, 0x83, 0x34, 0x14, 0x99, 0xee, 0x3e, 0x5c, 0x9f, 0x8b, 0xa5, - 0xca, 0xb3, 0x6d, 0xa8, 0x0f, 0x34, 0x93, 0x62, 0xda, 0xd8, 0xd9, 0xd8, 0xa6, 0xd4, 0xde, 0xce, - 0x85, 0x73, 0x11, 0x54, 0xd5, 0x3a, 0x0c, 0x46, 0x91, 0x1f, 0x7e, 0x78, 0xc6, 0x88, 0x88, 0xd1, - 0x14, 0x95, 0x9f, 0x8a, 0x72, 0x37, 0xa0, 0xad, 0x55, 0xa9, 0x4d, 0xff, 0x53, 0x05, 0x3a, 0x4f, - 0x86, 0xc3, 0xf7, 0xe4, 0x24, 0x26, 0x36, 0x67, 0x29, 0xa6, 0x3e, 0x6a, 0x2c, 0x53, 0x38, 0x0d, - 0xed, 0xdc, 0x85, 0xea, 0x34, 0xc3, 0x95, 0x54, 0x68, 0x25, 0x0d, 0xb5, 0x92, 0x37, 0xc8, 0xf2, - 0x68, 0xc0, 0x71, 0xa0, 0xea, 0x8b, 0x58, 0x56, 0x29, 0x96, 0xf4, 0x2d, 0x5c, 0x66, 0xd1, 0x29, - 0xee, 0xb3, 0x60, 0x89, 0x4f, 0xc1, 0x19, 0x9c, 0x0d, 0xd5, 0x0e, 0x8b, 0x4f, 0xbd, 0xac, 0xd5, - 0x7c, 0x59, 0x26, 0x6d, 0xd6, 0x16, 0xa7, 0x4d, 0x7d, 0x49, 0xda, 0x40, 0x21, 0x6d, 0x5c, 0x68, - 0x0e, 0xfc, 0xc4, 0x3f, 0x0e, 0xc2, 0x80, 0x07, 0x2c, 0xc3, 0xfd, 0x13, 0x4e, 0x14, 0x78, 0xce, - 0x7d, 0x58, 0xf7, 0x93, 0xc4, 0x4f, 0x27, 0x71, 0x8a, 0xa1, 0x79, 0x17, 0x84, 0xac, 0xdb, 0x24, - 0x25, 0xb3, 0x6c, 0xa1, 0x2d, 0x63, 0x61, 0x10, 0x4d, 0xcf, 0x9f, 0x8b, 0xec, 0xeb, 0xb6, 0x48, - 0xac, 0xc0, 0x13, 0xda, 0xa2, 0xf8, 0x25, 0x3b, 0x3b, 0x48, 0x83, 0x53, 0x9c, 0x33, 0x42, 0xa3, - 0x6d, 0x8a, 0xe2, 0x2c, 0xdb, 0xf9, 0x3a, 0x26, 0x66, 0x18, 0x4c, 0x02, 0x9e, 0x75, 0xd7, 0xd1, - 0xad, 0xc6, 0x4e, 0x4b, 0xc5, 0xd3, 0x23, 0xae, 0xa7, 0x47, 0xdd, 0x3d, 0xa8, 0x49, 0x96, 0x08, - 0xaf, 0x10, 0x51, 0xbb, 0x45, 0xdf, 0x82, 0x97, 0xc5, 0xef, 0x38, 0xed, 0x55, 0xd5, 0xa3, 0x6f, - 0xc1, 0x1b, 0xfb, 0xe9, 0x90, 0xf6, 0x09, 0x79, 0xe2, 0xdb, 0xf5, 0xa0, 0x2a, 0x36, 0x4a, 0x84, - 0x7a, 0xaa, 0x36, 0xbc, 0xe5, 0x89, 0x4f, 0xc1, 0x19, 0xa9, 0x9c, 0x42, 0x0e, 0x7e, 0x3a, 0x5f, - 0x83, 0xb6, 0x3f, 0x1c, 0x62, 0x78, 0x62, 0xdc, 0xf5, 0x2f, 0x82, 0x61, 0x86, 0x9a, 0x2a, 0x38, - 0x38, 0xc3, 0x75, 0x37, 0xc1, 0xb1, 0x13, 0x4a, 0xe5, 0xd9, 0x2f, 0x4b, 0xa6, 0x20, 0x4c, 0x9d, - 0x2c, 0xcb, 0xb6, 0x6f, 0x17, 0xd0, 0xa3, 0x4c, 0x79, 0xd5, 0xd1, 0x15, 0x92, 0xcf, 0xb6, 0x01, - 0x65, 0xae, 0x28, 0x2b, 0x8b, 0x8a, 0xb2, 0x07, 0xdd, 0x79, 0x1f, 0x94, 0x83, 0x03, 0xb8, 0xbe, - 0xc7, 0x42, 0xf6, 0x21, 0xfe, 0x61, 0x24, 0x23, 0x1f, 0xa1, 0x43, 0x16, 0x1c, 0x7d, 0x7f, 0xb8, - 0x03, 0xf3, 0x46, 0x94, 0x03, 0x2f, 0xe0, 0xda, 0xf3, 0x20, 0xe3, 0xef, 0x37, 0x3f, 0x67, 0xaa, - 0xbc, 0xc8, 0xd4, 0xef, 0x4a, 0x00, 0xb9, 0x2e, 0xe3, 0x73, 0xc9, 0xf2, 0x19, 0x79, 0xec, 0x3c, - 0xe0, 0xaa, 0xa2, 0xe9, 0x5b, 0xec, 0x3b, 0x1f, 0x24, 0xea, 0x90, 0x11, 0x9f, 0x02, 0x11, 0xa7, - 0x51, 0x70, 0x7e, 0x18, 0x0f, 0x4e, 0x18, 0xcf, 0x08, 0xb1, 0x11, 0x4d, 0x2d, 0x16, 0x95, 0xe5, - 0x98, 0x85, 0x21, 0xc1, 0xf6, 0x9a, 0x27, 0x09, 0x81, 0xb1, 0x6c, 0x92, 0xf0, 0x8b, 0x97, 0x87, - 0x58, 0xd4, 0xa2, 0xc2, 0x34, 0x89, 0x2b, 0xdd, 0x9a, 0x5d, 0xa9, 0x82, 0xc6, 0x47, 0xd0, 0xc8, - 0x57, 0x91, 0xa1, 0xb3, 0x95, 0xc5, 0x5b, 0x6f, 0x4b, 0xb9, 0x77, 0xa0, 0x79, 0xc8, 0x71, 0x53, - 0x97, 0xc4, 0xcb, 0xbd, 0x0f, 0x6d, 0x83, 0xab, 0x24, 0x28, 0x91, 0xc1, 0xe7, 0xd3, 0x4c, 0x49, - 0x29, 0xca, 0xfd, 0x73, 0x05, 0x56, 0x55, 0xe2, 0x6a, 0xf4, 0x29, 0xe5, 0xe8, 0xf3, 0x5f, 0x01, - 0xc1, 0x5b, 0x50, 0xcf, 0x2e, 0x32, 0xce, 0x26, 0x07, 0x0a, 0x0a, 0x5b, 0x5e, 0xce, 0xf8, 0x1f, - 0x20, 0xe6, 0x80, 0xf8, 0xd7, 0x12, 0xd4, 0xcd, 0x36, 0x7f, 0x74, 0xc3, 0xf2, 0x29, 0xd4, 0x13, - 0xb9, 0xf1, 0x4c, 0xe2, 0x5a, 0x63, 0xa7, 0xad, 0x0c, 0x69, 0x24, 0xcb, 0x05, 0xac, 0xfc, 0xa9, - 0xda, 0xf9, 0x63, 0x35, 0x24, 0x2b, 0x85, 0x86, 0x04, 0x37, 0x3f, 0x11, 0x80, 0x59, 0x23, 0xc0, - 0xa4, 0x6f, 0xbb, 0x05, 0x59, 0x2d, 0xb4, 0x20, 0xee, 0xe7, 0xb0, 0xfa, 0xc2, 0x1f, 0x8c, 0x71, - 0x1d, 0x62, 0xe2, 0x20, 0x51, 0x69, 0x8a, 0x13, 0xc5, 0xb7, 0x30, 0x32, 0x61, 0x18, 0xef, 0x0b, - 0x85, 0xee, 0x8a, 0x72, 0x4f, 0xb0, 0x4d, 0x90, 0x65, 0xa0, 0x8a, 0xe9, 0x21, 0xc2, 0xa8, 0x0e, - 0x88, 0xae, 0xa5, 0xf9, 0x46, 0xc3, 0x92, 0xc1, 0x6d, 0x59, 0x9d, 0x48, 0xcb, 0x0a, 0x75, 0x75, - 0x0c, 0x94, 0x3f, 0x9e, 0x1e, 0x76, 0x7f, 0x5d, 0x82, 0x2d, 0xd9, 0x45, 0xbe, 0xb7, 0x57, 0x5c, - 0xdc, 0x9d, 0xc8, 0xf0, 0x55, 0x0a, 0xe1, 0x7b, 0x04, 0xf5, 0x94, 0x65, 0xf1, 0x34, 0xc5, 0x30, - 0x53, 0x64, 0x1b, 0x3b, 0xd7, 0x74, 0x25, 0x91, 0x2d, 0x4f, 0x8d, 0x7a, 0xb9, 0x9c, 0xfb, 0x8f, - 0x1a, 0xb4, 0x8b, 0xa3, 0x02, 0xb1, 0x8e, 0xc3, 0x93, 0x20, 0x7e, 0x2b, 0xdb, 0xdf, 0x12, 0x85, - 0xc9, 0x66, 0x89, 0xaa, 0xc2, 0x58, 0x1e, 0xe2, 0x19, 0x88, 0x96, 0x64, 0x18, 0x73, 0x86, 0x1a, - 0x3d, 0x60, 0x69, 0x10, 0xeb, 0xe3, 0x32, 0x67, 0x08, 0x18, 0x40, 0xe2, 0xf5, 0x34, 0xe6, 0x3e, - 0x39, 0x59, 0xf5, 0x0c, 0x4d, 0x7d, 0x2f, 0xee, 0x11, 0xe3, 0xbb, 0x62, 0xd7, 0x56, 0x54, 0xdf, - 0x6b, 0x38, 0xf9, 0xf8, 0x0b, 0x36, 0xc9, 0x54, 0x99, 0x5b, 0x1c, 0xe1, 0xb9, 0xdc, 0xcd, 0xe7, - 0x22, 0xa9, 0x29, 0x31, 0xd0, 0x73, 0x8b, 0x25, 0x34, 0x48, 0xf2, 0xf0, 0xcc, 0x4f, 0xa8, 0xec, - 0xab, 0x9e, 0xc5, 0xc1, 0x44, 0xee, 0x48, 0x0a, 0xa3, 0x81, 0xb7, 0x1c, 0x5f, 0x1c, 0xcc, 0x04, - 0x03, 0x55, 0x6f, 0x7e, 0x40, 0x48, 0x9f, 0xb0, 0x34, 0x62, 0xe1, 0x0b, 0xcb, 0x2a, 0x48, 0xe9, - 0xb9, 0x01, 0x67, 0x07, 0x36, 0x25, 0xf3, 0x68, 0xf7, 0xc0, 0x9e, 0xd0, 0xa0, 0x09, 0x0b, 0xc7, - 0x44, 0xa5, 0x53, 0xe0, 0x9f, 0x33, 0xff, 0x9d, 0xda, 0x8f, 0x26, 0x89, 0xcf, 0xb2, 0x9d, 0x27, - 0xd0, 0xb1, 0xb6, 0x68, 0x0f, 0xef, 0x4d, 0x03, 0x86, 0xe0, 0x21, 0xb2, 0xf6, 0xaa, 0xca, 0x02, - 0x7b, 0xc8, 0x9b, 0x97, 0x76, 0xde, 0x40, 0x8f, 0x98, 0x47, 0x63, 0xbc, 0x07, 0xf2, 0x10, 0x33, - 0xc2, 0x1f, 0x3e, 0x4d, 0x32, 0xa5, 0xab, 0x4d, 0xba, 0x74, 0x46, 0x69, 0x19, 0xa5, 0xed, 0x92, - 0x89, 0xce, 0x5b, 0xb8, 0x59, 0x18, 0x7d, 0x9b, 0x06, 0x9c, 0xe5, 0x7a, 0xd7, 0x2f, 0xd3, 0x7b, - 0xd9, 0xcc, 0x39, 0xc5, 0xc2, 0xec, 0x7e, 0x6c, 0x14, 0x6f, 0x7c, 0xb8, 0xe2, 0xe2, 0x4c, 0xe7, - 0xa7, 0x70, 0x6b, 0xde, 0xae, 0xa5, 0xb9, 0x73, 0x99, 0xe6, 0x4b, 0xa7, 0xba, 0xdf, 0x87, 0xd6, - 0xd3, 0x10, 0x0f, 0xfe, 0xfd, 0x57, 0xca, 0x56, 0xe1, 0xda, 0x5c, 0x59, 0x78, 0x6d, 0xae, 0xa8, - 0x6b, 0xb3, 0xfb, 0x0b, 0x68, 0x16, 0x36, 0xec, 0x3b, 0x54, 0xa9, 0x5a, 0x95, 0xba, 0x0c, 0x6d, - 0x2a, 0xb7, 0x0a, 0x66, 0x3c, 0x5b, 0x50, 0x20, 0xc8, 0x99, 0x4c, 0x26, 0xd9, 0xa0, 0x2a, 0x4a, - 0x54, 0x47, 0x98, 0x27, 0x9a, 0xbc, 0xfb, 0x58, 0x1c, 0xf7, 0x67, 0xd0, 0x2e, 0x2e, 0xf6, 0xdf, - 0xf6, 0x00, 0x91, 0x39, 0x45, 0xcc, 0xd1, 0x1d, 0xb6, 0xf8, 0x16, 0xef, 0x0e, 0x73, 0x98, 0xa8, - 0x9a, 0xbb, 0x0b, 0x68, 0x3d, 0x3b, 0x65, 0xd8, 0xad, 0x68, 0x94, 0x7c, 0x0c, 0x75, 0xf3, 0x6c, - 0xa1, 0xc0, 0xb6, 0xb7, 0x2d, 0x1f, 0x36, 0xb6, 0xf5, 0xc3, 0xc6, 0xf6, 0x91, 0x96, 0xf0, 0x72, - 0x61, 0xb1, 0xc6, 0x8c, 0xc7, 0x29, 0x1b, 0xbe, 0x8a, 0xc2, 0x0b, 0xfd, 0x1a, 0x90, 0x73, 0x14, - 0xfe, 0x56, 0x4d, 0xfb, 0xf3, 0xdb, 0x12, 0xac, 0x90, 0xed, 0x85, 0x37, 0x05, 0x29, 0x5d, 0x36, - 0x68, 0x5d, 0xc4, 0xe6, 0x96, 0xc1, 0x66, 0x85, 0xe2, 0xd5, 0x1c, 0xc5, 0x0b, 0x2b, 0xa8, 0x7d, - 0xc4, 0x0a, 0xdc, 0xdf, 0x94, 0xa1, 0xf9, 0x92, 0xf1, 0xb3, 0x38, 0x3d, 0x11, 0x27, 0x56, 0xb6, - 0xb0, 0x39, 0xbd, 0x01, 0x6b, 0xe9, 0x79, 0xff, 0xf8, 0x82, 0x1b, 0x84, 0x5e, 0x4d, 0xcf, 0x9f, - 0x0a, 0xd2, 0xb9, 0x0d, 0x80, 0x43, 0x07, 0xbe, 0x6c, 0x48, 0x15, 0x40, 0xa7, 0xe7, 0x8a, 0xe1, - 0xdc, 0x84, 0xba, 0x77, 0xde, 0xc7, 0xc6, 0x26, 0x4e, 0x33, 0x8d, 0xd0, 0xe9, 0xf9, 0x33, 0xa2, - 0xc5, 0x5c, 0x1c, 0x1c, 0xa6, 0x71, 0x92, 0xb0, 0x21, 0x21, 0x34, 0xcd, 0xdd, 0x93, 0x0c, 0x61, - 0xf5, 0x48, 0x5b, 0xad, 0x49, 0xab, 0x3c, 0xb7, 0x8a, 0x43, 0x89, 0xb2, 0x2a, 0xa1, 0xb9, 0xce, - 0x6d, 0xab, 0x47, 0xc6, 0xaa, 0xc4, 0xe5, 0x35, 0x6e, 0x59, 0x3d, 0xca, 0xad, 0xd6, 0xf5, 0x5c, - 0x65, 0xd5, 0xfd, 0x63, 0x09, 0xd6, 0xf0, 0x7c, 0x78, 0x93, 0xf9, 0x23, 0x86, 0xad, 0x64, 0x83, - 0xe3, 0x59, 0x12, 0xf6, 0xa7, 0x82, 0x54, 0xa7, 0x17, 0x10, 0x4b, 0x0a, 0xfc, 0x1f, 0x34, 0x13, - 0x96, 0xe2, 0xa9, 0xa1, 0x24, 0xca, 0x58, 0xcc, 0x78, 0x4a, 0x48, 0x9e, 0x14, 0xd9, 0x86, 0xab, - 0x34, 0xd6, 0x0f, 0xa2, 0xbe, 0x84, 0xe5, 0x49, 0x3c, 0x64, 0x2a, 0x54, 0x1d, 0x1a, 0xda, 0x8f, - 0xbe, 0x34, 0x03, 0xce, 0x37, 0xa1, 0x63, 0xe4, 0x45, 0xbb, 0x4a, 0xd2, 0x32, 0x74, 0xeb, 0x4a, - 0xfa, 0x8d, 0x62, 0x63, 0x0d, 0xeb, 0x1a, 0x0a, 0xa2, 0xd1, 0x9e, 0x8f, 0xa7, 0x1e, 0xb6, 0x32, - 0x09, 0x9d, 0x8d, 0x99, 0xf2, 0x56, 0x93, 0xce, 0xb7, 0xa0, 0xc3, 0x55, 0xbd, 0x0d, 0xfb, 0x5a, - 0x46, 0xee, 0xe6, 0x86, 0x19, 0x38, 0x50, 0xc2, 0xff, 0x0f, 0xed, 0x5c, 0x98, 0x1a, 0x23, 0xe9, - 0x6f, 0xcb, 0x70, 0x45, 0x36, 0xb9, 0xbf, 0x97, 0xc1, 0x92, 0x99, 0xf3, 0x29, 0x1d, 0xd5, 0x56, - 0xa8, 0x1a, 0x3b, 0xeb, 0xba, 0xc5, 0x51, 0xc1, 0xa0, 0xe3, 0x59, 0x86, 0xe5, 0x07, 0xb0, 0xce, - 0x8d, 0xeb, 0x7d, 0xac, 0x54, 0x5f, 0x95, 0xde, 0x0c, 0x12, 0xaa, 0x85, 0x79, 0x6d, 0x5e, 0x5c, - 0x28, 0x46, 0x5e, 0xf6, 0xde, 0xca, 0xa0, 0xf4, 0xaf, 0x21, 0x79, 0x64, 0x02, 0xe1, 0xb1, 0x8e, - 0x8d, 0x79, 0x26, 0xbd, 0xc3, 0xc0, 0x0c, 0xa6, 0x69, 0x8a, 0xb5, 0xa7, 0x03, 0xa3, 0x48, 0x01, - 0x8f, 0xd4, 0xb7, 0xaa, 0x60, 0x48, 0xc2, 0x8d, 0x01, 0xe4, 0xd9, 0x49, 0xd6, 0x50, 0xc6, 0x4e, - 0x01, 0x49, 0x88, 0x3c, 0x9b, 0xf8, 0xe7, 0x66, 0xeb, 0x29, 0xcf, 0x90, 0x21, 0x17, 0x88, 0x06, - 0xdf, 0xf9, 0x41, 0x38, 0x50, 0x8f, 0x6e, 0x68, 0x50, 0x91, 0xb9, 0xc1, 0xaa, 0x6d, 0xf0, 0x0f, - 0x65, 0x68, 0x48, 0x8b, 0xd2, 0x61, 0x94, 0x1a, 0x60, 0x87, 0x67, 0x4c, 0x12, 0x81, 0x3d, 0xf8, - 0x4a, 0x6e, 0x2e, 0xbf, 0x8f, 0xe5, 0xae, 0x6a, 0xdf, 0xb0, 0xe3, 0xcc, 0xb0, 0x09, 0xb1, 0xa2, - 0xb3, 0x50, 0xba, 0x2e, 0x84, 0xa4, 0xc3, 0x9f, 0x41, 0x53, 0xe6, 0xa7, 0x9a, 0x53, 0x5d, 0x36, - 0xa7, 0x21, 0xc5, 0xe4, 0xac, 0x47, 0xe2, 0xda, 0x83, 0xfe, 0x52, 0x9b, 0xdd, 0xd8, 0xb9, 0x5d, - 0x10, 0xa7, 0x95, 0x6c, 0xd3, 0xef, 0xb3, 0x88, 0x63, 0xbf, 0x23, 0x65, 0x7b, 0x8f, 0x01, 0x72, - 0xa6, 0xc0, 0xb3, 0x13, 0x76, 0xa1, 0xaf, 0x77, 0xf8, 0x29, 0xd6, 0x7e, 0xea, 0x87, 0x53, 0x1d, - 0x54, 0x49, 0x7c, 0xaf, 0xfc, 0xb8, 0xe4, 0x0e, 0x60, 0xfd, 0xa9, 0x38, 0x12, 0xad, 0xe9, 0x85, - 0x43, 0xaf, 0xba, 0xf0, 0xd0, 0xab, 0xea, 0xb7, 0x62, 0x84, 0xd8, 0x38, 0x51, 0xad, 0x2e, 0x7e, - 0xe5, 0x86, 0xaa, 0x96, 0x21, 0xf7, 0xef, 0x55, 0x80, 0xdc, 0x8a, 0x73, 0x08, 0xbd, 0x20, 0xee, - 0x8b, 0x4e, 0x0d, 0x4f, 0x1b, 0x09, 0x48, 0xfd, 0x94, 0x61, 0xfa, 0x64, 0xc1, 0x29, 0x53, 0xcd, - 0xfc, 0x96, 0x39, 0xa6, 0x0a, 0xce, 0x79, 0xd7, 0x91, 0x92, 0x13, 0x09, 0xb9, 0x3c, 0x3d, 0xcd, - 0xf9, 0x31, 0x5c, 0xcb, 0x95, 0x0e, 0x2d, 0x7d, 0xe5, 0x4b, 0xf5, 0x5d, 0x35, 0xfa, 0x86, 0xb9, - 0xae, 0x1f, 0x02, 0xb2, 0xfb, 0x78, 0x98, 0x4d, 0x0b, 0x9a, 0x2a, 0x97, 0x6a, 0xea, 0x04, 0xf1, - 0x6b, 0x9a, 0x91, 0xeb, 0x79, 0x0d, 0x37, 0xac, 0x85, 0x8a, 0xb2, 0xb7, 0xb4, 0x55, 0x2f, 0xd5, - 0xb6, 0x65, 0xfc, 0x12, 0xc0, 0x90, 0xab, 0xfc, 0x12, 0x70, 0xa4, 0x7f, 0xe6, 0x07, 0x7c, 0x56, - 0xdf, 0xca, 0xfb, 0xd6, 0xf9, 0x16, 0x27, 0x15, 0x95, 0xc9, 0x75, 0x4e, 0x58, 0x3a, 0x2a, 0xac, - 0xb3, 0xf6, 0xbe, 0x75, 0xbe, 0xa0, 0x19, 0xb9, 0x9e, 0xa7, 0x80, 0xcc, 0x59, 0x7f, 0x56, 0x2f, - 0xd5, 0xb2, 0x8e, 0x5d, 0x58, 0xc1, 0x97, 0x5d, 0xe8, 0x64, 0x6c, 0x80, 0x47, 0xbd, 0x9d, 0x0b, - 0x6b, 0x97, 0xea, 0xd8, 0x50, 0x13, 0x8c, 0x12, 0xf7, 0x2b, 0x68, 0xfe, 0x68, 0x3a, 0x62, 0x3c, - 0x3c, 0x36, 0x35, 0xff, 0x9f, 0x86, 0x99, 0x7f, 0x22, 0xcc, 0xec, 0x8e, 0xd2, 0x78, 0x9a, 0x14, - 0x50, 0x5b, 0xd6, 0xf0, 0x1c, 0x6a, 0x93, 0x0c, 0xa1, 0xb6, 0x94, 0xfe, 0x1c, 0x9a, 0xf2, 0xe6, - 0xa2, 0x26, 0x48, 0x14, 0x72, 0xe6, 0x8b, 0x5e, 0xdf, 0x94, 0xe4, 0xb4, 0x1d, 0x75, 0x0b, 0x54, - 0xb3, 0x8a, 0x68, 0x94, 0x87, 0xc9, 0x83, 0xe3, 0xbc, 0xea, 0xf6, 0xa1, 0x35, 0x96, 0xb1, 0x51, - 0xb3, 0x64, 0x02, 0x7e, 0xa2, 0x9d, 0xcb, 0xd7, 0xb0, 0x6d, 0xc7, 0x50, 0x86, 0xba, 0x39, 0xb6, - 0xc3, 0xfa, 0x00, 0x40, 0xdc, 0xf3, 0xfb, 0x1a, 0xa8, 0xec, 0x67, 0x7e, 0x73, 0x42, 0x78, 0xf5, - 0x44, 0x7f, 0xf6, 0x8e, 0xa0, 0x33, 0xa7, 0x73, 0x01, 0x4c, 0x7d, 0xc3, 0x86, 0xa9, 0xfc, 0x6a, - 0x64, 0x4f, 0xb5, 0xb1, 0xeb, 0x2f, 0x25, 0xf9, 0x2c, 0x60, 0x5e, 0x62, 0xb1, 0x6f, 0x6b, 0x45, - 0xb2, 0xf9, 0x32, 0x1b, 0x60, 0xdf, 0xb1, 0xec, 0xc6, 0xcc, 0x6b, 0x46, 0x76, 0x9b, 0x86, 0x1b, - 0x31, 0xa0, 0x08, 0x2c, 0xdc, 0x08, 0x2b, 0x38, 0x5e, 0x63, 0x60, 0xed, 0x76, 0xa1, 0x51, 0xac, - 0x7e, 0x4c, 0xa3, 0xa8, 0x5e, 0xf6, 0x96, 0xfd, 0x2d, 0xb1, 0x83, 0x77, 0xff, 0xca, 0x93, 0x83, - 0x7d, 0xbc, 0xf7, 0x6d, 0xcc, 0xfe, 0xab, 0xe7, 0xdc, 0x51, 0x6e, 0x2d, 0xf9, 0x27, 0xb0, 0x77, - 0x77, 0xe9, 0xb8, 0x6a, 0xd9, 0xaf, 0x38, 0x1e, 0xac, 0xcf, 0xfc, 0x87, 0xe3, 0xe8, 0xa3, 0x66, - 0xf1, 0xff, 0x64, 0xbd, 0x3b, 0xcb, 0x86, 0x6d, 0x9d, 0x33, 0x77, 0x04, 0xa3, 0x73, 0xf1, 0x7b, - 0x8a, 0xd1, 0xb9, 0xec, 0x6a, 0x71, 0xc5, 0xf9, 0x2e, 0xd4, 0xe4, 0xbf, 0x3a, 0x8e, 0xbe, 0xb8, - 0x14, 0xfe, 0x2f, 0xea, 0x5d, 0x9b, 0xe1, 0x9a, 0x89, 0xcf, 0xa1, 0x55, 0xf8, 0x2b, 0xd0, 0xb9, - 0x59, 0xb0, 0x55, 0xfc, 0x53, 0xa8, 0x77, 0x6b, 0xf1, 0xa0, 0xd1, 0xb6, 0x0b, 0x90, 0x3f, 0xfc, - 0x3b, 0x5d, 0x25, 0x3d, 0xf7, 0xe7, 0x52, 0xef, 0xc6, 0x82, 0x11, 0xa3, 0x04, 0xb7, 0x72, 0xf6, - 0x89, 0xde, 0x99, 0x89, 0xea, 0xec, 0x03, 0xb9, 0xd9, 0xca, 0xa5, 0x6f, 0xfb, 0xa4, 0x76, 0xf6, - 0xe1, 0xdd, 0xa8, 0x5d, 0xf2, 0xec, 0x6f, 0xd4, 0x2e, 0x7d, 0xb1, 0xbf, 0xe2, 0xbc, 0x82, 0x76, - 0xf1, 0x25, 0xdb, 0xd1, 0x41, 0x5a, 0xf8, 0x94, 0xdf, 0xbb, 0xbd, 0x64, 0xd4, 0x28, 0xfc, 0x0c, - 0x56, 0xe4, 0x13, 0xb5, 0x2e, 0x47, 0xfb, 0x65, 0xbb, 0xb7, 0x59, 0x64, 0x9a, 0x59, 0x0f, 0xa1, - 0x26, 0x6f, 0x97, 0x26, 0x01, 0x0a, 0x97, 0xcd, 0x5e, 0xd3, 0xe6, 0xba, 0x57, 0x1e, 0x96, 0xb4, - 0x9d, 0xac, 0x60, 0x27, 0x5b, 0x64, 0xc7, 0xda, 0x9c, 0xe3, 0x1a, 0x95, 0xeb, 0xa3, 0x7f, 0x05, - 0x00, 0x00, 0xff, 0xff, 0xa7, 0x2d, 0xc6, 0x49, 0x94, 0x1f, 0x00, 0x00, -} diff --git a/api/grpc/types/api.proto b/api/grpc/types/api.proto deleted file mode 100644 index ea5ddb7..0000000 --- a/api/grpc/types/api.proto +++ /dev/null @@ -1,342 +0,0 @@ -syntax = "proto3"; - -package types; - -import "google/protobuf/timestamp.proto"; - -service API { - rpc GetServerVersion(GetServerVersionRequest) returns (GetServerVersionResponse) {} - rpc CreateContainer(CreateContainerRequest) returns (CreateContainerResponse) {} - rpc UpdateContainer(UpdateContainerRequest) returns (UpdateContainerResponse) {} - rpc Signal(SignalRequest) returns (SignalResponse) {} - rpc UpdateProcess(UpdateProcessRequest) returns (UpdateProcessResponse) {} - rpc AddProcess(AddProcessRequest) returns (AddProcessResponse) {} - rpc CreateCheckpoint(CreateCheckpointRequest) returns (CreateCheckpointResponse) {} - rpc DeleteCheckpoint(DeleteCheckpointRequest) returns (DeleteCheckpointResponse) {} - rpc ListCheckpoint(ListCheckpointRequest) returns (ListCheckpointResponse) {} - rpc State(StateRequest) returns (StateResponse) {} - rpc Events(EventsRequest) returns (stream Event) {} - rpc Stats(StatsRequest) returns (StatsResponse) {} -} - -message GetServerVersionRequest { -} - -message GetServerVersionResponse { - uint32 major = 1; - uint32 minor = 2; - uint32 patch = 3; - string revision = 4; -} - -message UpdateProcessRequest { - string id = 1; - string pid = 2; - bool closeStdin = 3; // Close stdin of the container - uint32 width = 4; - uint32 height = 5; -} - -message UpdateProcessResponse { -} - -message CreateContainerRequest { - string id = 1; // ID of container - string bundlePath = 2; // path to OCI bundle - string checkpoint = 3; // checkpoint name if you want to create immediate checkpoint (optional) - string stdin = 4; // path to the file where stdin will be read (optional) - string stdout = 5; // path to file where stdout will be written (optional) - string stderr = 6; // path to file where stderr will be written (optional) - repeated string labels = 7; - bool noPivotRoot = 8; - string runtime = 9; - repeated string runtimeArgs = 10; - string checkpointDir = 11; // Directory where checkpoints are stored -} - -message CreateContainerResponse { - Container container = 1; -} - -message SignalRequest { - string id = 1; // ID of container - string pid = 2; // PID of process inside container - uint32 signal = 3; // Signal which will be sent, you can find value in "man 7 signal" -} - -message SignalResponse { -} - -message AddProcessRequest { - string id = 1; // ID of container - bool terminal = 2; // Use tty for container stdio - User user = 3; // User under which process will be run - repeated string args = 4; // Arguments for process, first is binary path itself - repeated string env = 5; // List of environment variables for process - string cwd = 6; // Workind directory of process - string pid = 7; // Process ID - string stdin = 8; // path to the file where stdin will be read (optional) - string stdout = 9; // path to file where stdout will be written (optional) - string stderr = 10; // path to file where stderr will be written (optional) - repeated string capabilities = 11; - string apparmorProfile = 12; - string selinuxLabel = 13; - bool noNewPrivileges = 14; - repeated Rlimit rlimits = 15; -} - -message Rlimit { - string type = 1; - uint64 soft = 2; - uint64 hard = 3; -} - -message User { - uint32 uid = 1; // UID of user - uint32 gid = 2; // GID of user - repeated uint32 additionalGids = 3; // Additional groups to which user will be added -} - -message AddProcessResponse { -} - -message CreateCheckpointRequest { - string id = 1; // ID of container - Checkpoint checkpoint = 2; // Checkpoint configuration - string checkpointDir = 3; // Directory where checkpoints are stored -} - -message CreateCheckpointResponse { -} - -message DeleteCheckpointRequest { - string id = 1; // ID of container - string name = 2; // Name of checkpoint - string checkpointDir = 3; // Directory where checkpoints are stored -} - -message DeleteCheckpointResponse { -} - -message ListCheckpointRequest { - string id = 1; // ID of container - string checkpointDir = 2; // Directory where checkpoints are stored -} - -message Checkpoint { - string name = 1; // Name of checkpoint - bool exit = 2; // checkpoint configuration: should container exit on checkpoint or not - bool tcp = 3; // allow open tcp connections - bool unixSockets = 4; // allow external unix sockets - bool shell = 5; // allow shell-jobs - repeated string emptyNS = 6; -} - -message ListCheckpointResponse { - repeated Checkpoint checkpoints = 1; // List of checkpoints -} - -message StateRequest { - string id = 1; // container id for a single container -} - -message ContainerState { - string status = 1; -} - -message Process { - string pid = 1; - bool terminal = 2; // Use tty for container stdio - User user = 3; // User under which process will be run - repeated string args = 4; // Arguments for process, first is binary path itself - repeated string env = 5; // List of environment variables for process - string cwd = 6; // Workind directory of process - uint32 systemPid = 7; - string stdin = 8; // path to the file where stdin will be read (optional) - string stdout = 9; // path to file where stdout will be written (optional) - string stderr = 10; // path to file where stderr will be written (optional) - repeated string capabilities = 11; - string apparmorProfile = 12; - string selinuxLabel = 13; - bool noNewPrivileges = 14; - repeated Rlimit rlimits = 15; -} - -message Container { - string id = 1; // ID of container - string bundlePath = 2; // Path to OCI bundle - repeated Process processes = 3; // List of processes which run in container - string status = 4; // Container status ("running", "paused", etc.) - repeated string labels = 5; - repeated uint32 pids = 6; - string runtime = 7; // runtime used to execute the container -} - -// Machine is information about machine on which containerd is run -message Machine { - uint32 cpus = 1; // number of cpus - uint64 memory = 2; // amount of memory -} - -// StateResponse is information about containerd daemon -message StateResponse { - repeated Container containers = 1; - Machine machine = 2; -} - -message UpdateContainerRequest { - string id = 1; // ID of container - string pid = 2; - string status = 3; // Status to which containerd will try to change - UpdateResource resources =4; -} - -message UpdateResource { - uint64 blkioWeight = 1; - uint64 cpuShares = 2; - uint64 cpuPeriod = 3; - uint64 cpuQuota = 4; - string cpusetCpus = 5; - string cpusetMems = 6; - uint64 memoryLimit = 7; - uint64 memorySwap = 8; - uint64 memoryReservation = 9; - uint64 kernelMemoryLimit = 10; - uint64 kernelTCPMemoryLimit = 11; - uint64 blkioLeafWeight = 12; - repeated WeightDevice blkioWeightDevice = 13; - repeated ThrottleDevice blkioThrottleReadBpsDevice = 14; - repeated ThrottleDevice blkioThrottleWriteBpsDevice = 15; - repeated ThrottleDevice blkioThrottleReadIopsDevice = 16; - repeated ThrottleDevice blkioThrottleWriteIopsDevice = 17; -} - -message BlockIODevice { - int64 major = 1; - int64 minor = 2; -} - -message WeightDevice { - BlockIODevice blkIODevice = 1; - uint32 weight = 2; - uint32 leafWeight = 3; -} - -message ThrottleDevice { - BlockIODevice blkIODevice = 1; - uint64 rate = 2; -} - -message UpdateContainerResponse { -} - -message EventsRequest { - // Tag 1 is deprecated (old uint64 timestamp) - google.protobuf.Timestamp timestamp = 2; - bool storedOnly = 3; - string id = 4; -} - -message Event { - string type = 1; - string id = 2; - uint32 status = 3; - string pid = 4; - // Tag 5 is deprecated (old uint64 timestamp) - google.protobuf.Timestamp timestamp = 6; -} - -message NetworkStats { - string name = 1; // name of network interface - uint64 rx_bytes = 2; - uint64 rx_Packets = 3; - uint64 Rx_errors = 4; - uint64 Rx_dropped = 5; - uint64 Tx_bytes = 6; - uint64 Tx_packets = 7; - uint64 Tx_errors = 8; - uint64 Tx_dropped = 9; -} - -message CpuUsage { - uint64 total_usage = 1; - repeated uint64 percpu_usage = 2; - uint64 usage_in_kernelmode = 3; - uint64 usage_in_usermode = 4; -} - -message ThrottlingData { - uint64 periods = 1; - uint64 throttled_periods = 2; - uint64 throttled_time = 3; -} - -message CpuStats { - CpuUsage cpu_usage = 1; - ThrottlingData throttling_data = 2; - uint64 system_usage = 3; -} - -message PidsStats { - uint64 current = 1; - uint64 limit = 2; -} - -message MemoryData { - uint64 usage = 1; - uint64 max_usage = 2; - uint64 failcnt = 3; - uint64 limit = 4; -} - -message MemoryStats { - uint64 cache = 1; - MemoryData usage = 2; - MemoryData swap_usage = 3; - MemoryData kernel_usage = 4; - map stats = 5; -} - -message BlkioStatsEntry { - uint64 major = 1; - uint64 minor = 2; - string op = 3; - uint64 value = 4; -} - -message BlkioStats { - repeated BlkioStatsEntry io_service_bytes_recursive = 1; // number of bytes transferred to and from the block device - repeated BlkioStatsEntry io_serviced_recursive = 2; - repeated BlkioStatsEntry io_queued_recursive = 3; - repeated BlkioStatsEntry io_service_time_recursive = 4; - repeated BlkioStatsEntry io_wait_time_recursive = 5; - repeated BlkioStatsEntry io_merged_recursive = 6; - repeated BlkioStatsEntry io_time_recursive = 7; - repeated BlkioStatsEntry sectors_recursive = 8; -} - -message HugetlbStats { - uint64 usage = 1; - uint64 max_usage = 2; - uint64 failcnt = 3; - uint64 limit = 4; -} - -message CgroupStats { - CpuStats cpu_stats = 1; - MemoryStats memory_stats = 2; - BlkioStats blkio_stats = 3; - map hugetlb_stats = 4; // the map is in the format "size of hugepage: stats of the hugepage" - PidsStats pids_stats = 5; -} - -message StatsResponse { - repeated NetworkStats network_stats = 1; - CgroupStats cgroup_stats = 2; - // Tag 3 is deprecated (old uint64 timestamp) - google.protobuf.Timestamp timestamp = 4; -}; - -message StatsRequest { - string id = 1; -} diff --git a/api/image/gen.go b/api/image/gen.go deleted file mode 100644 index 4157fe6..0000000 --- a/api/image/gen.go +++ /dev/null @@ -1,3 +0,0 @@ -package image - -//go:generate protoc -I .:../../..:$GOPATH/src --gogo_out=plugins=grpc,import_path=github.com/docker/containerkit/api/image:. image.proto diff --git a/api/image/image.pb.go b/api/image/image.pb.go deleted file mode 100644 index 832a6e8..0000000 --- a/api/image/image.pb.go +++ /dev/null @@ -1,295 +0,0 @@ -// Code generated by protoc-gen-gogo. -// source: image.proto -// DO NOT EDIT! - -/* -Package image is a generated protocol buffer package. - -It is generated from these files: - image.proto - -It has these top-level messages: - PrepareRequest - PrepareResponse - CleanupRequest - CleanupResponse - CommitRequest - CommitResponse -*/ -package image - -import proto "github.com/gogo/protobuf/proto" -import fmt "fmt" -import math "math" -import _ "github.com/gogo/protobuf/gogoproto" -import docker_containerkit_types "github.com/docker/containerkit/api/types/mount" - -import ( - context "golang.org/x/net/context" - grpc "google.golang.org/grpc" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -const _ = proto.GoGoProtoPackageIsVersion1 - -type PrepareRequest struct { - // Path specifies the filesystem path to target for the image preparation. - // - // These will influence the values of "target" in the emitted mounts. It - // must be unique per usage of the prepared mount and can only be prepared - // again after a call to cleanup. - Path string `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"` - // name of the image to prepare. - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` -} - -func (m *PrepareRequest) Reset() { *m = PrepareRequest{} } -func (m *PrepareRequest) String() string { return proto.CompactTextString(m) } -func (*PrepareRequest) ProtoMessage() {} -func (*PrepareRequest) Descriptor() ([]byte, []int) { return fileDescriptorImage, []int{0} } - -type PrepareResponse struct { - // Layers provides a list of mounts to use with container creation. The - // layers will be mounted, in order, assembling the root filesystem. - // - // Typically, these can be augmented with other mounts from the volume - // service, tmpfs, application-specific bind mounts or even mounts from - // other containers. - Layers []*docker_containerkit_types.Mount `protobuf:"bytes,1,rep,name=layers" json:"layers,omitempty"` -} - -func (m *PrepareResponse) Reset() { *m = PrepareResponse{} } -func (m *PrepareResponse) String() string { return proto.CompactTextString(m) } -func (*PrepareResponse) ProtoMessage() {} -func (*PrepareResponse) Descriptor() ([]byte, []int) { return fileDescriptorImage, []int{1} } - -func (m *PrepareResponse) GetLayers() []*docker_containerkit_types.Mount { - if m != nil { - return m.Layers - } - return nil -} - -type CleanupRequest struct { - // Path cleans up the path used for the image. - // ID identifies the prepared image to cleanup. - Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` -} - -func (m *CleanupRequest) Reset() { *m = CleanupRequest{} } -func (m *CleanupRequest) String() string { return proto.CompactTextString(m) } -func (*CleanupRequest) ProtoMessage() {} -func (*CleanupRequest) Descriptor() ([]byte, []int) { return fileDescriptorImage, []int{2} } - -type CleanupResponse struct { -} - -func (m *CleanupResponse) Reset() { *m = CleanupResponse{} } -func (m *CleanupResponse) String() string { return proto.CompactTextString(m) } -func (*CleanupResponse) ProtoMessage() {} -func (*CleanupResponse) Descriptor() ([]byte, []int) { return fileDescriptorImage, []int{3} } - -// CommitRequest provides argument for the Commit RPC. -type CommitRequest struct { - // Path to a prepared image to capture changes. - Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` -} - -func (m *CommitRequest) Reset() { *m = CommitRequest{} } -func (m *CommitRequest) String() string { return proto.CompactTextString(m) } -func (*CommitRequest) ProtoMessage() {} -func (*CommitRequest) Descriptor() ([]byte, []int) { return fileDescriptorImage, []int{4} } - -type CommitResponse struct { - // name identifies the entity created as part of the image. - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` -} - -func (m *CommitResponse) Reset() { *m = CommitResponse{} } -func (m *CommitResponse) String() string { return proto.CompactTextString(m) } -func (*CommitResponse) ProtoMessage() {} -func (*CommitResponse) Descriptor() ([]byte, []int) { return fileDescriptorImage, []int{5} } - -func init() { - proto.RegisterType((*PrepareRequest)(nil), "docker.containerkit.types.PrepareRequest") - proto.RegisterType((*PrepareResponse)(nil), "docker.containerkit.types.PrepareResponse") - proto.RegisterType((*CleanupRequest)(nil), "docker.containerkit.types.CleanupRequest") - proto.RegisterType((*CleanupResponse)(nil), "docker.containerkit.types.CleanupResponse") - proto.RegisterType((*CommitRequest)(nil), "docker.containerkit.types.CommitRequest") - proto.RegisterType((*CommitResponse)(nil), "docker.containerkit.types.CommitResponse") -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion2 - -// Client API for Images service - -type ImagesClient interface { - // Prepare declares that an image is required for use. A prepared image, - // complete with a set of mounts to use for the image will be provided. - Prepare(ctx context.Context, in *PrepareRequest, opts ...grpc.CallOption) (*PrepareResponse, error) - // Cleanup instructs the images service to cleanup resources for the image. - Cleanup(ctx context.Context, in *CleanupRequest, opts ...grpc.CallOption) (*CleanupResponse, error) - // Commit - Commit(ctx context.Context, in *CommitRequest, opts ...grpc.CallOption) (*CommitResponse, error) -} - -type imagesClient struct { - cc *grpc.ClientConn -} - -func NewImagesClient(cc *grpc.ClientConn) ImagesClient { - return &imagesClient{cc} -} - -func (c *imagesClient) Prepare(ctx context.Context, in *PrepareRequest, opts ...grpc.CallOption) (*PrepareResponse, error) { - out := new(PrepareResponse) - err := grpc.Invoke(ctx, "/docker.containerkit.types.Images/Prepare", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *imagesClient) Cleanup(ctx context.Context, in *CleanupRequest, opts ...grpc.CallOption) (*CleanupResponse, error) { - out := new(CleanupResponse) - err := grpc.Invoke(ctx, "/docker.containerkit.types.Images/Cleanup", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *imagesClient) Commit(ctx context.Context, in *CommitRequest, opts ...grpc.CallOption) (*CommitResponse, error) { - out := new(CommitResponse) - err := grpc.Invoke(ctx, "/docker.containerkit.types.Images/Commit", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for Images service - -type ImagesServer interface { - // Prepare declares that an image is required for use. A prepared image, - // complete with a set of mounts to use for the image will be provided. - Prepare(context.Context, *PrepareRequest) (*PrepareResponse, error) - // Cleanup instructs the images service to cleanup resources for the image. - Cleanup(context.Context, *CleanupRequest) (*CleanupResponse, error) - // Commit - Commit(context.Context, *CommitRequest) (*CommitResponse, error) -} - -func RegisterImagesServer(s *grpc.Server, srv ImagesServer) { - s.RegisterService(&_Images_serviceDesc, srv) -} - -func _Images_Prepare_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(PrepareRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ImagesServer).Prepare(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/docker.containerkit.types.Images/Prepare", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ImagesServer).Prepare(ctx, req.(*PrepareRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Images_Cleanup_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CleanupRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ImagesServer).Cleanup(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/docker.containerkit.types.Images/Cleanup", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ImagesServer).Cleanup(ctx, req.(*CleanupRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Images_Commit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CommitRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ImagesServer).Commit(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/docker.containerkit.types.Images/Commit", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ImagesServer).Commit(ctx, req.(*CommitRequest)) - } - return interceptor(ctx, in, info, handler) -} - -var _Images_serviceDesc = grpc.ServiceDesc{ - ServiceName: "docker.containerkit.types.Images", - HandlerType: (*ImagesServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "Prepare", - Handler: _Images_Prepare_Handler, - }, - { - MethodName: "Cleanup", - Handler: _Images_Cleanup_Handler, - }, - { - MethodName: "Commit", - Handler: _Images_Commit_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, -} - -var fileDescriptorImage = []byte{ - // 314 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x8c, 0x52, 0x4f, 0x6b, 0x3a, 0x31, - 0x14, 0x64, 0xf5, 0xc7, 0xca, 0xef, 0x49, 0x95, 0xe6, 0x64, 0xf7, 0x24, 0xdb, 0x1e, 0xb4, 0xd0, - 0x0d, 0xd8, 0x8b, 0xf4, 0xea, 0xa9, 0x94, 0x42, 0xf1, 0x5e, 0x30, 0xda, 0xd7, 0x35, 0x68, 0xfe, - 0x34, 0xc9, 0x1e, 0xfc, 0x4c, 0xfd, 0x92, 0x65, 0x93, 0xd4, 0x7f, 0xd0, 0xc5, 0xcb, 0xf2, 0x12, - 0x66, 0xe6, 0xcd, 0xcc, 0x06, 0xba, 0x5c, 0xb0, 0x12, 0x0b, 0x6d, 0x94, 0x53, 0xe4, 0xe6, 0x43, - 0xad, 0x36, 0x68, 0x8a, 0x95, 0x92, 0x8e, 0x71, 0x89, 0x66, 0xc3, 0x5d, 0xe1, 0x76, 0x1a, 0x6d, - 0xf6, 0x50, 0x72, 0xb7, 0xae, 0x96, 0xc5, 0x4a, 0x09, 0x5a, 0xaa, 0x52, 0x51, 0xcf, 0x58, 0x56, - 0x9f, 0xfe, 0xe4, 0x0f, 0x7e, 0x0a, 0x4a, 0xd9, 0xd3, 0x11, 0x3c, 0x88, 0xd2, 0x63, 0x51, 0xca, - 0x34, 0xa7, 0x5e, 0x98, 0x0a, 0x55, 0x49, 0x17, 0xbe, 0x81, 0x9b, 0x4f, 0xa1, 0xf7, 0x66, 0x50, - 0x33, 0x83, 0x73, 0xfc, 0xaa, 0xd0, 0x3a, 0x42, 0xe0, 0x9f, 0x66, 0x6e, 0x3d, 0x68, 0x0f, 0x93, - 0xd1, 0xff, 0xb9, 0x9f, 0xeb, 0x3b, 0xc9, 0x04, 0x0e, 0x5a, 0xe1, 0xae, 0x9e, 0xf3, 0x17, 0xe8, - 0xef, 0x99, 0x56, 0x2b, 0x69, 0x91, 0x4c, 0x21, 0xdd, 0xb2, 0x1d, 0x1a, 0x3b, 0x48, 0x86, 0xed, - 0x51, 0x77, 0x32, 0x2c, 0xfe, 0xcc, 0x58, 0xbc, 0xd6, 0x26, 0xe6, 0x11, 0x9f, 0xdf, 0x41, 0x6f, - 0xb6, 0x45, 0x26, 0x2b, 0x7d, 0x6e, 0x23, 0x39, 0xd8, 0xc8, 0xaf, 0xa1, 0xbf, 0x47, 0x85, 0x95, - 0xf9, 0x2d, 0x5c, 0xcd, 0x94, 0x10, 0xdc, 0x35, 0xf1, 0x6a, 0xf5, 0x08, 0x8a, 0x4e, 0x7f, 0x03, - 0x25, 0x87, 0x40, 0x93, 0xef, 0x16, 0xa4, 0xcf, 0xf5, 0x0f, 0xb2, 0x64, 0x01, 0x9d, 0x98, 0x8d, - 0x8c, 0x1b, 0x32, 0x9c, 0x36, 0x97, 0xdd, 0x5f, 0x02, 0x8d, 0x06, 0x16, 0xd0, 0x89, 0x51, 0x1a, - 0x37, 0x9c, 0x96, 0xd2, 0xb8, 0xe1, 0xac, 0x19, 0xf2, 0x0e, 0x69, 0x08, 0x4d, 0x46, 0x4d, 0xac, - 0xe3, 0xf2, 0xb2, 0xf1, 0x05, 0xc8, 0x20, 0xbf, 0x4c, 0xfd, 0xfb, 0x79, 0xfc, 0x09, 0x00, 0x00, - 0xff, 0xff, 0x28, 0x48, 0xab, 0xcd, 0xd4, 0x02, 0x00, 0x00, -} diff --git a/api/image/image.proto b/api/image/image.proto deleted file mode 100644 index 0060c4d..0000000 --- a/api/image/image.proto +++ /dev/null @@ -1,83 +0,0 @@ -syntax = "proto3"; - -package docker.containerkit.types; - -import "github.com/gogo/protobuf/gogoproto/gogo.proto"; -import "github.com/docker/containerkit/api/types/mount/mount.proto"; - -// Images abstracts the graph driver and image store. -// -// The interface is to be able to request and manage images. The output, -// provided as part of the Prepare step, is to expose a set of mounts that can -// be used at container startup to run the image. -service Images { - // Prepare declares that an image is required for use. A prepared image, - // complete with a set of mounts to use for the image will be provided. - rpc Prepare(PrepareRequest) returns (PrepareResponse); - - // Cleanup instructs the images service to cleanup resources for the image. - rpc Cleanup(CleanupRequest) returns (CleanupResponse); - - // Commit - rpc Commit(CommitRequest) returns (CommitResponse); - - // NOTE(stevvooe): Placeholders for other operations here. Consider - // splitting this into a graphdriver like service (Prepare/Cleanup) and an - // image store service. - // - // Really, we want to separate image identification from CAS - // identification, so placing push/pull here may cause too much coupling. - // It might better to be able to import the layers here in the same way the - // graphdriver works, then only use the image metadata to maintain the link - // here. - // - // Basically, we want to avoid the tight coupling present between the image - // store and graphdriver in docker today. - // - // rpc Push(PushRequest) returns (stream PullRequest); - // rpc Pull(PullRequest) returns (stream PullResponse); -} - -message PrepareRequest { - // Path specifies the filesystem path to target for the image preparation. - // - // These will influence the values of "target" in the emitted mounts. It - // must be unique per usage of the prepared mount and can only be prepared - // again after a call to cleanup. - string path = 3; - - // name of the image to prepare. - string name = 2; -} - -message PrepareResponse { - // Layers provides a list of mounts to use with container creation. The - // layers will be mounted, in order, assembling the root filesystem. - // - // Typically, these can be augmented with other mounts from the volume - // service, tmpfs, application-specific bind mounts or even mounts from - // other containers. - repeated types.Mount layers = 1; - - // TODO(stevvooe): It is unclear whether or not we should integrate image - // metadata with this part of the service. -} - -message CleanupRequest { - // Path cleans up the path used for the image. - // ID identifies the prepared image to cleanup. - string path = 1; -} - -message CleanupResponse { } - -// CommitRequest provides argument for the Commit RPC. -message CommitRequest { - // Path to a prepared image to capture changes. - string path = 1; -} - -message CommitResponse { - // name identifies the entity created as part of the image. - string name = 1; -} diff --git a/api/pprof/pprof.go b/api/pprof/pprof.go deleted file mode 100644 index 2910926..0000000 --- a/api/pprof/pprof.go +++ /dev/null @@ -1,18 +0,0 @@ -package pprof - -import ( - // expvar init routine adds the "/debug/vars" handler - _ "expvar" - "net/http" - "net/http/pprof" -) - -// New returns a new handler serving pprof information -func New() http.Handler { - mux := http.NewServeMux() - mux.Handle("/pprof/block", pprof.Handler("block")) - mux.Handle("/pprof/heap", pprof.Handler("heap")) - mux.Handle("/pprof/goroutine", pprof.Handler("goroutine")) - mux.Handle("/pprof/threadcreate", pprof.Handler("threadcreate")) - return mux -} diff --git a/api/types/mount/gen.go b/api/types/mount/gen.go deleted file mode 100644 index 0eb0417..0000000 --- a/api/types/mount/gen.go +++ /dev/null @@ -1,5 +0,0 @@ -package mount - -//go:generate protoc -I .:../../..:$GOPATH/src --gogo_out=plugins=grpc,import_path=github.com/docker/containerkit/api/types/mount:. mount.proto - -//+++go:generate protoc -I .:../../..:$GOPATH/src --gogo_out=plugins=grpc,import_path=github.com/docker/containerkit/api/types/mount,Mgogoproto/gogo.proto=github.com/gogo/protobuf/gogoproto:. mount.proto diff --git a/api/types/mount/mount.pb.go b/api/types/mount/mount.pb.go deleted file mode 100644 index 799b487..0000000 --- a/api/types/mount/mount.pb.go +++ /dev/null @@ -1,71 +0,0 @@ -// Code generated by protoc-gen-gogo. -// source: mount.proto -// DO NOT EDIT! - -/* -Package mount is a generated protocol buffer package. - -It is generated from these files: - mount.proto - -It has these top-level messages: - Mount -*/ -package mount - -import proto "github.com/gogo/protobuf/proto" -import fmt "fmt" -import math "math" -import _ "github.com/gogo/protobuf/gogoproto" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -const _ = proto.GoGoProtoPackageIsVersion1 - -// Mount describes mounts for a container. -// -// This type is the lingua franca of ContainerKit. All services provide mounts -// to be used with the container at creation time. -// -// The Mount type follows the structure of the mount syscall, including a type, -// source, target and options. -type Mount struct { - // Type defines the nature of the mount. - Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` - // Source specifies the name of the mount. Depending on mount type, this - // may be a volume name or a host path, or even ignored. - Source string `protobuf:"bytes,2,opt,name=source,proto3" json:"source,omitempty"` - // Target path in container - Target string `protobuf:"bytes,3,opt,name=target,proto3" json:"target,omitempty"` - // Options specifies zero or more fstab style mount options. - Options []string `protobuf:"bytes,4,rep,name=options" json:"options,omitempty"` -} - -func (m *Mount) Reset() { *m = Mount{} } -func (m *Mount) String() string { return proto.CompactTextString(m) } -func (*Mount) ProtoMessage() {} -func (*Mount) Descriptor() ([]byte, []int) { return fileDescriptorMount, []int{0} } - -func init() { - proto.RegisterType((*Mount)(nil), "docker.containerkit.types.Mount") -} - -var fileDescriptorMount = []byte{ - // 163 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x34, 0x8d, 0xb1, 0x0e, 0x82, 0x30, - 0x10, 0x86, 0x83, 0x20, 0x86, 0xba, 0x75, 0x30, 0xd5, 0x89, 0x38, 0xb1, 0x58, 0x06, 0x9f, 0xc3, - 0x85, 0x37, 0x80, 0x7a, 0xd6, 0x86, 0xd0, 0x23, 0xe5, 0x3a, 0xf8, 0xf6, 0xa6, 0x57, 0xdd, 0xfe, - 0xef, 0x4b, 0xee, 0x3b, 0x71, 0x5c, 0x30, 0x7a, 0xd2, 0x6b, 0x40, 0x42, 0x79, 0x7e, 0xa2, 0x99, - 0x21, 0x68, 0x83, 0x9e, 0x46, 0xe7, 0x21, 0xcc, 0x8e, 0x34, 0x7d, 0x56, 0xd8, 0x2e, 0x37, 0xeb, - 0xe8, 0x1d, 0x27, 0x6d, 0x70, 0xe9, 0x2d, 0x5a, 0xec, 0xf9, 0x62, 0x8a, 0x2f, 0x26, 0x06, 0x5e, - 0xb9, 0x74, 0x05, 0xb1, 0x7f, 0xa4, 0xb0, 0x94, 0xa2, 0x4a, 0x01, 0x55, 0xb4, 0x45, 0xd7, 0x0c, - 0xbc, 0xe5, 0x49, 0xd4, 0x1b, 0xc6, 0x60, 0x40, 0xed, 0xd8, 0xfe, 0x28, 0x79, 0x1a, 0x83, 0x05, - 0x52, 0x65, 0xf6, 0x99, 0xa4, 0x12, 0x07, 0x5c, 0xc9, 0xa1, 0xdf, 0x54, 0xd5, 0x96, 0x5d, 0x33, - 0xfc, 0x71, 0xaa, 0xf9, 0xdb, 0xfd, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x20, 0x78, 0xd5, 0x59, 0xc6, - 0x00, 0x00, 0x00, -} diff --git a/api/types/mount/mount.proto b/api/types/mount/mount.proto deleted file mode 100644 index 3a8ef0e..0000000 --- a/api/types/mount/mount.proto +++ /dev/null @@ -1,27 +0,0 @@ -syntax = "proto3"; - -package docker.containerkit.types; - -import "github.com/gogo/protobuf/gogoproto/gogo.proto"; - -// Mount describes mounts for a container. -// -// This type is the lingua franca of ContainerKit. All services provide mounts -// to be used with the container at creation time. -// -// The Mount type follows the structure of the mount syscall, including a type, -// source, target and options. -message Mount { - // Type defines the nature of the mount. - string type = 1; - - // Source specifies the name of the mount. Depending on mount type, this - // may be a volume name or a host path, or even ignored. - string source = 2; - - // Target path in container - string target = 3; - - // Options specifies zero or more fstab style mount options. - repeated string options = 4; -} diff --git a/api/types/types.go b/api/types/types.go deleted file mode 100644 index ac54abd..0000000 --- a/api/types/types.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package types provides several types common to grpc services. -package types diff --git a/containerd/main.go b/containerd/main.go deleted file mode 100644 index 4cdca13..0000000 --- a/containerd/main.go +++ /dev/null @@ -1,161 +0,0 @@ -package main - -import ( - "fmt" - "net/http" - "os" - "os/signal" - "runtime" - "strings" - "sync" - "syscall" - "time" - - "github.com/Sirupsen/logrus" - "github.com/codegangsta/cli" - "github.com/docker/containerd/api/pprof" - "github.com/docker/containerd/supervisor" -) - -const ( - usage = `High performance container daemon` - minRlimit = 1024 - defaultStateDir = "/run/containerd" - defaultGRPCEndpoint = "unix:///run/containerd/containerd.sock" -) - -var daemonFlags = []cli.Flag{ - cli.BoolFlag{ - Name: "debug", - Usage: "enable debug output in the logs", - }, - cli.StringFlag{ - Name: "state-dir", - Value: defaultStateDir, - Usage: "runtime state directory", - }, - cli.StringFlag{ - Name: "listen,l", - Value: defaultGRPCEndpoint, - Usage: "proto://address on which the GRPC API will listen", - }, - cli.StringFlag{ - Name: "runtime,r", - Value: "runc", - Usage: "name or path of the OCI compliant runtime to use when executing containers", - }, - cli.StringSliceFlag{ - Name: "runtime-args", - Value: &cli.StringSlice{}, - Usage: "specify additional runtime args", - }, - cli.StringFlag{ - Name: "shim", - Value: "containerd-shim", - Usage: "Name or path of shim", - }, - cli.StringFlag{ - Name: "pprof-address", - Usage: "http address to listen for pprof events", - }, - cli.DurationFlag{ - Name: "start-timeout", - Value: 15 * time.Second, - Usage: "timeout duration for waiting on a container to start before it is killed", - }, - cli.IntFlag{ - Name: "retain-count", - Value: 500, - Usage: "number of past events to keep in the event log", - }, -} - -func main() { - logrus.SetFormatter(&logrus.TextFormatter{TimestampFormat: time.RFC3339Nano}) - app := cli.NewApp() - app.Name = "containerd" - app.Version = getVersion() - app.Usage = usage - app.Flags = daemonFlags - app.Before = func(context *cli.Context) error { - if context.GlobalBool("debug") { - logrus.SetLevel(logrus.DebugLevel) - } - if p := context.GlobalString("pprof-address"); len(p) > 0 { - h := pprof.New() - http.Handle("/debug", h) - go http.ListenAndServe(p, nil) - } - if err := checkLimits(); err != nil { - return err - } - return nil - } - app.Action = func(context *cli.Context) { - if err := daemon(context); err != nil { - logrus.Fatal(err) - } - } - if err := app.Run(os.Args); err != nil { - logrus.Fatal(err) - } -} - -func daemon(context *cli.Context) error { - signals := make(chan os.Signal, 2048) - signal.Notify(signals, syscall.SIGTERM, syscall.SIGINT, syscall.SIGUSR1) - sv, err := supervisor.New(supervisor.Config{ - StateDir: context.String("state-dir"), - Runtime: context.String("runtime"), - ShimName: context.String("shim"), - RuntimeArgs: context.StringSlice("runtime-args"), - Timeout: context.Duration("start-timeout"), - EventRetainCount: context.Int("retain-count"), - }) - if err != nil { - return err - } - wg := &sync.WaitGroup{} - for i := 0; i < 10; i++ { - wg.Add(1) - w := supervisor.NewWorker(sv, wg) - go w.Start() - } - if err := sv.Start(); err != nil { - return err - } - // Split the listen string of the form proto://addr - var ( - listenSpec = context.String("listen") - listenParts = strings.SplitN(listenSpec, "://", 2) - ) - if len(listenParts) != 2 { - return fmt.Errorf("bad listen address format %s, expected proto://address", listenSpec) - } - server, err := startServer(listenParts[0], listenParts[1], sv) - if err != nil { - return err - } - for s := range signals { - switch s { - case syscall.SIGUSR1: - 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] - logrus.Infof("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===", buf) - case syscall.SIGINT, syscall.SIGTERM: - logrus.Infof("stopping containerd after receiving %s", s) - server.Stop() - os.Exit(0) - } - } - return nil -} diff --git a/containerd/utils.go b/containerd/utils.go deleted file mode 100644 index bad337f..0000000 --- a/containerd/utils.go +++ /dev/null @@ -1,71 +0,0 @@ -package main - -import ( - "fmt" - "os" - "syscall" - - "github.com/Sirupsen/logrus" - "github.com/docker/containerd" - "github.com/docker/containerd/api/grpc/server" - "github.com/docker/containerd/api/grpc/types" - "github.com/docker/containerd/supervisor" - "github.com/docker/docker/pkg/listeners" - "google.golang.org/grpc" - "google.golang.org/grpc/health" - "google.golang.org/grpc/health/grpc_health_v1" -) - -func startServer(protocol, address string, sv *supervisor.Supervisor) (*grpc.Server, error) { - sockets, err := listeners.Init(protocol, address, "", nil) - if err != nil { - return nil, err - } - if len(sockets) != 1 { - return nil, fmt.Errorf("incorrect number of listeners") - } - l := sockets[0] - s := grpc.NewServer() - types.RegisterAPIServer(s, server.NewServer(sv)) - healthServer := health.NewServer() - grpc_health_v1.RegisterHealthServer(s, healthServer) - go func() { - logrus.Debugf("containerd: grpc api on %s", address) - if err := s.Serve(l); err != nil { - logrus.WithField("error", err).Fatal("containerd: serve grpc") - } - }() - return s, nil -} - -// getDefaultID returns the hostname for the instance host -func getDefaultID() string { - hostname, err := os.Hostname() - if err != nil { - panic(err) - } - return hostname -} - -func checkLimits() error { - var l syscall.Rlimit - if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &l); err != nil { - return err - } - if l.Cur <= minRlimit { - logrus.WithFields(logrus.Fields{ - "current": l.Cur, - "max": l.Max, - }).Warn("containerd: low RLIMIT_NOFILE changing to max") - l.Cur = l.Max - return syscall.Setrlimit(syscall.RLIMIT_NOFILE, &l) - } - return nil -} - -func getVersion() string { - if containerd.GitCommit != "" { - return fmt.Sprintf("%s commit: %s", containerd.Version, containerd.GitCommit) - } - return containerd.Version -} diff --git a/ctr/Makefile b/ctr/Makefile deleted file mode 100644 index 5f03483..0000000 --- a/ctr/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - go build diff --git a/ctr/checkpoint.go b/ctr/checkpoint.go deleted file mode 100644 index 71c0a04..0000000 --- a/ctr/checkpoint.go +++ /dev/null @@ -1,165 +0,0 @@ -package main - -import ( - "fmt" - "os" - "text/tabwriter" - - "github.com/codegangsta/cli" - "github.com/docker/containerd/api/grpc/types" - netcontext "golang.org/x/net/context" -) - -var checkpointSubCmds = []cli.Command{ - listCheckpointCommand, - createCheckpointCommand, - deleteCheckpointCommand, -} - -var checkpointCommand = cli.Command{ - Name: "checkpoints", - Usage: "list all checkpoints", - ArgsUsage: "COMMAND [arguments...]", - Subcommands: checkpointSubCmds, - Description: func() string { - desc := "\n COMMAND:\n" - for _, command := range checkpointSubCmds { - desc += fmt.Sprintf(" %-10.10s%s\n", command.Name, command.Usage) - } - return desc - }(), - Action: listCheckpoints, -} - -var listCheckpointCommand = cli.Command{ - Name: "list", - Usage: "list all checkpoints for a container", - Action: listCheckpoints, - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "checkpoint-dir", - Value: "", - Usage: "path to checkpoint directory", - }, - }, -} - -func listCheckpoints(context *cli.Context) { - var ( - c = getClient(context) - id = context.Args().First() - ) - if id == "" { - fatal("container id cannot be empty", ExitStatusMissingArg) - } - resp, err := c.ListCheckpoint(netcontext.Background(), &types.ListCheckpointRequest{ - Id: id, - CheckpointDir: context.String("checkpoint-dir"), - }) - if err != nil { - fatal(err.Error(), 1) - } - w := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) - fmt.Fprint(w, "NAME\tTCP\tUNIX SOCKETS\tSHELL\n") - for _, c := range resp.Checkpoints { - fmt.Fprintf(w, "%s\t%v\t%v\t%v\n", c.Name, c.Tcp, c.UnixSockets, c.Shell) - } - if err := w.Flush(); err != nil { - fatal(err.Error(), 1) - } -} - -var createCheckpointCommand = cli.Command{ - Name: "create", - Usage: "create a new checkpoint for the container", - Flags: []cli.Flag{ - cli.BoolFlag{ - Name: "tcp", - Usage: "persist open tcp connections", - }, - cli.BoolFlag{ - Name: "unix-sockets", - Usage: "persist unix sockets", - }, - cli.BoolFlag{ - Name: "exit", - Usage: "exit the container after the checkpoint completes successfully", - }, - cli.BoolFlag{ - Name: "shell", - Usage: "checkpoint shell jobs", - }, - cli.StringFlag{ - Name: "checkpoint-dir", - Value: "", - Usage: "directory to store checkpoints", - }, - cli.StringSliceFlag{ - Name: "empty-ns", - Usage: "create a namespace, but don't restore its properties", - }, - }, - Action: func(context *cli.Context) { - var ( - containerID = context.Args().Get(0) - name = context.Args().Get(1) - ) - if containerID == "" { - fatal("container id at cannot be empty", ExitStatusMissingArg) - } - if name == "" { - fatal("checkpoint name cannot be empty", ExitStatusMissingArg) - } - c := getClient(context) - checkpoint := types.Checkpoint{ - Name: name, - Exit: context.Bool("exit"), - Tcp: context.Bool("tcp"), - Shell: context.Bool("shell"), - UnixSockets: context.Bool("unix-sockets"), - } - - emptyNSes := context.StringSlice("empty-ns") - checkpoint.EmptyNS = append(checkpoint.EmptyNS, emptyNSes...) - - if _, err := c.CreateCheckpoint(netcontext.Background(), &types.CreateCheckpointRequest{ - Id: containerID, - CheckpointDir: context.String("checkpoint-dir"), - Checkpoint: &checkpoint, - }); err != nil { - fatal(err.Error(), 1) - } - }, -} - -var deleteCheckpointCommand = cli.Command{ - Name: "delete", - Usage: "delete a container's checkpoint", - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "checkpoint-dir", - Value: "", - Usage: "path to checkpoint directory", - }, - }, - Action: func(context *cli.Context) { - var ( - containerID = context.Args().Get(0) - name = context.Args().Get(1) - ) - if containerID == "" { - fatal("container id at cannot be empty", ExitStatusMissingArg) - } - if name == "" { - fatal("checkpoint name cannot be empty", ExitStatusMissingArg) - } - c := getClient(context) - if _, err := c.DeleteCheckpoint(netcontext.Background(), &types.DeleteCheckpointRequest{ - Id: containerID, - Name: name, - CheckpointDir: context.String("checkpoint-dir"), - }); err != nil { - fatal(err.Error(), 1) - } - }, -} diff --git a/ctr/const.go b/ctr/const.go deleted file mode 100644 index 3af854b..0000000 --- a/ctr/const.go +++ /dev/null @@ -1,10 +0,0 @@ -package main - -// ctr wide constants -const ( - // ExitStatusOK indicates successful completion - ExitStatusOK = 0 - - // ExitStatusMissingArg indicates failure due to missing argument(s) - ExitStatusMissingArg = 1 -) diff --git a/ctr/container.go b/ctr/container.go deleted file mode 100644 index 7e15d3f..0000000 --- a/ctr/container.go +++ /dev/null @@ -1,684 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "io" - "io/ioutil" - "log" - "net" - "os" - "os/signal" - "path/filepath" - "strconv" - "strings" - "syscall" - "text/tabwriter" - "time" - - "github.com/codegangsta/cli" - "github.com/docker/containerd/api/grpc/types" - "github.com/docker/containerd/specs" - "github.com/docker/docker/pkg/term" - "github.com/golang/protobuf/ptypes" - netcontext "golang.org/x/net/context" - "google.golang.org/grpc" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/transport" -) - -// TODO: parse flags and pass opts -func getClient(ctx *cli.Context) types.APIClient { - // Parse proto://address form addresses. - bindSpec := ctx.GlobalString("address") - bindParts := strings.SplitN(bindSpec, "://", 2) - if len(bindParts) != 2 { - fatal(fmt.Sprintf("bad bind address format %s, expected proto://address", bindSpec), 1) - } - - // reset the logger for grpc to log to dev/null so that it does not mess with our stdio - grpclog.SetLogger(log.New(ioutil.Discard, "", log.LstdFlags)) - dialOpts := []grpc.DialOption{grpc.WithInsecure(), grpc.WithTimeout(ctx.GlobalDuration("conn-timeout"))} - dialOpts = append(dialOpts, - grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) { - return net.DialTimeout(bindParts[0], bindParts[1], timeout) - }, - )) - conn, err := grpc.Dial(bindSpec, dialOpts...) - if err != nil { - fatal(err.Error(), 1) - } - return types.NewAPIClient(conn) -} - -var contSubCmds = []cli.Command{ - execCommand, - killCommand, - listCommand, - pauseCommand, - resumeCommand, - startCommand, - stateCommand, - statsCommand, - watchCommand, - updateCommand, -} - -var containersCommand = cli.Command{ - Name: "containers", - Usage: "interact with running containers", - ArgsUsage: "COMMAND [arguments...]", - Subcommands: contSubCmds, - Description: func() string { - desc := "\n COMMAND:\n" - for _, command := range contSubCmds { - desc += fmt.Sprintf(" %-10.10s%s\n", command.Name, command.Usage) - } - return desc - }(), - Action: listContainers, -} - -var stateCommand = cli.Command{ - Name: "state", - Usage: "get a raw dump of the containerd state", - Action: func(context *cli.Context) { - c := getClient(context) - resp, err := c.State(netcontext.Background(), &types.StateRequest{ - Id: context.Args().First(), - }) - if err != nil { - fatal(err.Error(), 1) - } - data, err := json.Marshal(resp) - if err != nil { - fatal(err.Error(), 1) - } - fmt.Print(string(data)) - }, -} - -var listCommand = cli.Command{ - Name: "list", - Usage: "list all running containers", - Action: listContainers, -} - -func listContainers(context *cli.Context) { - c := getClient(context) - resp, err := c.State(netcontext.Background(), &types.StateRequest{ - Id: context.Args().First(), - }) - if err != nil { - fatal(err.Error(), 1) - } - w := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) - fmt.Fprint(w, "ID\tPATH\tSTATUS\tPROCESSES\n") - sortContainers(resp.Containers) - for _, c := range resp.Containers { - procs := []string{} - for _, p := range c.Processes { - procs = append(procs, p.Pid) - } - fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", c.Id, c.BundlePath, c.Status, strings.Join(procs, ",")) - } - if err := w.Flush(); err != nil { - fatal(err.Error(), 1) - } -} - -var startCommand = cli.Command{ - Name: "start", - Usage: "start a container", - ArgsUsage: "ID BundlePath", - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "checkpoint,c", - Value: "", - Usage: "checkpoint to start the container from", - }, - cli.StringFlag{ - Name: "checkpoint-dir", - Value: "", - Usage: "path to checkpoint directory", - }, - cli.BoolFlag{ - Name: "attach,a", - Usage: "connect to the stdio of the container", - }, - cli.StringSliceFlag{ - Name: "label,l", - Value: &cli.StringSlice{}, - Usage: "set labels for the container", - }, - cli.BoolFlag{ - Name: "no-pivot", - Usage: "do not use pivot root", - }, - cli.StringFlag{ - Name: "runtime,r", - Value: "runc", - Usage: "name or path of the OCI compliant runtime to use when executing containers", - }, - cli.StringSliceFlag{ - Name: "runtime-args", - Value: &cli.StringSlice{}, - Usage: "specify additional runtime args", - }, - }, - Action: func(context *cli.Context) { - var ( - id = context.Args().Get(0) - path = context.Args().Get(1) - ) - if path == "" { - fatal("bundle path cannot be empty", ExitStatusMissingArg) - } - if id == "" { - fatal("container id cannot be empty", ExitStatusMissingArg) - } - bpath, err := filepath.Abs(path) - if err != nil { - fatal(fmt.Sprintf("cannot get the absolute path of the bundle: %v", err), 1) - } - s, err := createStdio() - defer func() { - if s.stdin != "" { - os.RemoveAll(filepath.Dir(s.stdin)) - } - }() - if err != nil { - fatal(err.Error(), 1) - } - var ( - restoreAndCloseStdin func() - tty bool - c = getClient(context) - r = &types.CreateContainerRequest{ - Id: id, - BundlePath: bpath, - Checkpoint: context.String("checkpoint"), - CheckpointDir: context.String("checkpoint-dir"), - Stdin: s.stdin, - Stdout: s.stdout, - Stderr: s.stderr, - Labels: context.StringSlice("label"), - NoPivotRoot: context.Bool("no-pivot"), - Runtime: context.String("runtime"), - RuntimeArgs: context.StringSlice("runtime-args"), - } - ) - restoreAndCloseStdin = func() { - if state != nil { - term.RestoreTerminal(os.Stdin.Fd(), state) - } - if stdin != nil { - stdin.Close() - } - } - defer restoreAndCloseStdin() - if context.Bool("attach") { - mkterm, err := readTermSetting(bpath) - if err != nil { - fatal(err.Error(), 1) - } - tty = mkterm - if mkterm { - s, err := term.SetRawTerminal(os.Stdin.Fd()) - if err != nil { - fatal(err.Error(), 1) - } - state = s - } - if err := attachStdio(s); err != nil { - fatal(err.Error(), 1) - } - } - events, err := c.Events(netcontext.Background(), &types.EventsRequest{}) - if err != nil { - fatal(err.Error(), 1) - } - if _, err := c.CreateContainer(netcontext.Background(), r); err != nil { - fatal(err.Error(), 1) - } - if context.Bool("attach") { - go func() { - io.Copy(stdin, os.Stdin) - if _, err := c.UpdateProcess(netcontext.Background(), &types.UpdateProcessRequest{ - Id: id, - Pid: "init", - CloseStdin: true, - }); err != nil { - fatal(err.Error(), 1) - } - restoreAndCloseStdin() - }() - if tty { - resize(id, "init", c) - go func() { - s := make(chan os.Signal, 64) - signal.Notify(s, syscall.SIGWINCH) - for range s { - if err := resize(id, "init", c); err != nil { - log.Println(err) - } - } - }() - } - waitForExit(c, events, id, "init", restoreAndCloseStdin) - } - }, -} - -func resize(id, pid string, c types.APIClient) error { - ws, err := term.GetWinsize(os.Stdin.Fd()) - if err != nil { - return err - } - if _, err := c.UpdateProcess(netcontext.Background(), &types.UpdateProcessRequest{ - Id: id, - Pid: "init", - Width: uint32(ws.Width), - Height: uint32(ws.Height), - }); err != nil { - return err - } - return nil -} - -var ( - stdin io.WriteCloser - state *term.State -) - -// readTermSetting reads the Terminal option out of the specs configuration -// to know if ctr should allocate a pty -func readTermSetting(path string) (bool, error) { - f, err := os.Open(filepath.Join(path, "config.json")) - if err != nil { - return false, err - } - defer f.Close() - var spec specs.Spec - if err := json.NewDecoder(f).Decode(&spec); err != nil { - return false, err - } - return spec.Process.Terminal, nil -} - -func attachStdio(s stdio) error { - stdinf, err := os.OpenFile(s.stdin, syscall.O_RDWR, 0) - if err != nil { - return err - } - // FIXME: assign to global - stdin = stdinf - stdoutf, err := os.OpenFile(s.stdout, syscall.O_RDWR, 0) - if err != nil { - return err - } - go io.Copy(os.Stdout, stdoutf) - stderrf, err := os.OpenFile(s.stderr, syscall.O_RDWR, 0) - if err != nil { - return err - } - go io.Copy(os.Stderr, stderrf) - return nil -} - -var watchCommand = cli.Command{ - Name: "watch", - Usage: "print container events", - Action: func(context *cli.Context) { - c := getClient(context) - id := context.Args().First() - if id != "" { - resp, err := c.State(netcontext.Background(), &types.StateRequest{Id: id}) - if err != nil { - fatal(err.Error(), 1) - } - for _, c := range resp.Containers { - if c.Id == id { - break - } - } - if id == "" { - fatal("Invalid container id", 1) - } - } - events, reqErr := c.Events(netcontext.Background(), &types.EventsRequest{}) - if reqErr != nil { - fatal(reqErr.Error(), 1) - } - - for { - e, err := events.Recv() - if err != nil { - fatal(err.Error(), 1) - } - - if id == "" || e.Id == id { - fmt.Printf("%#v\n", e) - } - } - }, -} - -var pauseCommand = cli.Command{ - Name: "pause", - Usage: "pause a container", - Action: func(context *cli.Context) { - id := context.Args().First() - if id == "" { - fatal("container id cannot be empty", ExitStatusMissingArg) - } - c := getClient(context) - _, err := c.UpdateContainer(netcontext.Background(), &types.UpdateContainerRequest{ - Id: id, - Pid: "init", - Status: "paused", - }) - if err != nil { - fatal(err.Error(), 1) - } - }, -} - -var resumeCommand = cli.Command{ - Name: "resume", - Usage: "resume a paused container", - Action: func(context *cli.Context) { - id := context.Args().First() - if id == "" { - fatal("container id cannot be empty", ExitStatusMissingArg) - } - c := getClient(context) - _, err := c.UpdateContainer(netcontext.Background(), &types.UpdateContainerRequest{ - Id: id, - Pid: "init", - Status: "running", - }) - if err != nil { - fatal(err.Error(), 1) - } - }, -} - -var killCommand = cli.Command{ - Name: "kill", - Usage: "send a signal to a container or its processes", - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "pid,p", - Value: "init", - Usage: "pid of the process to signal within the container", - }, - cli.IntFlag{ - Name: "signal,s", - Value: 15, - Usage: "signal to send to the container", - }, - }, - Action: func(context *cli.Context) { - id := context.Args().First() - if id == "" { - fatal("container id cannot be empty", ExitStatusMissingArg) - } - c := getClient(context) - if _, err := c.Signal(netcontext.Background(), &types.SignalRequest{ - Id: id, - Pid: context.String("pid"), - Signal: uint32(context.Int("signal")), - }); err != nil { - fatal(err.Error(), 1) - } - }, -} - -var execCommand = cli.Command{ - Name: "exec", - Usage: "exec another process in an existing container", - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "id", - Usage: "container id to add the process to", - }, - cli.StringFlag{ - Name: "pid", - Usage: "process id for the new process", - }, - cli.BoolFlag{ - Name: "attach,a", - Usage: "connect to the stdio of the container", - }, - cli.StringFlag{ - Name: "cwd", - Usage: "current working directory for the process", - }, - cli.BoolFlag{ - Name: "tty,t", - Usage: "create a terminal for the process", - }, - cli.StringSliceFlag{ - Name: "env,e", - Value: &cli.StringSlice{}, - Usage: "environment variables for the process", - }, - cli.IntFlag{ - Name: "uid,u", - Usage: "user id of the user for the process", - }, - cli.IntFlag{ - Name: "gid,g", - Usage: "group id of the user for the process", - }, - }, - Action: func(context *cli.Context) { - var restoreAndCloseStdin func() - - p := &types.AddProcessRequest{ - Id: context.String("id"), - Pid: context.String("pid"), - Args: context.Args(), - Cwd: context.String("cwd"), - Terminal: context.Bool("tty"), - Env: context.StringSlice("env"), - User: &types.User{ - Uid: uint32(context.Int("uid")), - Gid: uint32(context.Int("gid")), - }, - } - s, err := createStdio() - defer func() { - if s.stdin != "" { - os.RemoveAll(filepath.Dir(s.stdin)) - } - }() - if err != nil { - fatal(err.Error(), 1) - } - p.Stdin = s.stdin - p.Stdout = s.stdout - p.Stderr = s.stderr - restoreAndCloseStdin = func() { - if state != nil { - term.RestoreTerminal(os.Stdin.Fd(), state) - } - if stdin != nil { - stdin.Close() - } - } - defer restoreAndCloseStdin() - if context.Bool("attach") { - if context.Bool("tty") { - s, err := term.SetRawTerminal(os.Stdin.Fd()) - if err != nil { - fatal(err.Error(), 1) - } - state = s - } - if err := attachStdio(s); err != nil { - fatal(err.Error(), 1) - } - } - c := getClient(context) - events, err := c.Events(netcontext.Background(), &types.EventsRequest{}) - if err != nil { - fatal(err.Error(), 1) - } - if _, err := c.AddProcess(netcontext.Background(), p); err != nil { - fatal(err.Error(), 1) - } - if context.Bool("attach") { - go func() { - io.Copy(stdin, os.Stdin) - if _, err := c.UpdateProcess(netcontext.Background(), &types.UpdateProcessRequest{ - Id: p.Id, - Pid: p.Pid, - CloseStdin: true, - }); err != nil { - log.Println(err) - } - restoreAndCloseStdin() - }() - if context.Bool("tty") { - resize(p.Id, p.Pid, c) - go func() { - s := make(chan os.Signal, 64) - signal.Notify(s, syscall.SIGWINCH) - for range s { - if err := resize(p.Id, p.Pid, c); err != nil { - log.Println(err) - } - } - }() - } - waitForExit(c, events, context.String("id"), context.String("pid"), restoreAndCloseStdin) - } - }, -} - -var statsCommand = cli.Command{ - Name: "stats", - Usage: "get stats for running container", - Action: func(context *cli.Context) { - req := &types.StatsRequest{ - Id: context.Args().First(), - } - c := getClient(context) - stats, err := c.Stats(netcontext.Background(), req) - if err != nil { - fatal(err.Error(), 1) - } - data, err := json.Marshal(stats) - if err != nil { - fatal(err.Error(), 1) - } - fmt.Print(string(data)) - }, -} - -func getUpdateCommandInt64Flag(context *cli.Context, name string) uint64 { - str := context.String(name) - if str == "" { - return 0 - } - - val, err := strconv.ParseUint(str, 0, 64) - if err != nil { - fatal(err.Error(), 1) - } - - return val -} - -var updateCommand = cli.Command{ - Name: "update", - Usage: "update a containers resources", - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "memory-limit", - }, - cli.StringFlag{ - Name: "memory-reservation", - }, - cli.StringFlag{ - Name: "memory-swap", - }, - cli.StringFlag{ - Name: "cpu-quota", - }, - cli.StringFlag{ - Name: "cpu-period", - }, - cli.StringFlag{ - Name: "kernel-limit", - }, - cli.StringFlag{ - Name: "kernel-tcp-limit", - }, - cli.StringFlag{ - Name: "blkio-weight", - }, - cli.StringFlag{ - Name: "cpuset-cpus", - }, - cli.StringFlag{ - Name: "cpuset-mems", - }, - }, - Action: func(context *cli.Context) { - req := &types.UpdateContainerRequest{ - Id: context.Args().First(), - } - req.Resources = &types.UpdateResource{} - req.Resources.MemoryLimit = getUpdateCommandInt64Flag(context, "memory-limit") - req.Resources.MemoryReservation = getUpdateCommandInt64Flag(context, "memory-reservation") - req.Resources.MemorySwap = getUpdateCommandInt64Flag(context, "memory-swap") - req.Resources.BlkioWeight = getUpdateCommandInt64Flag(context, "blkio-weight") - req.Resources.CpuPeriod = getUpdateCommandInt64Flag(context, "cpu-period") - req.Resources.CpuQuota = getUpdateCommandInt64Flag(context, "cpu-quota") - req.Resources.CpuShares = getUpdateCommandInt64Flag(context, "cpu-shares") - req.Resources.CpusetCpus = context.String("cpuset-cpus") - req.Resources.CpusetMems = context.String("cpuset-mems") - req.Resources.KernelMemoryLimit = getUpdateCommandInt64Flag(context, "kernel-limit") - req.Resources.KernelTCPMemoryLimit = getUpdateCommandInt64Flag(context, "kernel-tcp-limit") - c := getClient(context) - if _, err := c.UpdateContainer(netcontext.Background(), req); err != nil { - fatal(err.Error(), 1) - } - }, -} - -func waitForExit(c types.APIClient, events types.API_EventsClient, id, pid string, closer func()) { - timestamp := time.Now() - for { - e, err := events.Recv() - if err != nil { - if grpc.ErrorDesc(err) == transport.ErrConnClosing.Desc { - closer() - os.Exit(128 + int(syscall.SIGHUP)) - } - time.Sleep(1 * time.Second) - tsp, err := ptypes.TimestampProto(timestamp) - if err != nil { - closer() - fmt.Fprintf(os.Stderr, "%s", err.Error()) - os.Exit(1) - } - events, _ = c.Events(netcontext.Background(), &types.EventsRequest{Timestamp: tsp}) - continue - } - timestamp, err = ptypes.Timestamp(e.Timestamp) - if e.Id == id && e.Type == "exit" && e.Pid == pid { - closer() - os.Exit(int(e.Status)) - } - } -} - -type stdio struct { - stdin string - stdout string - stderr string -} diff --git a/ctr/container_linux.go b/ctr/container_linux.go deleted file mode 100644 index a297ea2..0000000 --- a/ctr/container_linux.go +++ /dev/null @@ -1,28 +0,0 @@ -package main - -import ( - "io/ioutil" - "os" - "path/filepath" - "syscall" -) - -func createStdio() (s stdio, err error) { - tmp, err := ioutil.TempDir("", "ctr-") - if err != nil { - return s, err - } - // create fifo's for the process - for name, fd := range map[string]*string{ - "stdin": &s.stdin, - "stdout": &s.stdout, - "stderr": &s.stderr, - } { - path := filepath.Join(tmp, name) - if err := syscall.Mkfifo(path, 0755); err != nil && !os.IsExist(err) { - return s, err - } - *fd = path - } - return s, nil -} diff --git a/ctr/container_solaris.go b/ctr/container_solaris.go deleted file mode 100644 index 521a994..0000000 --- a/ctr/container_solaris.go +++ /dev/null @@ -1,9 +0,0 @@ -package main - -import ( - "errors" -) - -func createStdio() (s stdio, err error) { - return s, errors.New("createStdio not implemented on Solaris") -} diff --git a/ctr/events.go b/ctr/events.go deleted file mode 100644 index d65cebf..0000000 --- a/ctr/events.go +++ /dev/null @@ -1,63 +0,0 @@ -package main - -import ( - "fmt" - "os" - "text/tabwriter" - "time" - - "github.com/codegangsta/cli" - "github.com/docker/containerd/api/grpc/types" - "github.com/golang/protobuf/ptypes" - netcontext "golang.org/x/net/context" -) - -var eventsCommand = cli.Command{ - Name: "events", - Usage: "receive events from the containerd daemon", - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "timestamp,t", - Usage: "get events from a specific time stamp in RFC3339Nano format", - }, - }, - Action: func(context *cli.Context) { - var ( - t = time.Time{} - c = getClient(context) - ) - if ts := context.String("timestamp"); ts != "" { - from, err := time.Parse(time.RFC3339Nano, ts) - if err != nil { - fatal(err.Error(), 1) - } - t = from - } - tsp, err := ptypes.TimestampProto(t) - if err != nil { - fatal(err.Error(), 1) - } - events, err := c.Events(netcontext.Background(), &types.EventsRequest{ - Timestamp: tsp, - }) - if err != nil { - fatal(err.Error(), 1) - } - w := tabwriter.NewWriter(os.Stdout, 31, 1, 1, ' ', 0) - fmt.Fprint(w, "TIME\tTYPE\tID\tPID\tSTATUS\n") - w.Flush() - for { - e, err := events.Recv() - if err != nil { - fatal(err.Error(), 1) - } - t, err := ptypes.Timestamp(e.Timestamp) - if err != nil { - fmt.Fprintf(os.Stderr, "Unable to convert timestamp") - t = time.Time{} - } - fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%d\n", t.Format(time.RFC3339Nano), e.Type, e.Id, e.Pid, e.Status) - w.Flush() - } - }, -} diff --git a/ctr/main.go b/ctr/main.go deleted file mode 100644 index 85ed049..0000000 --- a/ctr/main.go +++ /dev/null @@ -1,90 +0,0 @@ -package main - -import ( - "fmt" - "os" - "time" - - netcontext "golang.org/x/net/context" - - "github.com/Sirupsen/logrus" - "github.com/codegangsta/cli" - "github.com/docker/containerd" - "github.com/docker/containerd/api/grpc/types" -) - -const usage = `High performance container daemon cli` - -type exit struct { - Code int -} - -func main() { - // We want our defer functions to be run when calling fatal() - defer func() { - if e := recover(); e != nil { - if ex, ok := e.(exit); ok == true { - os.Exit(ex.Code) - } - panic(e) - } - }() - app := cli.NewApp() - app.Name = "ctr" - if containerd.GitCommit != "" { - app.Version = fmt.Sprintf("%s commit: %s", containerd.Version, containerd.GitCommit) - } else { - app.Version = containerd.Version - } - app.Usage = usage - app.Flags = []cli.Flag{ - cli.BoolFlag{ - Name: "debug", - Usage: "enable debug output in the logs", - }, - cli.StringFlag{ - Name: "address", - Value: "unix:///run/containerd/containerd.sock", - Usage: "proto://address of GRPC API", - }, - cli.DurationFlag{ - Name: "conn-timeout", - Value: 1 * time.Second, - Usage: "GRPC connection timeout", - }, - } - app.Commands = []cli.Command{ - checkpointCommand, - containersCommand, - eventsCommand, - stateCommand, - versionCommand, - } - app.Before = func(context *cli.Context) error { - if context.GlobalBool("debug") { - logrus.SetLevel(logrus.DebugLevel) - } - return nil - } - if err := app.Run(os.Args); err != nil { - logrus.Fatal(err) - } -} - -var versionCommand = cli.Command{ - Name: "version", - Usage: "return the daemon version", - Action: func(context *cli.Context) { - c := getClient(context) - resp, err := c.GetServerVersion(netcontext.Background(), &types.GetServerVersionRequest{}) - if err != nil { - fatal(err.Error(), 1) - } - fmt.Printf("daemon version %d.%d.%d commit: %s\n", resp.Major, resp.Minor, resp.Patch, resp.Revision) - }, -} - -func fatal(err string, code int) { - fmt.Fprintf(os.Stderr, "[ctr] %s\n", err) - panic(exit{code}) -} diff --git a/ctr/sort.go b/ctr/sort.go deleted file mode 100644 index fbd090b..0000000 --- a/ctr/sort.go +++ /dev/null @@ -1,27 +0,0 @@ -package main - -import ( - "sort" - - "github.com/docker/containerd/api/grpc/types" -) - -func sortContainers(c []*types.Container) { - sort.Sort(&containerSorter{c}) -} - -type containerSorter struct { - c []*types.Container -} - -func (s *containerSorter) Len() int { - return len(s.c) -} - -func (s *containerSorter) Swap(i, j int) { - s.c[i], s.c[j] = s.c[j], s.c[i] -} - -func (s *containerSorter) Less(i, j int) bool { - return s.c[i].Id < s.c[j].Id -} diff --git a/docs/api.md b/docs/api.md deleted file mode 100644 index 24336d3..0000000 --- a/docs/api.md +++ /dev/null @@ -1,6 +0,0 @@ -# API - -The API for containerd is with GRPC over a unix socket located at the default location of `/run/containerd/containerd.sock`. - -At this time please refer to the [proto at](https://github.com/docker/containerd/blob/master/api/grpc/types/api.proto) for the API methods and types. -There is a Go implementation and types checked into this repository but alternate language implementations can be created using the grpc and protoc toolchain. diff --git a/docs/attach.md b/docs/attach.md deleted file mode 100644 index e109ec5..0000000 --- a/docs/attach.md +++ /dev/null @@ -1,36 +0,0 @@ -# Attaching to STDIO or TTY - -The model for STDIO, TTY, and logging is a little different in containerd. -Because of the various methods that consumers want on the logging side these types of decisions -are pushed to the client. -Containerd API is developed for access on a single host therefore many things like paths on the host system are acceptable in the API. -For the STDIO model the client requesting to start a container provides the paths for the IO. - -## Logging - -If no options are specified on create all STDIO of the processes launched by containerd will be sent to `/dev/null`. -If you want containerd to send the STDIO of the processes to a file, you can pass paths to the files in the create container method defined by this proto in the stdin, stdout, and stderr fields: - -```proto -message CreateContainerRequest { - string id = 1; // ID of container - string bundlePath = 2; // path to OCI bundle - string stdin = 3; // path to the file where stdin will be read (optional) - string stdout = 4; // path to file where stdout will be written (optional) - string stderr = 5; // path to file where stderr will be written (optional) - string console = 6; // path to the console for a container (optional) - string checkpoint = 7; // checkpoint name if you want to create immediate checkpoint (optional) -} -``` - -## Attach - -In order to have attach like functionality for your containers you use the same API request but named pipes or fifos can be used to achieve this type of functionality. -The default CLI for containerd does this if you specify the `--attach` flag on `create` or `start`. -It will create fifos for each of the containers stdio which the CLI can read and write to. -This can be used to create an interactive session with the container, `bash` for example, or to have a blocking way to collect the container's STDIO and forward it to your logging facilities. - -## TTY - -The tty model is the same as above only the client creates a pty and provides to other side to containerd in the create request in the `console` field. -Containerd will provide the pty to the container to use and the session can be opened with the container after it starts. diff --git a/docs/bundle-changes.md b/docs/bundle-changes.md deleted file mode 100644 index 7e32df0..0000000 --- a/docs/bundle-changes.md +++ /dev/null @@ -1,12 +0,0 @@ -# containerd changes to the bundle - -Containerd will make changes to the container's bundle by adding additional files or folders by default with -options to change the output. - -The current change that it makes is if you create a checkpoint of a container, the checkpoints will be saved -by default in the container bundle at `{bundle}/checkpoints/{checkpoint name}`. -A user can also populate this directory and provide the checkpoint name on the create request so that the container is started from this checkpoint. - - -As of this point, containerd has no other additions to the bundle. -Runtime state is currently stored in a tmpfs filesystem like `/run`. diff --git a/docs/bundle.md b/docs/bundle.md deleted file mode 100644 index 36a123b..0000000 --- a/docs/bundle.md +++ /dev/null @@ -1,208 +0,0 @@ -# Creating OCI bundles - -Since containerd consumes the OCI bundle format containers and configuration will have to be created -on the machine that containerd is running on. The easiest way to do this is to download an image -with docker and export it. - - -## Setup - -First thing we need to do to create a bundle is setup the initial directory structure. -Create a directory with a unique name. In this example we will create a redis container. -We will create this container in a `/containers` directory. - - -```bash -mkdir redis -``` - -Inside the `redis` directory create another directory named `rootfs` - -```bash -mkdir redis/rootfs -``` - -## Root Filesystem - -Now we need to populate the `rootfs` directory with the filesystem of a redis container. To do this we -need to pull the redis image with docker and export its contents to the `rootfs` directory. - -```bash -docker pull redis - -# create the container with a temp name so that we can export it -docker create --name tempredis redis - -# export it into the rootfs directory -docker export tempredis | tar -C redis/rootfs -xf - - -# remove the container now that we have exported -docker rm tempredis -``` - -Now that we have the root filesystem populated we need to create the configs for the container. - -## Configs - -An easy way to get temp configs for the container bundle is to use the `runc` -cli tool from the [runc](https://github.com/opencontainers/runc) repository. - - -You need to `cd` into the `redis` directory and run the `runc spec` command. After doing this you -should have a file `config.json` created. The directory structure should look like this: - -``` -/containers/redis -├── config.json -└── rootfs/ -``` - -## Edits - -We need to edit the config to add `redis-server` as the application to launch inside the container, -and remove the network namespace so that you can connect to the redis server on your system. -The resulting `config.json` should look like this: - -```json -{ - "ociVersion": "0.4.0", - "platform": { - "os": "linux", - "arch": "amd64" - }, - "process": { - "terminal": true, - "user": {}, - "args": [ - "redis-server", "--bind", "0.0.0.0" - ], - "env": [ - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", - "TERM=xterm" - ], - "cwd": "/", - "capabilities": [ - "CAP_AUDIT_WRITE", - "CAP_KILL", - "CAP_NET_BIND_SERVICE" - ], - "rlimits": [ - { - "type": "RLIMIT_NOFILE", - "hard": 1024, - "soft": 1024 - } - ], - "noNewPrivileges": true - }, - "root": { - "path": "rootfs", - "readonly": true - }, - "hostname": "runc", - "mounts": [ - { - "destination": "/proc", - "type": "proc", - "source": "proc" - }, - { - "destination": "/dev", - "type": "tmpfs", - "source": "tmpfs", - "options": [ - "nosuid", - "strictatime", - "mode=755", - "size=65536k" - ] - }, - { - "destination": "/dev/pts", - "type": "devpts", - "source": "devpts", - "options": [ - "nosuid", - "noexec", - "newinstance", - "ptmxmode=0666", - "mode=0620", - "gid=5" - ] - }, - { - "destination": "/dev/shm", - "type": "tmpfs", - "source": "shm", - "options": [ - "nosuid", - "noexec", - "nodev", - "mode=1777", - "size=65536k" - ] - }, - { - "destination": "/dev/mqueue", - "type": "mqueue", - "source": "mqueue", - "options": [ - "nosuid", - "noexec", - "nodev" - ] - }, - { - "destination": "/sys", - "type": "sysfs", - "source": "sysfs", - "options": [ - "nosuid", - "noexec", - "nodev", - "ro" - ] - }, - { - "destination": "/sys/fs/cgroup", - "type": "cgroup", - "source": "cgroup", - "options": [ - "nosuid", - "noexec", - "nodev", - "relatime", - "ro" - ] - } - ], - "hooks": {}, - "linux": { - "resources": { - "devices": [ - { - "allow": false, - "access": "rwm" - } - ] - }, - "namespaces": [ - { - "type": "pid" - }, - { - "type": "ipc" - }, - { - "type": "uts" - }, - { - "type": "mount" - } - ], - "devices": null - } -} -``` - -This is what you need to do to make a OCI compliant bundle for containerd to start. diff --git a/docs/cli.md b/docs/cli.md deleted file mode 100644 index 88ee7a3..0000000 --- a/docs/cli.md +++ /dev/null @@ -1,159 +0,0 @@ -# Client CLI - -There is a default cli named `ctr` based on the GRPC api. -This cli will allow you to create and manage containers run with containerd. - -``` -$ ctr -h -NAME: - ctr - High performance container daemon cli - -USAGE: - ctr [global options] command [command options] [arguments...] - -VERSION: - 0.1.0 commit: 54c213e8a719d734001beb2cb8f130c84cc3bd20 - -COMMANDS: - checkpoints list all checkpoints - containers interact with running containers - events receive events from the containerd daemon - state get a raw dump of the containerd state - help, h Shows a list of commands or help for one command - -GLOBAL OPTIONS: - --debug enable debug output in the logs - --address "/run/containerd/containerd.sock" address of GRPC API - --help, -h show help - --version, -v print the version -``` - -## Starting a container - -``` -$ ctr containers start -h -NAME: - ctr containers start - start a container - -USAGE: - ctr containers start [command options] [arguments...] - -OPTIONS: - --checkpoint, -c checkpoint to start the container from - --attach, -a connect to the stdio of the container - --label, -l [--label option --label option] set labels for the container -``` - -```bash -$ sudo ctr containers start redis /containers/redis -``` - -`/containers/redis` is the path to an OCI bundle. [See the bundle docs for more information.](bundle.md) - -## Listing containers - -```bash -$ sudo ctr containers -ID PATH STATUS PROCESSES -1 /containers/redis running 14063 -19 /containers/redis running 14100 -14 /containers/redis running 14117 -4 /containers/redis running 14030 -16 /containers/redis running 14061 -3 /containers/redis running 14024 -12 /containers/redis running 14097 -10 /containers/redis running 14131 -18 /containers/redis running 13977 -13 /containers/redis running 13979 -15 /containers/redis running 13998 -5 /containers/redis running 14021 -9 /containers/redis running 14075 -6 /containers/redis running 14107 -2 /containers/redis running 14135 -11 /containers/redis running 13978 -17 /containers/redis running 13989 -8 /containers/redis running 14053 -7 /containers/redis running 14022 -0 /containers/redis running 14006 -``` - -## Kill a container's process - -``` -$ ctr containers kill -h -NAME: - ctr containers kill - send a signal to a container or its processes - -USAGE: - ctr containers kill [command options] [arguments...] - -OPTIONS: - --pid, -p "init" pid of the process to signal within the container - --signal, -s "15" signal to send to the container -``` - -## Exec another process into a container - -``` -$ ctr containers exec -h -NAME: - ctr containers exec - exec another process in an existing container - -USAGE: - ctr containers exec [command options] [arguments...] - -OPTIONS: - --id container id to add the process to - --pid process id for the new process - --attach, -a connect to the stdio of the container - --cwd current working directory for the process - --tty, -t create a terminal for the process - --env, -e [--env option --env option] environment variables for the process - --uid, -u "0" user id of the user for the process - --gid, -g "0" group id of the user for the process -``` - -## Stats for a container - -``` -$ ctr containers stats -h -NAME: - ctr containers stats - get stats for running container - -USAGE: - ctr containers stats [arguments...] -``` - -## List checkpoints - -``` -$ sudo ctr checkpoints redis -NAME TCP UNIX SOCKETS SHELL -test false false false -test2 false false false -``` - -## Create a new checkpoint - -``` -$ ctr checkpoints create -h -NAME: - ctr checkpoints create - create a new checkpoint for the container - -USAGE: - ctr checkpoints create [command options] [arguments...] - -OPTIONS: - --tcp persist open tcp connections - --unix-sockets perist unix sockets - --exit exit the container after the checkpoint completes successfully - --shell checkpoint shell jobs -``` - -## Get events - -``` -$ sudo ctr events -TYPE ID PID STATUS -exit redis 24761 0 -``` diff --git a/docs/daemon.md b/docs/daemon.md deleted file mode 100644 index d656a04..0000000 --- a/docs/daemon.md +++ /dev/null @@ -1,27 +0,0 @@ -# Daemon options - -``` -$ containerd -h - -NAME: - containerd - High performance container daemon - -USAGE: - containerd [global options] command [command options] [arguments...] - -VERSION: - 0.1.0 commit: 54c213e8a719d734001beb2cb8f130c84cc3bd20 - -COMMANDS: - help, h Shows a list of commands or help for one command - -GLOBAL OPTIONS: - --debug enable debug output in the logs - --state-dir "/run/containerd" runtime state directory - --metrics-interval "5m0s" interval for flushing metrics to the store - --listen, -l "/run/containerd/containerd.sock" Address on which GRPC API will listen - --runtime, -r "runc" name of the OCI compliant runtime to use when executing containers - --graphite-address Address of graphite server - --help, -h show help - --version, -v print the version -``` diff --git a/docs/telemetry.md b/docs/telemetry.md deleted file mode 100644 index 1ac869c..0000000 --- a/docs/telemetry.md +++ /dev/null @@ -1,31 +0,0 @@ -# Telemetry - -Currently containerd only outputs metrics to stdout but will support dumping to various backends in the future. - -``` -[containerd] 2015/12/16 11:48:28 timer container-start-time -[containerd] 2015/12/16 11:48:28 count: 22 -[containerd] 2015/12/16 11:48:28 min: 25425883 -[containerd] 2015/12/16 11:48:28 max: 113077691 -[containerd] 2015/12/16 11:48:28 mean: 68386923.27 -[containerd] 2015/12/16 11:48:28 stddev: 20928453.26 -[containerd] 2015/12/16 11:48:28 median: 65489003.50 -[containerd] 2015/12/16 11:48:28 75%: 82393210.50 -[containerd] 2015/12/16 11:48:28 95%: 112267814.75 -[containerd] 2015/12/16 11:48:28 99%: 113077691.00 -[containerd] 2015/12/16 11:48:28 99.9%: 113077691.00 -[containerd] 2015/12/16 11:48:28 1-min rate: 0.00 -[containerd] 2015/12/16 11:48:28 5-min rate: 0.01 -[containerd] 2015/12/16 11:48:28 15-min rate: 0.01 -[containerd] 2015/12/16 11:48:28 mean rate: 0.03 -[containerd] 2015/12/16 11:48:28 counter containers -[containerd] 2015/12/16 11:48:28 count: 1 -[containerd] 2015/12/16 11:48:28 counter events -[containerd] 2015/12/16 11:48:28 count: 87 -[containerd] 2015/12/16 11:48:28 counter events-subscribers -[containerd] 2015/12/16 11:48:28 count: 2 -[containerd] 2015/12/16 11:48:28 gauge goroutines -[containerd] 2015/12/16 11:48:28 value: 38 -[containerd] 2015/12/16 11:48:28 gauge fds -[containerd] 2015/12/16 11:48:28 value: 18 -``` diff --git a/hack/benchmark.go b/hack/benchmark.go deleted file mode 100644 index aa537de..0000000 --- a/hack/benchmark.go +++ /dev/null @@ -1,75 +0,0 @@ -// single app that will run containers in containerd and output -// the total time in seconds that it took for the execution. -// go run benchmark.go -count 1000 -bundle /containers/redis -package main - -import ( - "flag" - "net" - "strconv" - "sync" - "time" - - "github.com/Sirupsen/logrus" - "github.com/docker/containerd/api/grpc/types" - netcontext "golang.org/x/net/context" - "google.golang.org/grpc" -) - -func init() { - flag.StringVar(&bundle, "bundle", "/containers/redis", "the bundle path") - flag.StringVar(&addr, "addr", "/run/containerd/containerd.sock", "address to the container d instance") - flag.IntVar(&count, "count", 1000, "number of containers to run") - flag.Parse() -} - -var ( - count int - bundle, addr string - group = sync.WaitGroup{} - jobs = make(chan string, 20) -) - -func getClient() types.APIClient { - dialOpts := []grpc.DialOption{grpc.WithInsecure()} - dialOpts = append(dialOpts, - grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) { - return net.DialTimeout("unix", addr, timeout) - }, - )) - conn, err := grpc.Dial(addr, dialOpts...) - if err != nil { - logrus.Fatal(err) - } - return types.NewAPIClient(conn) -} - -func main() { - client := getClient() - for i := 0; i < 100; i++ { - group.Add(1) - go worker(client) - } - start := time.Now() - for i := 0; i < count; i++ { - id := strconv.Itoa(i) - jobs <- id - } - close(jobs) - group.Wait() - end := time.Now() - duration := end.Sub(start).Seconds() - logrus.Info(duration) -} - -func worker(client types.APIClient) { - defer group.Done() - for id := range jobs { - if _, err := client.CreateContainer(netcontext.Background(), &types.CreateContainerRequest{ - Id: id, - BundlePath: bundle, - }); err != nil { - logrus.Error(err) - } - } -} diff --git a/example/main.go b/hack/example/main.go similarity index 100% rename from example/main.go rename to hack/example/main.go diff --git a/example/utils.go b/hack/example/utils.go similarity index 100% rename from example/utils.go rename to hack/example/utils.go diff --git a/integration-test/bundle_utils_test.go b/integration-test/bundle_utils_test.go deleted file mode 100644 index f110ead..0000000 --- a/integration-test/bundle_utils_test.go +++ /dev/null @@ -1,111 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "os" - "os/exec" - "path/filepath" - "reflect" - - utils "github.com/docker/containerd/testutils" - ocs "github.com/opencontainers/runtime-spec/specs-go" -) - -type OciProcessArgs struct { - Cmd string - Args []string -} - -type Bundle struct { - Source string - Name string - Spec ocs.Spec - Path string -} - -var bundleMap map[string]Bundle - -// untarRootfs untars the given `source` tarPath into `destination/rootfs` -func untarRootfs(source string, destination string) error { - destination = filepath.Join(destination, "rootfs") - if err := os.MkdirAll(destination, 0755); err != nil { - return nil - } - tar := exec.Command("tar", "-C", destination, "-xf", source) - return tar.Run() -} - -// CreateBundleWithFilter generate a new oci-bundle named `name` from -// the provide `source` rootfs. It starts from the default spec -// generated by `runc spec`, overrides the `spec.Process.Args` value -// with `args` and set `spec.Process.Terminal` to false. It then apply -// `filter()` to the resulting spec if it is provided. -func CreateBundleWithFilter(source, name string, args []string, filter func(spec *ocs.Spec)) error { - // Generate the spec - var spec ocs.Spec - f, err := os.Open(utils.RefOciSpecsPath) - if err != nil { - return fmt.Errorf("Failed to open default spec: %v", err) - } - if err := json.NewDecoder(f).Decode(&spec); err != nil { - return fmt.Errorf("Failed to load default spec: %v", err) - } - f.Close() - - spec.Process.Args = args - spec.Process.Terminal = false - if filter != nil { - filter(&spec) - } - - bundlePath := filepath.Join(utils.BundlesRoot, name) - nb := Bundle{source, name, spec, bundlePath} - - // Check that we don't already have such a bundle - if b, ok := bundleMap[name]; ok { - if reflect.DeepEqual(b, nb) == false { - return fmt.Errorf("A bundle name named '%s' already exist but with different properties! %#v != %#v", - name, b, nb) - } - return nil - } - - // Nothing should be there, but just in case - os.RemoveAll(bundlePath) - - if err := untarRootfs(filepath.Join(utils.ArchivesDir, source+".tar"), bundlePath); err != nil { - return fmt.Errorf("Failed to untar %s.tar: %v", source, err) - } - - // create a place for the io fifo - if err := os.Mkdir(filepath.Join(bundlePath, "io"), 0755); err != nil { - return fmt.Errorf("Failed to create bundle io directory: %v", err) - } - - // Write the updated spec to the right location - config, e := os.Create(filepath.Join(bundlePath, "config.json")) - if e != nil { - return fmt.Errorf("Failed to create oci spec: %v", e) - } - defer config.Close() - - if err := json.NewEncoder(config).Encode(&spec); err != nil { - return fmt.Errorf("Failed to encore oci spec: %v", e) - } - - bundleMap[name] = nb - return nil -} - -func GetBundle(name string) *Bundle { - bundle, ok := bundleMap[name] - if !ok { - return nil - } - return &bundle -} - -func CreateBusyboxBundle(name string, args []string) error { - return CreateBundleWithFilter("busybox", name, args, nil) -} diff --git a/integration-test/check_test.go b/integration-test/check_test.go deleted file mode 100644 index 6b32415..0000000 --- a/integration-test/check_test.go +++ /dev/null @@ -1,278 +0,0 @@ -package main - -import ( - "fmt" - "io/ioutil" - "log" - "net" - "os" - "os/exec" - "path/filepath" - "strings" - "sync" - "testing" - "time" - - "golang.org/x/net/context" - - "google.golang.org/grpc" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/health/grpc_health_v1" - - "github.com/docker/containerd/api/grpc/types" - utils "github.com/docker/containerd/testutils" - "github.com/go-check/check" - "github.com/golang/protobuf/ptypes/timestamp" -) - -func Test(t *testing.T) { - check.TestingT(t) -} - -func init() { - check.Suite(&ContainerdSuite{}) -} - -type ContainerdSuite struct { - cwd string - outputDir string - stateDir string - grpcSocket string - logFile *os.File - cd *exec.Cmd - syncChild chan error - grpcClient types.APIClient - eventFiltersMutex sync.Mutex - eventFilters map[string]func(event *types.Event) - lastEventTs *timestamp.Timestamp -} - -// getClient returns a connection to the Suite containerd -func (cs *ContainerdSuite) getClient(socket string) error { - // Parse proto://address form addresses. - bindParts := strings.SplitN(socket, "://", 2) - if len(bindParts) != 2 { - return fmt.Errorf("bad bind address format %s, expected proto://address", socket) - } - - // reset the logger for grpc to log to dev/null so that it does not mess with our stdio - grpclog.SetLogger(log.New(ioutil.Discard, "", log.LstdFlags)) - dialOpts := []grpc.DialOption{grpc.WithInsecure()} - dialOpts = append(dialOpts, - grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) { - return net.DialTimeout(bindParts[0], bindParts[1], timeout) - }), - grpc.WithBlock(), - grpc.WithTimeout(5*time.Second), - ) - conn, err := grpc.Dial(socket, dialOpts...) - if err != nil { - return err - } - healthClient := grpc_health_v1.NewHealthClient(conn) - if _, err := healthClient.Check(context.Background(), &grpc_health_v1.HealthCheckRequest{}); err != nil { - return err - } - cs.grpcClient = types.NewAPIClient(conn) - - return nil -} - -// ContainerdEventsHandler will process all events coming from -// containerd. If a filter as been register for a given container id -// via `SetContainerEventFilter()`, it will be invoked every time an -// event for that id is received -func (cs *ContainerdSuite) ContainerdEventsHandler(events types.API_EventsClient) { - for { - e, err := events.Recv() - if err != nil { - // If daemon died or exited, return - if strings.Contains(err.Error(), "transport is closing") { - break - } - time.Sleep(1 * time.Second) - events, _ = cs.grpcClient.Events(context.Background(), &types.EventsRequest{Timestamp: cs.lastEventTs}) - continue - } - cs.lastEventTs = e.Timestamp - cs.eventFiltersMutex.Lock() - if f, ok := cs.eventFilters[e.Id]; ok { - f(e) - if e.Type == "exit" && e.Pid == "init" { - delete(cs.eventFilters, e.Id) - } - } - cs.eventFiltersMutex.Unlock() - } -} - -func (cs *ContainerdSuite) StopDaemon(kill bool) { - if cs.cd == nil { - return - } - - if kill { - cs.cd.Process.Kill() - <-cs.syncChild - cs.cd = nil - } else { - // Terminate gently if possible - cs.cd.Process.Signal(os.Interrupt) - - done := false - for done == false { - select { - case err := <-cs.syncChild: - if err != nil { - fmt.Printf("master containerd did not exit cleanly: %v\n", err) - } - done = true - case <-time.After(3 * time.Second): - fmt.Println("Timeout while waiting for containerd to exit, killing it!") - cs.cd.Process.Kill() - } - } - } -} - -func (cs *ContainerdSuite) RestartDaemon(kill bool) error { - cs.StopDaemon(kill) - - cd := exec.Command("containerd", "--debug", - "--state-dir", cs.stateDir, - "--listen", cs.grpcSocket, - "--metrics-interval", "0m0s", - "--runtime-args", fmt.Sprintf("--root=%s", filepath.Join(cs.cwd, cs.outputDir, "runc")), - ) - cd.Stderr = cs.logFile - cd.Stdout = cs.logFile - - if err := cd.Start(); err != nil { - return err - } - cs.cd = cd - - if err := cs.getClient(cs.grpcSocket); err != nil { - // Kill the daemon - cs.cd.Process.Kill() - return err - } - - // Monitor events - events, err := cs.grpcClient.Events(context.Background(), &types.EventsRequest{Timestamp: cs.lastEventTs}) - if err != nil { - return err - } - - go cs.ContainerdEventsHandler(events) - - go func() { - cs.syncChild <- cd.Wait() - }() - - return nil -} - -func (cs *ContainerdSuite) SetUpSuite(c *check.C) { - bundleMap = make(map[string]Bundle) - cs.eventFilters = make(map[string]func(event *types.Event)) - - // Get working directory for tests - wd := utils.GetTestOutDir() - if err := os.Chdir(wd); err != nil { - c.Fatalf("Could not change working directory: %v", err) - } - cs.cwd = wd - - // Clean old bundles - os.RemoveAll(utils.BundlesRoot) - - // Ensure the oci bundles directory exists - if err := os.MkdirAll(utils.BundlesRoot, 0755); err != nil { - c.Fatalf("Failed to create bundles directory: %v", err) - } - - // Generate the reference spec - if err := utils.GenerateReferenceSpecs(utils.BundlesRoot); err != nil { - c.Fatalf("Unable to generate OCI reference spec: %v", err) - } - - // Create our output directory - cs.outputDir = fmt.Sprintf(utils.OutputDirFormat, time.Now().Format("2006-01-02_150405.000000")) - - cs.stateDir = filepath.Join(cs.outputDir, "containerd-master") - if err := os.MkdirAll(cs.stateDir, 0755); err != nil { - c.Fatalf("Unable to created output directory '%s': %v", cs.stateDir, err) - } - - cs.grpcSocket = "unix://" + filepath.Join(cs.outputDir, "containerd-master", "containerd.sock") - cdLogFile := filepath.Join(cs.outputDir, "containerd-master", "containerd.log") - - f, err := os.OpenFile(cdLogFile, os.O_CREATE|os.O_TRUNC|os.O_RDWR|os.O_SYNC, 0777) - if err != nil { - c.Fatalf("Failed to create master containerd log file: %v", err) - } - cs.logFile = f - - cs.syncChild = make(chan error) - cs.RestartDaemon(false) -} - -func (cs *ContainerdSuite) TearDownSuite(c *check.C) { - - // tell containerd to stop - if cs.cd != nil { - cs.cd.Process.Signal(os.Interrupt) - - done := false - for done == false { - select { - case err := <-cs.syncChild: - if err != nil { - c.Errorf("master containerd did not exit cleanly: %v", err) - } - done = true - case <-time.After(3 * time.Second): - fmt.Println("Timeout while waiting for containerd to exit, killing it!") - cs.cd.Process.Kill() - } - } - } - - if cs.logFile != nil { - cs.logFile.Close() - } -} - -func (cs *ContainerdSuite) SetContainerEventFilter(id string, filter func(event *types.Event)) { - cs.eventFiltersMutex.Lock() - cs.eventFilters[id] = filter - cs.eventFiltersMutex.Unlock() -} - -func (cs *ContainerdSuite) TearDownTest(c *check.C) { - ctrs, err := cs.ListRunningContainers() - if err != nil { - c.Fatalf("Unable to retrieve running containers: %v", err) - } - - // Kill all containers that survived - for _, ctr := range ctrs { - ch := make(chan interface{}) - cs.SetContainerEventFilter(ctr.Id, func(e *types.Event) { - if e.Type == "exit" && e.Pid == "init" { - ch <- nil - } - }) - - if err := cs.KillContainer(ctr.Id); err != nil { - fmt.Fprintf(os.Stderr, "Failed to cleanup leftover test containers: %v\n", err) - } - - select { - case <-ch: - case <-time.After(3 * time.Second): - fmt.Fprintf(os.Stderr, "TearDownTest: Containerd %v didn't die after 3 seconds\n", ctr.Id) - } - } -} diff --git a/integration-test/container_utils_test.go b/integration-test/container_utils_test.go deleted file mode 100644 index 9bafa92..0000000 --- a/integration-test/container_utils_test.go +++ /dev/null @@ -1,321 +0,0 @@ -package main - -import ( - "bytes" - "fmt" - "io" - "io/ioutil" - "os" - "path/filepath" - "sort" - "syscall" - "time" - - "github.com/docker/containerd/api/grpc/types" - "github.com/golang/protobuf/ptypes" - "github.com/golang/protobuf/ptypes/timestamp" - "golang.org/x/net/context" -) - -func (cs *ContainerdSuite) GetLogs() string { - b, _ := ioutil.ReadFile(cs.logFile.Name()) - return string(b) -} - -func (cs *ContainerdSuite) Events(from time.Time, storedOnly bool, id string) (types.API_EventsClient, error) { - var ( - ftsp *timestamp.Timestamp - err error - ) - if !from.IsZero() { - ftsp, err = ptypes.TimestampProto(from) - if err != nil { - return nil, err - } - } - - return cs.grpcClient.Events(context.Background(), &types.EventsRequest{Timestamp: ftsp, StoredOnly: storedOnly, Id: id}) -} - -func (cs *ContainerdSuite) ListRunningContainers() ([]*types.Container, error) { - resp, err := cs.grpcClient.State(context.Background(), &types.StateRequest{}) - if err != nil { - return nil, err - } - return resp.Containers, nil -} - -func (cs *ContainerdSuite) SignalContainerProcess(id string, procID string, sig uint32) error { - _, err := cs.grpcClient.Signal(context.Background(), &types.SignalRequest{ - Id: id, - Pid: procID, - Signal: sig, - }) - return err -} - -func (cs *ContainerdSuite) SignalContainer(id string, sig uint32) error { - return cs.SignalContainerProcess(id, "init", sig) -} - -func (cs *ContainerdSuite) KillContainer(id string) error { - return cs.SignalContainerProcess(id, "init", uint32(syscall.SIGKILL)) -} - -func (cs *ContainerdSuite) UpdateContainerResource(id string, rs *types.UpdateResource) error { - _, err := cs.grpcClient.UpdateContainer(context.Background(), &types.UpdateContainerRequest{ - Id: id, - Pid: "init", - Status: "", - Resources: rs, - }) - return err -} - -func (cs *ContainerdSuite) PauseContainer(id string) error { - _, err := cs.grpcClient.UpdateContainer(context.Background(), &types.UpdateContainerRequest{ - Id: id, - Pid: "init", - Status: "paused", - }) - return err -} - -func (cs *ContainerdSuite) ResumeContainer(id string) error { - _, err := cs.grpcClient.UpdateContainer(context.Background(), &types.UpdateContainerRequest{ - Id: id, - Pid: "init", - Status: "running", - }) - return err -} - -func (cs *ContainerdSuite) GetContainerStats(id string) (*types.StatsResponse, error) { - stats, err := cs.grpcClient.Stats(context.Background(), &types.StatsRequest{ - Id: id, - }) - return stats, err -} - -type stdio struct { - stdin string - stdout string - stderr string - stdinf *os.File - stdoutf *os.File - stderrf *os.File - stdoutBuffer bytes.Buffer - stderrBuffer bytes.Buffer -} - -type ContainerProcess struct { - containerID string - pid string - bundle *Bundle - io stdio - eventsCh chan *types.Event - cs *ContainerdSuite - hasExited bool -} - -func (c *ContainerProcess) openIo() (err error) { - defer func() { - if err != nil { - c.Cleanup() - } - }() - - c.io.stdinf, err = os.OpenFile(c.io.stdin, os.O_RDWR, 0) - if err != nil { - return err - } - - c.io.stdoutf, err = os.OpenFile(c.io.stdout, os.O_RDWR, 0) - if err != nil { - return err - } - go io.Copy(&c.io.stdoutBuffer, c.io.stdoutf) - - c.io.stderrf, err = os.OpenFile(c.io.stderr, os.O_RDWR, 0) - if err != nil { - return err - } - go io.Copy(&c.io.stderrBuffer, c.io.stderrf) - - return nil -} - -func (c *ContainerProcess) GetEventsChannel() chan *types.Event { - return c.eventsCh -} - -func (c *ContainerProcess) GetNextEvent() *types.Event { - if c.hasExited { - return nil - } - - e := <-c.eventsCh - - if e.Type == "exit" && e.Pid == c.pid { - c.Cleanup() - c.hasExited = true - close(c.eventsCh) - } - - return e -} - -func (c *ContainerProcess) CloseStdin() error { - _, err := c.cs.grpcClient.UpdateProcess(context.Background(), &types.UpdateProcessRequest{ - Id: c.containerID, - Pid: c.pid, - CloseStdin: true, - }) - return err -} - -func (c *ContainerProcess) Cleanup() { - for _, f := range []*os.File{ - c.io.stdinf, - c.io.stdoutf, - c.io.stderrf, - } { - if f != nil { - f.Close() - f = nil - } - } -} - -func NewContainerProcess(cs *ContainerdSuite, bundle *Bundle, cid, pid string) (c *ContainerProcess, err error) { - c = &ContainerProcess{ - containerID: cid, - pid: "init", - bundle: bundle, - eventsCh: make(chan *types.Event, 8), - cs: cs, - hasExited: false, - } - - for name, path := range map[string]*string{ - "stdin": &c.io.stdin, - "stdout": &c.io.stdout, - "stderr": &c.io.stderr, - } { - *path = filepath.Join(bundle.Path, "io", cid+"-"+pid+"-"+name) - if err = syscall.Mkfifo(*path, 0755); err != nil && !os.IsExist(err) { - return nil, err - } - } - - if err = c.openIo(); err != nil { - return nil, err - } - - return c, nil -} - -func (cs *ContainerdSuite) StartContainerWithEventFilter(id, bundleName string, filter func(*types.Event)) (c *ContainerProcess, err error) { - bundle := GetBundle(bundleName) - if bundle == nil { - return nil, fmt.Errorf("No such bundle '%s'", bundleName) - } - - c, err = NewContainerProcess(cs, bundle, id, "init") - if err != nil { - return nil, err - } - - r := &types.CreateContainerRequest{ - Id: id, - BundlePath: filepath.Join(cs.cwd, bundle.Path), - Stdin: filepath.Join(cs.cwd, c.io.stdin), - Stdout: filepath.Join(cs.cwd, c.io.stdout), - Stderr: filepath.Join(cs.cwd, c.io.stderr), - } - - if filter == nil { - filter = func(event *types.Event) { - c.eventsCh <- event - } - } - - cs.SetContainerEventFilter(id, filter) - - if _, err := cs.grpcClient.CreateContainer(context.Background(), r); err != nil { - c.Cleanup() - return nil, err - } - - return c, nil -} - -func (cs *ContainerdSuite) StartContainer(id, bundleName string) (c *ContainerProcess, err error) { - return cs.StartContainerWithEventFilter(id, bundleName, nil) -} - -func (cs *ContainerdSuite) RunContainer(id, bundleName string) (c *ContainerProcess, err error) { - c, err = cs.StartContainer(id, bundleName) - if err != nil { - return nil, err - } - - for { - e := c.GetNextEvent() - if e.Type == "exit" && e.Pid == "init" { - break - } - } - - return c, err -} - -func (cs *ContainerdSuite) AddProcessToContainer(init *ContainerProcess, pid, cwd string, env, args []string, uid, gid uint32) (c *ContainerProcess, err error) { - c, err = NewContainerProcess(cs, init.bundle, init.containerID, pid) - if err != nil { - return nil, err - } - - pr := &types.AddProcessRequest{ - Id: init.containerID, - Pid: pid, - Args: args, - Cwd: cwd, - Env: env, - User: &types.User{ - Uid: uid, - Gid: gid, - }, - Stdin: filepath.Join(cs.cwd, c.io.stdin), - Stdout: filepath.Join(cs.cwd, c.io.stdout), - Stderr: filepath.Join(cs.cwd, c.io.stderr), - } - - _, err = cs.grpcClient.AddProcess(context.Background(), pr) - if err != nil { - c.Cleanup() - return nil, err - } - - return c, nil -} - -type containerSorter struct { - c []*types.Container -} - -func (s *containerSorter) Len() int { - return len(s.c) -} - -func (s *containerSorter) Swap(i, j int) { - s.c[i], s.c[j] = s.c[j], s.c[i] -} - -func (s *containerSorter) Less(i, j int) bool { - return s.c[i].Id < s.c[j].Id -} - -func sortContainers(c []*types.Container) { - sort.Sort(&containerSorter{c}) -} diff --git a/integration-test/events_test.go b/integration-test/events_test.go deleted file mode 100644 index c8db406..0000000 --- a/integration-test/events_test.go +++ /dev/null @@ -1,63 +0,0 @@ -package main - -import ( - "fmt" - "time" - - "github.com/docker/containerd/api/grpc/types" - "github.com/docker/docker/pkg/integration/checker" - "github.com/go-check/check" -) - -func (cs *ContainerdSuite) TestEventsId(t *check.C) { - if err := CreateBusyboxBundle("busybox-ls", []string{"ls"}); err != nil { - t.Fatal(err) - } - - from := time.Now() - - for i := 0; i < 10; i++ { - _, err := cs.RunContainer(fmt.Sprintf("ls-%d", i), "busybox-ls") - if err != nil { - t.Fatal(err) - } - } - - containerID := "ls-4" - - events, err := cs.Events(from, true, containerID) - if err != nil { - t.Fatal(err) - } - - evs := []*types.Event{} - for { - e, err := events.Recv() - if err != nil { - if err.Error() == "EOF" { - break - } - t.Fatal(err) - } - evs = append(evs, e) - } - - t.Assert(len(evs), checker.Equals, 2) - for idx, evt := range []types.Event{ - { - Type: "start-container", - Id: containerID, - Status: 0, - Pid: "", - }, - { - Type: "exit", - Id: containerID, - Status: 0, - Pid: "init", - }, - } { - evt.Timestamp = evs[idx].Timestamp - t.Assert(*evs[idx], checker.Equals, evt) - } -} diff --git a/integration-test/exec_test.go b/integration-test/exec_test.go deleted file mode 100644 index e2b9bff..0000000 --- a/integration-test/exec_test.go +++ /dev/null @@ -1,187 +0,0 @@ -package main - -import ( - "path/filepath" - "syscall" - - "github.com/docker/containerd/api/grpc/types" - "github.com/docker/docker/pkg/integration/checker" - "github.com/go-check/check" -) - -func (cs *ContainerdSuite) TestBusyboxTopExecEcho(t *check.C) { - bundleName := "busybox-top" - if err := CreateBusyboxBundle(bundleName, []string{"top"}); err != nil { - t.Fatal(err) - } - - var ( - err error - initp *ContainerProcess - echop *ContainerProcess - ) - - containerID := "top" - initp, err = cs.StartContainer(containerID, bundleName) - t.Assert(err, checker.Equals, nil) - - echop, err = cs.AddProcessToContainer(initp, "echo", "/", []string{"PATH=/bin"}, []string{"sh", "-c", "echo -n Ay Caramba! ; exit 1"}, 0, 0) - t.Assert(err, checker.Equals, nil) - - for _, evt := range []types.Event{ - { - Type: "start-container", - Id: containerID, - Status: 0, - Pid: "", - }, - { - Type: "start-process", - Id: containerID, - Status: 0, - Pid: "echo", - }, - { - Type: "exit", - Id: containerID, - Status: 1, - Pid: "echo", - }, - } { - ch := initp.GetEventsChannel() - e := <-ch - evt.Timestamp = e.Timestamp - - t.Assert(*e, checker.Equals, evt) - } - - t.Assert(echop.io.stdoutBuffer.String(), checker.Equals, "Ay Caramba!") -} - -func (cs *ContainerdSuite) TestBusyboxTopExecTop(t *check.C) { - bundleName := "busybox-top" - if err := CreateBusyboxBundle(bundleName, []string{"top"}); err != nil { - t.Fatal(err) - } - - var ( - err error - initp *ContainerProcess - ) - - containerID := "top" - initp, err = cs.StartContainer(containerID, bundleName) - t.Assert(err, checker.Equals, nil) - - execID := "top1" - _, err = cs.AddProcessToContainer(initp, execID, "/", []string{"PATH=/usr/bin"}, []string{"top"}, 0, 0) - t.Assert(err, checker.Equals, nil) - - for idx, evt := range []types.Event{ - { - Type: "start-container", - Id: containerID, - Status: 0, - Pid: "", - }, - { - Type: "start-process", - Id: containerID, - Status: 0, - Pid: execID, - }, - { - Type: "exit", - Id: containerID, - Status: 137, - Pid: execID, - }, - } { - ch := initp.GetEventsChannel() - e := <-ch - evt.Timestamp = e.Timestamp - t.Assert(*e, checker.Equals, evt) - if idx == 1 { - // Process Started, kill it - cs.SignalContainerProcess(containerID, "top1", uint32(syscall.SIGKILL)) - } - } - - // Container should still be running - containers, err := cs.ListRunningContainers() - if err != nil { - t.Fatal(err) - } - t.Assert(len(containers), checker.Equals, 1) - t.Assert(containers[0].Id, checker.Equals, "top") - t.Assert(containers[0].Status, checker.Equals, "running") - t.Assert(containers[0].BundlePath, check.Equals, filepath.Join(cs.cwd, GetBundle(bundleName).Path)) -} - -func (cs *ContainerdSuite) TestBusyboxTopExecTopKillInit(t *check.C) { - bundleName := "busybox-top" - if err := CreateBusyboxBundle(bundleName, []string{"top"}); err != nil { - t.Fatal(err) - } - - var ( - err error - initp *ContainerProcess - ) - - containerID := "top" - initp, err = cs.StartContainer(containerID, bundleName) - t.Assert(err, checker.Equals, nil) - - execID := "top1" - _, err = cs.AddProcessToContainer(initp, execID, "/", []string{"PATH=/usr/bin"}, []string{"top"}, 0, 0) - t.Assert(err, checker.Equals, nil) - - ch := initp.GetEventsChannel() - for _, evt := range []types.Event{ - { - Type: "start-container", - Id: containerID, - Status: 0, - Pid: "", - }, - { - Type: "start-process", - Id: containerID, - Status: 0, - Pid: execID, - }, - } { - e := <-ch - evt.Timestamp = e.Timestamp - t.Assert(*e, checker.Equals, evt) - } - - cs.SignalContainerProcess(containerID, "init", uint32(syscall.SIGTERM)) - for i := 0; i < 2; i++ { - e := <-ch - switch e.Pid { - case "init": - evt := types.Event{ - Type: "exit", - Id: containerID, - Status: 143, - Pid: "init", - Timestamp: e.Timestamp, - } - t.Assert(*e, checker.Equals, evt) - case execID: - evt := types.Event{ - Type: "exit", - Id: containerID, - Status: 137, - Pid: execID, - Timestamp: e.Timestamp, - } - t.Assert(*e, checker.Equals, evt) - default: - t.Fatalf("Unexpected event %v", e) - } - } - -} diff --git a/integration-test/start_test.go b/integration-test/start_test.go deleted file mode 100644 index 94eec66..0000000 --- a/integration-test/start_test.go +++ /dev/null @@ -1,538 +0,0 @@ -package main - -import ( - "fmt" - "os" - "os/exec" - "path/filepath" - "syscall" - "time" - - "github.com/docker/containerd/api/grpc/types" - "github.com/docker/docker/pkg/integration/checker" - "github.com/go-check/check" - ocs "github.com/opencontainers/runtime-spec/specs-go" - "google.golang.org/grpc" -) - -func (cs *ContainerdSuite) TestStartBusyboxLsSlash(t *check.C) { - expectedOutput := `bin -dev -etc -home -lib -lib64 -linuxrc -media -mnt -opt -proc -root -run -sbin -sys -tmp -usr -var -` - if err := CreateBusyboxBundle("busybox-ls-slash", []string{"ls", "/"}); err != nil { - t.Fatal(err) - } - - c, err := cs.RunContainer("myls", "busybox-ls-slash") - if err != nil { - t.Fatal(err) - } - - t.Assert(c.io.stdoutBuffer.String(), checker.Equals, expectedOutput) -} - -func (cs *ContainerdSuite) TestStartBusyboxNoSuchFile(t *check.C) { - expectedOutput := `oci runtime error: exec: "NoSuchFile": executable file not found in $PATH` - - if err := CreateBusyboxBundle("busybox-no-such-file", []string{"NoSuchFile"}); err != nil { - t.Fatal(err) - } - - _, err := cs.RunContainer("NoSuchFile", "busybox-no-such-file") - t.Assert(grpc.ErrorDesc(err), checker.Contains, expectedOutput) -} - -func (cs *ContainerdSuite) TestStartBusyboxTop(t *check.C) { - bundleName := "busybox-top" - if err := CreateBusyboxBundle(bundleName, []string{"top"}); err != nil { - t.Fatal(err) - } - - containerID := "start-busybox-top" - _, err := cs.StartContainer(containerID, bundleName) - t.Assert(err, checker.Equals, nil) - - containers, err := cs.ListRunningContainers() - if err != nil { - t.Fatal(err) - } - t.Assert(len(containers), checker.Equals, 1) - t.Assert(containers[0].Id, checker.Equals, containerID) - t.Assert(containers[0].Status, checker.Equals, "running") - t.Assert(containers[0].BundlePath, check.Equals, filepath.Join(cs.cwd, GetBundle(bundleName).Path)) -} - -func (cs *ContainerdSuite) TestStartBusyboxLsEvents(t *check.C) { - if err := CreateBusyboxBundle("busybox-ls", []string{"ls"}); err != nil { - t.Fatal(err) - } - - containerID := "ls-events" - c, err := cs.StartContainer(containerID, "busybox-ls") - if err != nil { - t.Fatal(err) - } - - for _, evt := range []types.Event{ - { - Type: "start-container", - Id: containerID, - Status: 0, - Pid: "", - }, - { - Type: "exit", - Id: containerID, - Status: 0, - Pid: "init", - }, - } { - ch := c.GetEventsChannel() - select { - case e := <-ch: - evt.Timestamp = e.Timestamp - - t.Assert(*e, checker.Equals, evt) - case <-time.After(2 * time.Second): - t.Fatal("Container took more than 2 seconds to terminate") - } - } -} - -func (cs *ContainerdSuite) TestStartBusyboxSleep(t *check.C) { - if err := CreateBusyboxBundle("busybox-sleep-5", []string{"sleep", "5"}); err != nil { - t.Fatal(err) - } - - ch := make(chan interface{}) - filter := func(e *types.Event) { - if e.Type == "exit" && e.Pid == "init" { - ch <- nil - } - } - - start := time.Now() - _, err := cs.StartContainerWithEventFilter("sleep5", "busybox-sleep-5", filter) - if err != nil { - t.Fatal(err) - } - - // We add a generous 20% marge of error - select { - case <-ch: - t.Assert(uint64(time.Now().Sub(start)), checker.LessOrEqualThan, uint64(6*time.Second)) - case <-time.After(6 * time.Second): - t.Fatal("Container took more than 6 seconds to exit") - } -} - -func (cs *ContainerdSuite) TestStartBusyboxTopKill(t *check.C) { - bundleName := "busybox-top" - if err := CreateBusyboxBundle(bundleName, []string{"top"}); err != nil { - t.Fatal(err) - } - - containerID := "top-kill" - c, err := cs.StartContainer(containerID, bundleName) - if err != nil { - t.Fatal(err) - } - - <-time.After(1 * time.Second) - - err = cs.KillContainer(containerID) - if err != nil { - t.Fatal(err) - } - - for _, evt := range []types.Event{ - { - Type: "start-container", - Id: containerID, - Status: 0, - Pid: "", - }, - { - Type: "exit", - Id: containerID, - Status: 128 + uint32(syscall.SIGKILL), - Pid: "init", - }, - } { - ch := c.GetEventsChannel() - select { - case e := <-ch: - evt.Timestamp = e.Timestamp - - t.Assert(*e, checker.Equals, evt) - case <-time.After(2 * time.Second): - t.Fatal("Container took more than 2 seconds to terminate") - } - } -} - -func (cs *ContainerdSuite) TestStartBusyboxTopSignalSigterm(t *check.C) { - bundleName := "busybox-top" - if err := CreateBusyboxBundle(bundleName, []string{"top"}); err != nil { - t.Fatal(err) - } - - containerID := "top-sigterm" - c, err := cs.StartContainer(containerID, bundleName) - if err != nil { - t.Fatal(err) - } - - <-time.After(1 * time.Second) - - err = cs.SignalContainer(containerID, uint32(syscall.SIGTERM)) - if err != nil { - t.Fatal(err) - } - - for _, evt := range []types.Event{ - { - Type: "start-container", - Id: containerID, - Status: 0, - Pid: "", - }, - { - Type: "exit", - Id: containerID, - Status: 128 + uint32(syscall.SIGTERM), - Pid: "init", - }, - } { - ch := c.GetEventsChannel() - select { - case e := <-ch: - evt.Timestamp = e.Timestamp - - t.Assert(*e, checker.Equals, evt) - case <-time.After(2 * time.Second): - t.Fatal("Container took more than 2 seconds to terminate") - } - } -} - -func (cs *ContainerdSuite) TestStartBusyboxTrapUSR1(t *check.C) { - if err := CreateBusyboxBundle("busybox-trap-usr1", []string{"sh", "-c", "trap 'echo -n booh!' SIGUSR1 ; sleep 60 & wait"}); err != nil { - t.Fatal(err) - } - - containerID := "trap-usr1" - c, err := cs.StartContainer(containerID, "busybox-trap-usr1") - if err != nil { - t.Fatal(err) - } - - <-time.After(1 * time.Second) - - if err := cs.SignalContainer(containerID, uint32(syscall.SIGUSR1)); err != nil { - t.Fatal(err) - } - - for { - e := c.GetNextEvent() - if e.Type == "exit" && e.Pid == "init" { - break - } - } - - t.Assert(c.io.stdoutBuffer.String(), checker.Equals, "booh!") -} - -func (cs *ContainerdSuite) TestStartBusyboxTopPauseResume(t *check.C) { - bundleName := "busybox-top" - if err := CreateBusyboxBundle(bundleName, []string{"top"}); err != nil { - t.Fatal(err) - } - - containerID := "top-pause-resume" - c, err := cs.StartContainer(containerID, bundleName) - if err != nil { - t.Fatal(err) - } - - if err := cs.PauseContainer(containerID); err != nil { - t.Fatal(err) - } - - if err := cs.ResumeContainer(containerID); err != nil { - t.Fatal(err) - } - - for _, evt := range []types.Event{ - { - Type: "start-container", - Id: containerID, - Status: 0, - Pid: "", - }, - { - Type: "pause", - Id: containerID, - Status: 0, - Pid: "", - }, - { - Type: "resume", - Id: containerID, - Status: 0, - Pid: "", - }, - } { - ch := c.GetEventsChannel() - select { - case e := <-ch: - evt.Timestamp = e.Timestamp - - t.Assert(*e, checker.Equals, evt) - case <-time.After(2 * time.Second): - t.Fatal("Container took more than 2 seconds to terminate") - } - } - - // check that status is running - containers, err := cs.ListRunningContainers() - if err != nil { - t.Fatal(err) - } - t.Assert(len(containers), checker.Equals, 1) - t.Assert(containers[0].Id, checker.Equals, containerID) - t.Assert(containers[0].Status, checker.Equals, "running") -} - -func (cs *ContainerdSuite) TestOOM(t *check.C) { - bundleName := "busybox-sh-512k-memlimit" - if err := CreateBundleWithFilter("busybox", bundleName, []string{"sh", "-c", "x=oom-party-time; while true; do x=$x$x$x$x$x$x$x$x$x$x; done"}, func(spec *ocs.Spec) { - // Limit to 512k for quick oom - var limit uint64 = 8 * 1024 * 1024 - spec.Linux.Resources.Memory = &ocs.Memory{ - Limit: &limit, - } - if swapEnabled() { - spec.Linux.Resources.Memory.Swap = &limit - } - }); err != nil { - t.Fatal(err) - } - - containerID := "sh-oom" - c, err := cs.StartContainer(containerID, bundleName) - if err != nil { - t.Fatal(err) - } - - for _, evt := range []types.Event{ - { - Type: "start-container", - Id: containerID, - Status: 0, - Pid: "", - }, - { - Type: "oom", - Id: containerID, - Status: 0, - Pid: "", - }, - { - Type: "exit", - Id: containerID, - Status: 137, - Pid: "init", - }, - } { - ch := c.GetEventsChannel() - select { - case e := <-ch: - evt.Timestamp = e.Timestamp - t.Assert(*e, checker.Equals, evt) - case <-time.After(60 * time.Second): - t.Fatalf("Container took more than 60 seconds to %s", evt.Type) - } - } -} - -func (cs *ContainerdSuite) TestRestart(t *check.C) { - bundleName := "busybox-top" - if err := CreateBusyboxBundle(bundleName, []string{"top"}); err != nil { - t.Fatal(err) - } - - totalCtr := 10 - - for i := 0; i < totalCtr; i++ { - containerID := fmt.Sprintf("top%d", i) - c, err := cs.StartContainer(containerID, bundleName) - if err != nil { - t.Fatal(err) - } - - e := c.GetNextEvent() - - t.Assert(*e, checker.Equals, types.Event{ - Type: "start-container", - Id: containerID, - Status: 0, - Pid: "", - Timestamp: e.Timestamp, - }) - } - - // restart daemon gracefully (SIGINT) - cs.RestartDaemon(false) - - // check that status is running - containers, err := cs.ListRunningContainers() - if err != nil { - t.Fatal(err) - } - sortContainers(containers) - t.Assert(len(containers), checker.Equals, totalCtr) - for i := 0; i < totalCtr; i++ { - t.Assert(containers[i].Id, checker.Equals, fmt.Sprintf("top%d", i)) - t.Assert(containers[i].Status, checker.Equals, "running") - } - - // Now kill daemon (SIGKILL) - cs.StopDaemon(true) - - // Sleep a second to allow thevent e timestamp to change since - // it's second based - <-time.After(3 * time.Second) - - // Kill a couple of containers - killedCtr := map[int]bool{4: true, 2: true} - - var f func(*types.Event) - deathChans := make([]chan error, len(killedCtr)) - deathChansIdx := 0 - - for i := range killedCtr { - ch := make(chan error, 1) - deathChans[deathChansIdx] = ch - deathChansIdx++ - syscall.Kill(int(containers[i].Pids[0]), syscall.SIGKILL) - - // Filter to be notified of their death - containerID := fmt.Sprintf("top%d", i) - f = func(event *types.Event) { - expectedEvent := types.Event{ - Type: "exit", - Id: containerID, - Status: 137, - Pid: "init", - } - expectedEvent.Timestamp = event.Timestamp - if ok := t.Check(*event, checker.Equals, expectedEvent); !ok { - ch <- fmt.Errorf("Unexpected event: %#v", *event) - } else { - ch <- nil - } - } - cs.SetContainerEventFilter(containerID, f) - } - - cs.RestartDaemon(true) - - // Ensure we got our events - for i := range deathChans { - done := false - for done == false { - select { - case err := <-deathChans[i]: - t.Assert(err, checker.Equals, nil) - done = true - case <-time.After(3 * time.Second): - t.Fatal("Exit event for container not received after 3 seconds") - } - } - } - - // check that status is running - containers, err = cs.ListRunningContainers() - if err != nil { - t.Fatal(err) - } - sortContainers(containers) - t.Assert(len(containers), checker.Equals, totalCtr-len(killedCtr)) - idShift := 0 - for i := 0; i < totalCtr-len(killedCtr); i++ { - if _, ok := killedCtr[i+idShift]; ok { - idShift++ - } - t.Assert(containers[i].Id, checker.Equals, fmt.Sprintf("top%d", i+idShift)) - t.Assert(containers[i].Status, checker.Equals, "running") - } -} - -func swapEnabled() bool { - _, err := os.Stat("/sys/fs/cgroup/memory/memory.memsw.limit_in_bytes") - return err == nil -} - -func (cs *ContainerdSuite) TestSigkillShimReuseName(t *check.C) { - bundleName := "busybox-top" - if err := CreateBusyboxBundle(bundleName, []string{"top"}); err != nil { - t.Fatal(err) - } - containerID := "top" - c, err := cs.StartContainer(containerID, bundleName) - if err != nil { - t.Fatal(err) - } - - // Sigkill the shim - exec.Command("pkill", "-9", "containerd-shim").Run() - - // Wait for it to be reaped - for _, evt := range []types.Event{ - { - Type: "start-container", - Id: containerID, - Status: 0, - Pid: "", - }, - { - Type: "exit", - Id: containerID, - Status: 128 + 9, - Pid: "init", - }, - } { - ch := c.GetEventsChannel() - select { - case e := <-ch: - evt.Timestamp = e.Timestamp - - t.Assert(*e, checker.Equals, evt) - case <-time.After(2 * time.Second): - t.Fatal("Container took more than 2 seconds to terminate") - } - } - - // Start a new continer with the same name - c, err = cs.StartContainer(containerID, bundleName) - if err != nil { - t.Fatal(err) - } -} diff --git a/runtime/container.go b/runtime/container.go deleted file mode 100644 index ec3189f..0000000 --- a/runtime/container.go +++ /dev/null @@ -1,738 +0,0 @@ -package runtime - -import ( - "encoding/json" - "fmt" - "io" - "io/ioutil" - "os" - "os/exec" - "path/filepath" - "syscall" - "time" - - "github.com/Sirupsen/logrus" - "github.com/docker/containerd/specs" - ocs "github.com/opencontainers/runtime-spec/specs-go" - "golang.org/x/sys/unix" -) - -// Container defines the operations allowed on a container -type Container interface { - // ID returns the container ID - ID() string - // Path returns the path to the bundle - Path() string - // Start starts the init process of the container - Start(checkpointPath string, s Stdio) (Process, error) - // Exec starts another process in an existing container - Exec(string, specs.ProcessSpec, Stdio) (Process, error) - // Delete removes the container's state and any resources - Delete() error - // Processes returns all the containers processes that have been added - Processes() ([]Process, error) - // State returns the containers runtime state - State() State - // Resume resumes a paused container - Resume() error - // Pause pauses a running container - Pause() error - // RemoveProcess removes the specified process from the container - RemoveProcess(string) error - // Checkpoints returns all the checkpoints for a container - Checkpoints(checkpointDir string) ([]Checkpoint, error) - // Checkpoint creates a new checkpoint - Checkpoint(checkpoint Checkpoint, checkpointDir string) error - // DeleteCheckpoint deletes the checkpoint for the provided name - DeleteCheckpoint(name string, checkpointDir string) error - // Labels are user provided labels for the container - Labels() []string - // Pids returns all pids inside the container - Pids() ([]int, error) - // Stats returns realtime container stats and resource information - Stats() (*Stat, error) - // Name or path of the OCI compliant runtime used to execute the container - Runtime() string - // OOM signals the channel if the container received an OOM notification - OOM() (OOM, error) - // UpdateResource updates the containers resources to new values - UpdateResources(*Resource) error - - // Status return the current status of the container. - Status() (State, error) -} - -// OOM wraps a container OOM. -type OOM interface { - io.Closer - FD() int - ContainerID() string - Flush() error - Removed() bool -} - -// Stdio holds the path to the 3 pipes used for the standard ios. -type Stdio struct { - Stdin string - Stdout string - Stderr string -} - -// NewStdio wraps the given standard io path into an Stdio struct. -// If a given parameter is the empty string, it is replaced by "/dev/null" -func NewStdio(stdin, stdout, stderr string) Stdio { - for _, s := range []*string{ - &stdin, &stdout, &stderr, - } { - if *s == "" { - *s = "/dev/null" - } - } - return Stdio{ - Stdin: stdin, - Stdout: stdout, - Stderr: stderr, - } -} - -// ContainerOpts keeps the options passed at container creation -type ContainerOpts struct { - Root string - ID string - Bundle string - Runtime string - RuntimeArgs []string - Shim string - Labels []string - NoPivotRoot bool - Timeout time.Duration -} - -// New returns a new container -func New(opts ContainerOpts) (Container, error) { - c := &container{ - root: opts.Root, - id: opts.ID, - bundle: opts.Bundle, - labels: opts.Labels, - processes: make(map[string]*process), - runtime: opts.Runtime, - runtimeArgs: opts.RuntimeArgs, - shim: opts.Shim, - noPivotRoot: opts.NoPivotRoot, - timeout: opts.Timeout, - } - if err := os.Mkdir(filepath.Join(c.root, c.id), 0755); err != nil { - return nil, err - } - f, err := os.Create(filepath.Join(c.root, c.id, StateFile)) - if err != nil { - return nil, err - } - defer f.Close() - if err := json.NewEncoder(f).Encode(state{ - Bundle: c.bundle, - Labels: c.labels, - Runtime: c.runtime, - RuntimeArgs: c.runtimeArgs, - Shim: c.shim, - NoPivotRoot: opts.NoPivotRoot, - }); err != nil { - return nil, err - } - return c, nil -} - -// Load return a new container from the matchin state file on disk. -func Load(root, id, shimName string, timeout time.Duration) (Container, error) { - var s state - f, err := os.Open(filepath.Join(root, id, StateFile)) - if err != nil { - return nil, err - } - defer f.Close() - if err := json.NewDecoder(f).Decode(&s); err != nil { - return nil, err - } - c := &container{ - root: root, - id: id, - bundle: s.Bundle, - labels: s.Labels, - runtime: s.Runtime, - runtimeArgs: s.RuntimeArgs, - shim: s.Shim, - noPivotRoot: s.NoPivotRoot, - processes: make(map[string]*process), - timeout: timeout, - } - - if c.shim == "" { - c.shim = shimName - } - - dirs, err := ioutil.ReadDir(filepath.Join(root, id)) - if err != nil { - return nil, err - } - for _, d := range dirs { - if !d.IsDir() { - continue - } - pid := d.Name() - s, err := readProcessState(filepath.Join(root, id, pid)) - if err != nil { - return nil, err - } - p, err := loadProcess(filepath.Join(root, id, pid), pid, c, s) - if err != nil { - logrus.WithField("id", id).WithField("pid", pid).Debug("containerd: error loading process %s", err) - continue - } - c.processes[pid] = p - } - return c, nil -} - -func readProcessState(dir string) (*ProcessState, error) { - f, err := os.Open(filepath.Join(dir, "process.json")) - if err != nil { - return nil, err - } - defer f.Close() - var s ProcessState - if err := json.NewDecoder(f).Decode(&s); err != nil { - return nil, err - } - return &s, nil -} - -type container struct { - // path to store runtime state information - root string - id string - bundle string - runtime string - runtimeArgs []string - shim string - processes map[string]*process - labels []string - oomFds []int - noPivotRoot bool - timeout time.Duration -} - -func (c *container) ID() string { - return c.id -} - -func (c *container) Path() string { - return c.bundle -} - -func (c *container) Labels() []string { - return c.labels -} - -func (c *container) readSpec() (*specs.Spec, error) { - var spec specs.Spec - f, err := os.Open(filepath.Join(c.bundle, "config.json")) - if err != nil { - return nil, err - } - defer f.Close() - if err := json.NewDecoder(f).Decode(&spec); err != nil { - return nil, err - } - return &spec, nil -} - -func (c *container) Delete() error { - err := os.RemoveAll(filepath.Join(c.root, c.id)) - - args := c.runtimeArgs - args = append(args, "delete", c.id) - if b, derr := exec.Command(c.runtime, args...).CombinedOutput(); err != nil { - err = fmt.Errorf("%s: %q", derr, string(b)) - } else if len(b) > 0 { - logrus.Debugf("%v %v: %q", c.runtime, args, string(b)) - } - return err -} - -func (c *container) Processes() ([]Process, error) { - out := []Process{} - for _, p := range c.processes { - out = append(out, p) - } - return out, nil -} - -func (c *container) RemoveProcess(pid string) error { - delete(c.processes, pid) - return os.RemoveAll(filepath.Join(c.root, c.id, pid)) -} - -func (c *container) State() State { - proc := c.processes["init"] - if proc == nil { - return Stopped - } - return proc.State() -} - -func (c *container) Runtime() string { - return c.runtime -} - -func (c *container) Pause() error { - args := c.runtimeArgs - args = append(args, "pause", c.id) - b, err := exec.Command(c.runtime, args...).CombinedOutput() - if err != nil { - return fmt.Errorf("%s: %q", err.Error(), string(b)) - } - return nil -} - -func (c *container) Resume() error { - args := c.runtimeArgs - args = append(args, "resume", c.id) - b, err := exec.Command(c.runtime, args...).CombinedOutput() - if err != nil { - return fmt.Errorf("%s: %q", err.Error(), string(b)) - } - return nil -} - -func (c *container) Checkpoints(checkpointDir string) ([]Checkpoint, error) { - if checkpointDir == "" { - checkpointDir = filepath.Join(c.bundle, "checkpoints") - } - - dirs, err := ioutil.ReadDir(checkpointDir) - if err != nil { - return nil, err - } - var out []Checkpoint - for _, d := range dirs { - if !d.IsDir() { - continue - } - path := filepath.Join(checkpointDir, d.Name(), "config.json") - data, err := ioutil.ReadFile(path) - if err != nil { - return nil, err - } - var cpt Checkpoint - if err := json.Unmarshal(data, &cpt); err != nil { - return nil, err - } - out = append(out, cpt) - } - return out, nil -} - -func (c *container) Checkpoint(cpt Checkpoint, checkpointDir string) error { - if checkpointDir == "" { - checkpointDir = filepath.Join(c.bundle, "checkpoints") - } - - if err := os.MkdirAll(checkpointDir, 0755); err != nil { - return err - } - - path := filepath.Join(checkpointDir, cpt.Name) - if err := os.Mkdir(path, 0755); err != nil { - return err - } - f, err := os.Create(filepath.Join(path, "config.json")) - if err != nil { - return err - } - cpt.Created = time.Now() - err = json.NewEncoder(f).Encode(cpt) - f.Close() - if err != nil { - return err - } - args := []string{ - "checkpoint", - "--image-path", path, - "--work-path", filepath.Join(path, "criu.work"), - } - add := func(flags ...string) { - args = append(args, flags...) - } - add(c.runtimeArgs...) - if !cpt.Exit { - add("--leave-running") - } - if cpt.Shell { - add("--shell-job") - } - if cpt.TCP { - add("--tcp-established") - } - if cpt.UnixSockets { - add("--ext-unix-sk") - } - for _, ns := range cpt.EmptyNS { - add("--empty-ns", ns) - } - add(c.id) - out, err := exec.Command(c.runtime, args...).CombinedOutput() - if err != nil { - return fmt.Errorf("%s: %q", err.Error(), string(out)) - } - return err -} - -func (c *container) DeleteCheckpoint(name string, checkpointDir string) error { - if checkpointDir == "" { - checkpointDir = filepath.Join(c.bundle, "checkpoints") - } - return os.RemoveAll(filepath.Join(checkpointDir, name)) -} - -func (c *container) Start(checkpointPath string, s Stdio) (Process, error) { - processRoot := filepath.Join(c.root, c.id, InitProcessID) - if err := os.Mkdir(processRoot, 0755); err != nil { - return nil, err - } - cmd := exec.Command(c.shim, - c.id, c.bundle, c.runtime, - ) - cmd.Dir = processRoot - cmd.SysProcAttr = &syscall.SysProcAttr{ - Setpgid: true, - } - spec, err := c.readSpec() - if err != nil { - return nil, err - } - config := &processConfig{ - checkpoint: checkpointPath, - root: processRoot, - id: InitProcessID, - c: c, - stdio: s, - spec: spec, - processSpec: specs.ProcessSpec(spec.Process), - } - p, err := newProcess(config) - if err != nil { - return nil, err - } - if err := c.createCmd(InitProcessID, cmd, p); err != nil { - return nil, err - } - return p, nil -} - -func (c *container) Exec(pid string, pspec specs.ProcessSpec, s Stdio) (pp Process, err error) { - processRoot := filepath.Join(c.root, c.id, pid) - if err := os.Mkdir(processRoot, 0755); err != nil { - return nil, err - } - defer func() { - if err != nil { - c.RemoveProcess(pid) - } - }() - cmd := exec.Command(c.shim, - c.id, c.bundle, c.runtime, - ) - cmd.Dir = processRoot - cmd.SysProcAttr = &syscall.SysProcAttr{ - Setpgid: true, - } - spec, err := c.readSpec() - if err != nil { - return nil, err - } - config := &processConfig{ - exec: true, - id: pid, - root: processRoot, - c: c, - processSpec: pspec, - spec: spec, - stdio: s, - } - p, err := newProcess(config) - if err != nil { - return nil, err - } - if err := c.createCmd(pid, cmd, p); err != nil { - return nil, err - } - return p, nil -} - -func (c *container) createCmd(pid string, cmd *exec.Cmd, p *process) error { - p.cmd = cmd - if err := cmd.Start(); err != nil { - close(p.cmdDoneCh) - if exErr, ok := err.(*exec.Error); ok { - if exErr.Err == exec.ErrNotFound || exErr.Err == os.ErrNotExist { - return fmt.Errorf("%s not installed on system", c.shim) - } - } - return err - } - // We need the pid file to have been written to run - defer func() { - go func() { - err := p.cmd.Wait() - if err == nil { - p.cmdSuccess = true - } - - if same, err := p.isSameProcess(); same && p.pid > 0 { - // The process changed its PR_SET_PDEATHSIG, so force - // kill it - logrus.Infof("containerd: %s:%s (pid %v) has become an orphan, killing it", p.container.id, p.id, p.pid) - err = unix.Kill(p.pid, syscall.SIGKILL) - if err != nil && err != syscall.ESRCH { - logrus.Errorf("containerd: unable to SIGKILL %s:%s (pid %v): %v", p.container.id, p.id, p.pid, err) - } else { - for { - err = unix.Kill(p.pid, 0) - if err != nil { - break - } - time.Sleep(5 * time.Millisecond) - } - } - } - close(p.cmdDoneCh) - }() - }() - if err := c.waitForCreate(p, cmd); err != nil { - return err - } - c.processes[pid] = p - return nil -} - -func hostIDFromMap(id uint32, mp []ocs.IDMapping) int { - for _, m := range mp { - if (id >= m.ContainerID) && (id <= (m.ContainerID + m.Size - 1)) { - return int(m.HostID + (id - m.ContainerID)) - } - } - return 0 -} - -func (c *container) Pids() ([]int, error) { - args := c.runtimeArgs - args = append(args, "ps", "--format=json", c.id) - out, err := exec.Command(c.runtime, args...).CombinedOutput() - if err != nil { - return nil, fmt.Errorf("%s: %q", err.Error(), out) - } - var pids []int - if err := json.Unmarshal(out, &pids); err != nil { - return nil, err - } - return pids, nil -} - -func (c *container) Stats() (*Stat, error) { - now := time.Now() - args := c.runtimeArgs - args = append(args, "events", "--stats", c.id) - out, err := exec.Command(c.runtime, args...).CombinedOutput() - if err != nil { - return nil, fmt.Errorf("%s: %q", err.Error(), out) - } - s := struct { - Data *Stat `json:"data"` - }{} - if err := json.Unmarshal(out, &s); err != nil { - return nil, err - } - s.Data.Timestamp = now - return s.Data, nil -} - -// Status implements the runtime Container interface. -func (c *container) Status() (State, error) { - args := c.runtimeArgs - args = append(args, "state", c.id) - - out, err := exec.Command(c.runtime, args...).CombinedOutput() - if err != nil { - return "", fmt.Errorf("%s: %q", err.Error(), out) - } - - // We only require the runtime json output to have a top level Status field. - var s struct { - Status State `json:"status"` - } - if err := json.Unmarshal(out, &s); err != nil { - return "", err - } - return s.Status, nil -} - -func (c *container) writeEventFD(root string, cfd, efd int) error { - f, err := os.OpenFile(filepath.Join(root, "cgroup.event_control"), os.O_WRONLY, 0) - if err != nil { - return err - } - defer f.Close() - _, err = f.WriteString(fmt.Sprintf("%d %d", efd, cfd)) - return err -} - -type waitArgs struct { - pid int - err error -} - -func (c *container) waitForCreate(p *process, cmd *exec.Cmd) error { - wc := make(chan error, 1) - go func() { - for { - if _, err := p.getPidFromFile(); err != nil { - if os.IsNotExist(err) || err == errInvalidPidInt { - alive, err := isAlive(cmd) - if err != nil { - wc <- err - return - } - if !alive { - // runc could have failed to run the container so lets get the error - // out of the logs or the shim could have encountered an error - messages, err := readLogMessages(filepath.Join(p.root, "shim-log.json")) - if err != nil { - wc <- err - return - } - for _, m := range messages { - if m.Level == "error" { - wc <- fmt.Errorf("shim error: %v", m.Msg) - return - } - } - // no errors reported back from shim, check for runc/runtime errors - messages, err = readLogMessages(filepath.Join(p.root, "log.json")) - if err != nil { - if os.IsNotExist(err) { - err = ErrContainerNotStarted - } - wc <- err - return - } - for _, m := range messages { - if m.Level == "error" { - wc <- fmt.Errorf("oci runtime error: %v", m.Msg) - return - } - } - wc <- ErrContainerNotStarted - return - } - time.Sleep(15 * time.Millisecond) - continue - } - wc <- err - return - } - // the pid file was read successfully - wc <- nil - return - } - }() - select { - case err := <-wc: - if err != nil { - return err - } - err = p.saveStartTime() - if err != nil { - logrus.Warnf("containerd: unable to save %s:%s starttime: %v", p.container.id, p.id, err) - } - return nil - case <-time.After(c.timeout): - cmd.Process.Kill() - cmd.Wait() - return ErrContainerStartTimeout - } -} - -// isAlive checks if the shim that launched the container is still alive -func isAlive(cmd *exec.Cmd) (bool, error) { - if _, err := syscall.Wait4(cmd.Process.Pid, nil, syscall.WNOHANG, nil); err == nil { - return true, nil - } - if err := syscall.Kill(cmd.Process.Pid, 0); err != nil { - if err == syscall.ESRCH { - return false, nil - } - return false, err - } - return true, nil -} - -type oom struct { - id string - root string - control *os.File - eventfd int -} - -func (o *oom) ContainerID() string { - return o.id -} - -func (o *oom) FD() int { - return o.eventfd -} - -func (o *oom) Flush() error { - buf := make([]byte, 8) - _, err := syscall.Read(o.eventfd, buf) - return err -} - -func (o *oom) Removed() bool { - _, err := os.Lstat(filepath.Join(o.root, "cgroup.event_control")) - return os.IsNotExist(err) -} - -func (o *oom) Close() error { - err := syscall.Close(o.eventfd) - if cerr := o.control.Close(); err == nil { - err = cerr - } - return err -} - -type message struct { - Level string `json:"level"` - Msg string `json:"msg"` -} - -func readLogMessages(path string) ([]message, error) { - var out []message - f, err := os.Open(path) - if err != nil { - return nil, err - } - defer f.Close() - dec := json.NewDecoder(f) - for { - var m message - if err := dec.Decode(&m); err != nil { - if err == io.EOF { - break - } - return nil, err - } - out = append(out, m) - } - return out, nil -} diff --git a/runtime/container_linux.go b/runtime/container_linux.go deleted file mode 100644 index cb7d0cb..0000000 --- a/runtime/container_linux.go +++ /dev/null @@ -1,174 +0,0 @@ -package runtime - -import ( - "bufio" - "bytes" - "encoding/json" - "fmt" - "os" - "os/exec" - "path/filepath" - "strings" - "syscall" - - "github.com/docker/containerd/specs" - ocs "github.com/opencontainers/runtime-spec/specs-go" -) - -func findCgroupMountpointAndRoot(pid int, subsystem string) (string, string, error) { - f, err := os.Open(fmt.Sprintf("/proc/%d/mountinfo", pid)) - if err != nil { - return "", "", err - } - defer f.Close() - - scanner := bufio.NewScanner(f) - for scanner.Scan() { - txt := scanner.Text() - fields := strings.Split(txt, " ") - for _, opt := range strings.Split(fields[len(fields)-1], ",") { - if opt == subsystem { - return fields[4], fields[3], nil - } - } - } - if err := scanner.Err(); err != nil { - return "", "", err - } - - return "", "", fmt.Errorf("cgroup path for %s not found", subsystem) -} - -func parseCgroupFile(path string) (map[string]string, error) { - f, err := os.Open(path) - if err != nil { - return nil, err - } - defer f.Close() - - s := bufio.NewScanner(f) - cgroups := make(map[string]string) - - for s.Scan() { - if err := s.Err(); err != nil { - return nil, err - } - - text := s.Text() - parts := strings.Split(text, ":") - - for _, subs := range strings.Split(parts[1], ",") { - cgroups[subs] = parts[2] - } - } - return cgroups, nil -} - -func (c *container) OOM() (OOM, error) { - p := c.processes[InitProcessID] - if p == nil { - return nil, fmt.Errorf("no init process found") - } - - mountpoint, hostRoot, err := findCgroupMountpointAndRoot(os.Getpid(), "memory") - if err != nil { - return nil, err - } - - cgroups, err := parseCgroupFile(fmt.Sprintf("/proc/%d/cgroup", p.pid)) - if err != nil { - return nil, err - } - - root, ok := cgroups["memory"] - if !ok { - return nil, fmt.Errorf("no memory cgroup for container %s", c.ID()) - } - - // Take care of the case were we're running inside a container - // ourself - root = strings.TrimPrefix(root, hostRoot) - - return c.getMemeoryEventFD(filepath.Join(mountpoint, root)) -} - -func u64Ptr(i uint64) *uint64 { return &i } - -func (c *container) UpdateResources(r *Resource) error { - sr := ocs.Resources{ - Memory: &ocs.Memory{ - Limit: u64Ptr(uint64(r.Memory)), - Reservation: u64Ptr(uint64(r.MemoryReservation)), - Swap: u64Ptr(uint64(r.MemorySwap)), - Kernel: u64Ptr(uint64(r.KernelMemory)), - KernelTCP: u64Ptr(uint64(r.KernelTCPMemory)), - }, - CPU: &ocs.CPU{ - Shares: u64Ptr(uint64(r.CPUShares)), - Quota: u64Ptr(uint64(r.CPUQuota)), - Period: u64Ptr(uint64(r.CPUPeriod)), - Cpus: &r.CpusetCpus, - Mems: &r.CpusetMems, - }, - BlockIO: &ocs.BlockIO{ - Weight: &r.BlkioWeight, - }, - } - - srStr := bytes.NewBuffer(nil) - if err := json.NewEncoder(srStr).Encode(&sr); err != nil { - return err - } - - args := c.runtimeArgs - args = append(args, "update", "-r", "-", c.id) - cmd := exec.Command(c.runtime, args...) - cmd.Stdin = srStr - b, err := cmd.CombinedOutput() - if err != nil { - return fmt.Errorf(string(b)) - } - return nil -} - -func getRootIDs(s *specs.Spec) (int, int, error) { - if s == nil { - return 0, 0, nil - } - var hasUserns bool - for _, ns := range s.Linux.Namespaces { - if ns.Type == ocs.UserNamespace { - hasUserns = true - break - } - } - if !hasUserns { - return 0, 0, nil - } - uid := hostIDFromMap(0, s.Linux.UIDMappings) - gid := hostIDFromMap(0, s.Linux.GIDMappings) - return uid, gid, nil -} - -func (c *container) getMemeoryEventFD(root string) (*oom, error) { - f, err := os.Open(filepath.Join(root, "memory.oom_control")) - if err != nil { - return nil, err - } - fd, _, serr := syscall.RawSyscall(syscall.SYS_EVENTFD2, 0, syscall.FD_CLOEXEC, 0) - if serr != 0 { - f.Close() - return nil, serr - } - if err := c.writeEventFD(root, int(f.Fd()), int(fd)); err != nil { - syscall.Close(int(fd)) - f.Close() - return nil, err - } - return &oom{ - root: root, - id: c.id, - eventfd: int(fd), - control: f, - }, nil -} diff --git a/runtime/container_solaris.go b/runtime/container_solaris.go deleted file mode 100644 index 4d0d8b4..0000000 --- a/runtime/container_solaris.go +++ /dev/null @@ -1,19 +0,0 @@ -package runtime - -import ( - "errors" - - "github.com/docker/containerd/specs" -) - -func (c *container) OOM() (OOM, error) { - return nil, errors.New("runtime OOM() not implemented on Solaris") -} - -func (c *container) UpdateResources(r *Resource) error { - return errors.New("runtime UpdateResources() not implemented on Solaris") -} - -func getRootIDs(s *specs.Spec) (int, int, error) { - return 0, 0, errors.New("runtime getRootIDs() not implemented on Solaris") -} diff --git a/runtime/process.go b/runtime/process.go deleted file mode 100644 index e2e340d..0000000 --- a/runtime/process.go +++ /dev/null @@ -1,467 +0,0 @@ -package runtime - -import ( - "encoding/json" - "fmt" - "io" - "io/ioutil" - "os" - "os/exec" - "path/filepath" - "strconv" - "strings" - "sync" - "syscall" - "time" - - "github.com/Sirupsen/logrus" - "github.com/docker/containerd/specs" - "golang.org/x/sys/unix" -) - -// Process holds the operation allowed on a container's process -type Process interface { - io.Closer - - // ID of the process. - // This is either "init" when it is the container's init process or - // it is a user provided id for the process similar to the container id - ID() string - // Start unblocks the associated container init process. - // This should only be called on the process with ID "init" - Start() error - CloseStdin() error - Resize(int, int) error - // FD returns the fd the provides an event when the process exits - FD() int - // ExitStatus returns the exit status of the process or an error if it - // has not exited - ExitStatus() (uint32, error) - // Spec returns the process spec that created the process - Spec() specs.ProcessSpec - // Signal sends the provided signal to the process - Signal(os.Signal) error - // Container returns the container that the process belongs to - Container() Container - // Stdio of the container - Stdio() Stdio - // SystemPid is the pid on the system - SystemPid() int - // State returns if the process is running or not - State() State - // Wait reaps the shim process if avaliable - Wait() -} - -type processConfig struct { - id string - root string - processSpec specs.ProcessSpec - spec *specs.Spec - c *container - stdio Stdio - exec bool - checkpoint string -} - -func newProcess(config *processConfig) (*process, error) { - p := &process{ - root: config.root, - id: config.id, - container: config.c, - spec: config.processSpec, - stdio: config.stdio, - cmdDoneCh: make(chan struct{}), - state: Running, - } - uid, gid, err := getRootIDs(config.spec) - if err != nil { - return nil, err - } - f, err := os.Create(filepath.Join(config.root, "process.json")) - if err != nil { - return nil, err - } - defer f.Close() - - ps := ProcessState{ - ProcessSpec: config.processSpec, - Exec: config.exec, - PlatformProcessState: PlatformProcessState{ - Checkpoint: config.checkpoint, - RootUID: uid, - RootGID: gid, - }, - Stdin: config.stdio.Stdin, - Stdout: config.stdio.Stdout, - Stderr: config.stdio.Stderr, - RuntimeArgs: config.c.runtimeArgs, - NoPivotRoot: config.c.noPivotRoot, - } - - if err := json.NewEncoder(f).Encode(ps); err != nil { - return nil, err - } - exit, err := getExitPipe(filepath.Join(config.root, ExitFile)) - if err != nil { - return nil, err - } - control, err := getControlPipe(filepath.Join(config.root, ControlFile)) - if err != nil { - return nil, err - } - p.exitPipe = exit - p.controlPipe = control - return p, nil -} - -func loadProcess(root, id string, c *container, s *ProcessState) (*process, error) { - p := &process{ - root: root, - id: id, - container: c, - spec: s.ProcessSpec, - stdio: Stdio{ - Stdin: s.Stdin, - Stdout: s.Stdout, - Stderr: s.Stderr, - }, - state: Stopped, - } - - startTime, err := ioutil.ReadFile(filepath.Join(p.root, StartTimeFile)) - if err != nil && !os.IsNotExist(err) { - return nil, err - } - p.startTime = string(startTime) - - if _, err := p.getPidFromFile(); err != nil { - return nil, err - } - if _, err := p.ExitStatus(); err != nil { - if err == ErrProcessNotExited { - exit, err := getExitPipe(filepath.Join(root, ExitFile)) - if err != nil { - return nil, err - } - p.exitPipe = exit - - control, err := getControlPipe(filepath.Join(root, ControlFile)) - if err != nil { - return nil, err - } - p.controlPipe = control - - p.state = Running - return p, nil - } - return nil, err - } - return p, nil -} - -func readProcStatField(pid int, field int) (string, error) { - data, err := ioutil.ReadFile(filepath.Join(string(filepath.Separator), "proc", strconv.Itoa(pid), "stat")) - if err != nil { - return "", err - } - - if field > 2 { - // First, split out the name since he could contains spaces. - parts := strings.Split(string(data), ") ") - // Now split out the rest, we end up with 2 fields less - parts = strings.Split(parts[1], " ") - return parts[field-2-1], nil // field count start at 1 in manual - } - - parts := strings.Split(string(data), " (") - - if field == 1 { - return parts[0], nil - } - - parts = strings.Split(parts[1], ") ") - return parts[0], nil -} - -type process struct { - root string - id string - pid int - exitPipe *os.File - controlPipe *os.File - container *container - spec specs.ProcessSpec - stdio Stdio - cmd *exec.Cmd - cmdSuccess bool - cmdDoneCh chan struct{} - state State - stateLock sync.Mutex - startTime string -} - -func (p *process) ID() string { - return p.id -} - -func (p *process) Container() Container { - return p.container -} - -func (p *process) SystemPid() int { - return p.pid -} - -// FD returns the fd of the exit pipe -func (p *process) FD() int { - return int(p.exitPipe.Fd()) -} - -func (p *process) CloseStdin() error { - _, err := fmt.Fprintf(p.controlPipe, "%d %d %d\n", 0, 0, 0) - return err -} - -func (p *process) Resize(w, h int) error { - _, err := fmt.Fprintf(p.controlPipe, "%d %d %d\n", 1, w, h) - return err -} - -func (p *process) updateExitStatusFile(status uint32) (uint32, error) { - p.stateLock.Lock() - p.state = Stopped - p.stateLock.Unlock() - err := ioutil.WriteFile(filepath.Join(p.root, ExitStatusFile), []byte(fmt.Sprintf("%u", status)), 0644) - return status, err -} - -func (p *process) handleSigkilledShim(rst uint32, rerr error) (uint32, error) { - if p.cmd == nil || p.cmd.Process == nil { - e := unix.Kill(p.pid, 0) - if e == syscall.ESRCH { - logrus.Warnf("containerd: %s:%s (pid %d) does not exist", p.container.id, p.id, p.pid) - // The process died while containerd was down (probably of - // SIGKILL, but no way to be sure) - return p.updateExitStatusFile(UnknownStatus) - } - - // If it's not the same process, just mark it stopped and set - // the status to the UnknownStatus value (i.e. 255) - if same, err := p.isSameProcess(); !same { - logrus.Warnf("containerd: %s:%s (pid %d) is not the same process anymore (%v)", p.container.id, p.id, p.pid, err) - // Create the file so we get the exit event generated once monitor kicks in - // without having to go through all this process again - return p.updateExitStatusFile(UnknownStatus) - } - - ppid, err := readProcStatField(p.pid, 4) - if err != nil { - return rst, fmt.Errorf("could not check process ppid: %v (%v)", err, rerr) - } - if ppid == "1" { - logrus.Warnf("containerd: %s:%s shim died, killing associated process", p.container.id, p.id) - unix.Kill(p.pid, syscall.SIGKILL) - if err != nil && err != syscall.ESRCH { - return UnknownStatus, fmt.Errorf("containerd: unable to SIGKILL %s:%s (pid %v): %v", p.container.id, p.id, p.pid, err) - } - - // wait for the process to die - for { - e := unix.Kill(p.pid, 0) - if e == syscall.ESRCH { - break - } - time.Sleep(5 * time.Millisecond) - } - // Create the file so we get the exit event generated once monitor kicks in - // without having to go through all this process again - return p.updateExitStatusFile(128 + uint32(syscall.SIGKILL)) - } - - return rst, rerr - } - - // Possible that the shim was SIGKILLED - e := unix.Kill(p.cmd.Process.Pid, 0) - if e != syscall.ESRCH { - return rst, rerr - } - - // Ensure we got the shim ProcessState - <-p.cmdDoneCh - - shimStatus := p.cmd.ProcessState.Sys().(syscall.WaitStatus) - if shimStatus.Signaled() && shimStatus.Signal() == syscall.SIGKILL { - logrus.Debugf("containerd: ExitStatus(container: %s, process: %s): shim was SIGKILL'ed reaping its child with pid %d", p.container.id, p.id, p.pid) - - rerr = nil - rst = 128 + uint32(shimStatus.Signal()) - - p.stateLock.Lock() - p.state = Stopped - p.stateLock.Unlock() - } - - return rst, rerr -} - -func (p *process) ExitStatus() (rst uint32, rerr error) { - data, err := ioutil.ReadFile(filepath.Join(p.root, ExitStatusFile)) - defer func() { - if rerr != nil { - rst, rerr = p.handleSigkilledShim(rst, rerr) - } - }() - if err != nil { - if os.IsNotExist(err) { - return UnknownStatus, ErrProcessNotExited - } - return UnknownStatus, err - } - if len(data) == 0 { - return UnknownStatus, ErrProcessNotExited - } - p.stateLock.Lock() - p.state = Stopped - p.stateLock.Unlock() - - i, err := strconv.ParseUint(string(data), 10, 32) - return uint32(i), err -} - -func (p *process) Spec() specs.ProcessSpec { - return p.spec -} - -func (p *process) Stdio() Stdio { - return p.stdio -} - -// Close closes any open files and/or resouces on the process -func (p *process) Close() error { - err := p.exitPipe.Close() - if cerr := p.controlPipe.Close(); err == nil { - err = cerr - } - return err -} - -func (p *process) State() State { - p.stateLock.Lock() - defer p.stateLock.Unlock() - return p.state -} - -func (p *process) getPidFromFile() (int, error) { - data, err := ioutil.ReadFile(filepath.Join(p.root, "pid")) - if err != nil { - return -1, err - } - i, err := strconv.Atoi(string(data)) - if err != nil { - return -1, errInvalidPidInt - } - p.pid = i - return i, nil -} - -func (p *process) readStartTime() (string, error) { - return readProcStatField(p.pid, 22) -} - -func (p *process) saveStartTime() error { - startTime, err := p.readStartTime() - if err != nil { - return err - } - - p.startTime = startTime - return ioutil.WriteFile(filepath.Join(p.root, StartTimeFile), []byte(startTime), 0644) -} - -func (p *process) isSameProcess() (bool, error) { - // for backward compat assume it's the same if startTime wasn't set - if p.startTime == "" { - return true, nil - } - if p.pid == 0 { - _, err := p.getPidFromFile() - if err != nil { - return false, err - } - } - - startTime, err := p.readStartTime() - if err != nil { - return false, err - } - - return startTime == p.startTime, nil -} - -// Wait will reap the shim process -func (p *process) Wait() { - if p.cmdDoneCh != nil { - <-p.cmdDoneCh - } -} - -func getExitPipe(path string) (*os.File, error) { - if err := unix.Mkfifo(path, 0755); err != nil && !os.IsExist(err) { - return nil, err - } - // add NONBLOCK in case the other side has already closed or else - // this function would never return - return os.OpenFile(path, syscall.O_RDONLY|syscall.O_NONBLOCK, 0) -} - -func getControlPipe(path string) (*os.File, error) { - if err := unix.Mkfifo(path, 0755); err != nil && !os.IsExist(err) { - return nil, err - } - return os.OpenFile(path, syscall.O_RDWR|syscall.O_NONBLOCK, 0) -} - -// Signal sends the provided signal to the process -func (p *process) Signal(s os.Signal) error { - return syscall.Kill(p.pid, s.(syscall.Signal)) -} - -// Start unblocks the associated container init process. -// This should only be called on the process with ID "init" -func (p *process) Start() error { - if p.ID() == InitProcessID { - var ( - errC = make(chan error, 1) - args = append(p.container.runtimeArgs, "start", p.container.id) - cmd = exec.Command(p.container.runtime, args...) - ) - go func() { - out, err := cmd.CombinedOutput() - if err != nil { - errC <- fmt.Errorf("%s: %q", err.Error(), out) - } - errC <- nil - }() - select { - case err := <-errC: - if err != nil { - return err - } - case <-p.cmdDoneCh: - if !p.cmdSuccess { - if cmd.Process != nil { - cmd.Process.Kill() - } - cmd.Wait() - return ErrShimExited - } - err := <-errC - if err != nil { - return err - } - } - } - return nil -} diff --git a/runtime/runtime.go b/runtime/runtime.go deleted file mode 100644 index ef5dad9..0000000 --- a/runtime/runtime.go +++ /dev/null @@ -1,130 +0,0 @@ -package runtime - -import ( - "errors" - "time" - - "github.com/docker/containerd/specs" -) - -var ( - // ErrContainerExited is returned when access to an exited - // container is attempted - ErrContainerExited = errors.New("containerd: container has exited") - // ErrProcessNotExited is returned when trying to retrieve the exit - // status of an alive process - ErrProcessNotExited = errors.New("containerd: process has not exited") - // ErrContainerNotStarted is returned when a container fails to - // start without error from the shim or the OCI runtime - ErrContainerNotStarted = errors.New("containerd: container not started") - // ErrContainerStartTimeout is returned if a container takes too - // long to start - ErrContainerStartTimeout = errors.New("containerd: container did not start before the specified timeout") - // ErrShimExited is returned if the shim or the contianer's init process - // exits before completing - ErrShimExited = errors.New("containerd: shim exited before container process was started") - - errNoPidFile = errors.New("containerd: no process pid file found") - errInvalidPidInt = errors.New("containerd: process pid is invalid") - errNotImplemented = errors.New("containerd: not implemented") -) - -const ( - // ExitFile holds the name of the pipe used to monitor process - // exit - ExitFile = "exit" - // ExitStatusFile holds the name of the file where the container - // exit code is to be written - ExitStatusFile = "exitStatus" - // StateFile holds the name of the file where the container state - // is written - StateFile = "state.json" - // ControlFile holds the name of the pipe used to control the shim - ControlFile = "control" - // InitProcessID holds the special ID used for the very first - // container's process - InitProcessID = "init" - // StartTimeFile holds the name of the file in which the process - // start time is saved - StartTimeFile = "starttime" - - // UnknownStatus is the value returned when a process exit - // status cannot be determined - UnknownStatus = 255 -) - -// Checkpoint holds information regarding a container checkpoint -type Checkpoint struct { - // Timestamp is the time that checkpoint happened - Created time.Time `json:"created"` - // Name is the name of the checkpoint - Name string `json:"name"` - // TCP checkpoints open tcp connections - TCP bool `json:"tcp"` - // UnixSockets persists unix sockets in the checkpoint - UnixSockets bool `json:"unixSockets"` - // Shell persists tty sessions in the checkpoint - Shell bool `json:"shell"` - // Exit exits the container after the checkpoint is finished - Exit bool `json:"exit"` - // EmptyNS tells CRIU to omit a specified namespace - EmptyNS []string `json:"emptyNS,omitempty"` -} - -// PlatformProcessState container platform-specific fields in the ProcessState structure -type PlatformProcessState struct { - Checkpoint string `json:"checkpoint"` - RootUID int `json:"rootUID"` - RootGID int `json:"rootGID"` -} - -// State represents a container state -type State string - -// Resource regroups the various container limits that can be updated -type Resource struct { - CPUShares int64 - BlkioWeight uint16 - CPUPeriod int64 - CPUQuota int64 - CpusetCpus string - CpusetMems string - KernelMemory int64 - KernelTCPMemory int64 - Memory int64 - MemoryReservation int64 - MemorySwap int64 -} - -// Possible container states -const ( - Paused = State("paused") - Stopped = State("stopped") - Running = State("running") -) - -type state struct { - Bundle string `json:"bundle"` - Labels []string `json:"labels"` - Stdin string `json:"stdin"` - Stdout string `json:"stdout"` - Stderr string `json:"stderr"` - Runtime string `json:"runtime"` - RuntimeArgs []string `json:"runtimeArgs"` - Shim string `json:"shim"` - NoPivotRoot bool `json:"noPivotRoot"` -} - -// ProcessState holds the process OCI specs along with various fields -// required by containerd -type ProcessState struct { - specs.ProcessSpec - Exec bool `json:"exec"` - Stdin string `json:"containerdStdin"` - Stdout string `json:"containerdStdout"` - Stderr string `json:"containerdStderr"` - RuntimeArgs []string `json:"runtimeArgs"` - NoPivotRoot bool `json:"noPivotRoot"` - - PlatformProcessState -} diff --git a/runtime/runtime_test.go b/runtime/runtime_test.go deleted file mode 100644 index 3581493..0000000 --- a/runtime/runtime_test.go +++ /dev/null @@ -1,180 +0,0 @@ -package runtime - -import ( - "flag" - "fmt" - "io" - "os" - "os/exec" - "path/filepath" - "syscall" - "testing" - "time" - - utils "github.com/docker/containerd/testutils" -) - -var ( - devNull = "/dev/null" - stdin io.WriteCloser - runtimeTool = flag.String("runtime", "runc", "Runtime to use for this test") -) - -// Create containerd state and oci bundles directory -func setup() error { - if err := os.MkdirAll(utils.StateDir, 0755); err != nil { - return err - } - - if err := os.MkdirAll(utils.BundlesRoot, 0755); err != nil { - return err - } - return nil -} - -// Creates the bundleDir with rootfs, io fifo dir and a default spec. -// On success, returns the bundlePath -func setupBundle(bundleName string) (string, error) { - bundlePath := filepath.Join(utils.BundlesRoot, bundleName) - if err := os.MkdirAll(bundlePath, 0755); err != nil { - fmt.Println("Unable to create bundlePath due to ", err) - return "", err - } - - io := filepath.Join(bundlePath, "io") - if err := os.MkdirAll(io, 0755); err != nil { - fmt.Println("Unable to create io dir due to ", err) - return "", err - } - - if err := utils.GenerateReferenceSpecs(bundlePath); err != nil { - fmt.Println("Unable to generate OCI reference spec: ", err) - return "", err - } - - if err := utils.CreateBusyboxBundle(bundleName); err != nil { - fmt.Println("CreateBusyboxBundle error: ", err) - return "", err - } - - return bundlePath, nil -} - -func setupStdio(cwd string, bundlePath string, bundleName string) (Stdio, error) { - s := NewStdio(devNull, devNull, devNull) - - pid := "init" - for stdName, stdPath := range map[string]*string{ - "stdin": &s.Stdin, - "stdout": &s.Stdout, - "stderr": &s.Stderr, - } { - *stdPath = filepath.Join(cwd, bundlePath, "io", bundleName+"-"+pid+"-"+stdName) - if err := syscall.Mkfifo(*stdPath, 0755); err != nil && !os.IsExist(err) { - fmt.Println("Mkfifo error: ", err) - return s, err - } - } - - err := attachStdio(s) - if err != nil { - fmt.Println("attachStdio error: ", err) - return s, err - } - - return s, nil -} - -func attachStdio(s Stdio) error { - stdinf, err := os.OpenFile(s.Stdin, syscall.O_RDWR, 0) - if err != nil { - return err - } - stdin = stdinf - stdoutf, err := os.OpenFile(s.Stdout, syscall.O_RDWR, 0) - if err != nil { - return err - } - go io.Copy(os.Stdout, stdoutf) - stderrf, err := os.OpenFile(s.Stderr, syscall.O_RDWR, 0) - if err != nil { - return err - } - go io.Copy(os.Stderr, stderrf) - return nil -} - -func teardownBundle(bundleName string) { - containerRoot := filepath.Join(utils.StateDir, bundleName) - os.RemoveAll(containerRoot) - - bundlePath := filepath.Join(utils.BundlesRoot, bundleName) - os.RemoveAll(bundlePath) - return -} - -// Remove containerd state and oci bundles directory -func teardown() { - os.RemoveAll(utils.StateDir) - os.RemoveAll(utils.BundlesRoot) -} - -func BenchmarkBusyboxSh(b *testing.B) { - bundleName := "busybox-sh" - - wd := utils.GetTestOutDir() - if err := os.Chdir(wd); err != nil { - b.Fatalf("Could not change working directory: %v", err) - } - - if err := setup(); err != nil { - b.Fatalf("Error setting up test: %v", err) - } - defer teardown() - - for n := 0; n < b.N; n++ { - bundlePath, err := setupBundle(bundleName) - if err != nil { - return - } - - s, err := setupStdio(wd, bundlePath, bundleName) - if err != nil { - return - } - - c, err := New(ContainerOpts{ - Root: utils.StateDir, - ID: bundleName, - Bundle: filepath.Join(wd, bundlePath), - Runtime: *runtimeTool, - Shim: "containerd-shim", - Timeout: 15 * time.Second, - }) - - if err != nil { - b.Fatalf("Error creating a New container: ", err) - } - - benchmarkStartContainer(b, c, s, bundleName) - - teardownBundle(bundleName) - } -} - -func benchmarkStartContainer(b *testing.B, c Container, s Stdio, bundleName string) { - p, err := c.Start("", s) - if err != nil { - b.Fatalf("Error starting container %v", err) - } - - kill := exec.Command(c.Runtime(), "kill", bundleName, "KILL") - kill.Run() - - p.Wait() - c.Delete() - - // wait for kill to finish. selected wait time is arbitrary - time.Sleep(500 * time.Millisecond) - -} diff --git a/runtime/stats.go b/runtime/stats.go deleted file mode 100644 index 4cfa9e9..0000000 --- a/runtime/stats.go +++ /dev/null @@ -1,87 +0,0 @@ -package runtime - -import "time" - -// Stat holds a container statistics -type Stat struct { - // Timestamp is the time that the statistics where collected - Timestamp time.Time - CPU CPU `json:"cpu"` - Memory Memory `json:"memory"` - Pids Pids `json:"pids"` - Blkio Blkio `json:"blkio"` - Hugetlb map[string]Hugetlb `json:"hugetlb"` -} - -// Hugetlb holds information regarding a container huge tlb usage -type Hugetlb struct { - Usage uint64 `json:"usage,omitempty"` - Max uint64 `json:"max,omitempty"` - Failcnt uint64 `json:"failcnt"` -} - -// BlkioEntry represents a single record for a Blkio stat -type BlkioEntry struct { - Major uint64 `json:"major,omitempty"` - Minor uint64 `json:"minor,omitempty"` - Op string `json:"op,omitempty"` - Value uint64 `json:"value,omitempty"` -} - -// Blkio regroups all the Blkio related stats -type Blkio struct { - IoServiceBytesRecursive []BlkioEntry `json:"ioServiceBytesRecursive,omitempty"` - IoServicedRecursive []BlkioEntry `json:"ioServicedRecursive,omitempty"` - IoQueuedRecursive []BlkioEntry `json:"ioQueueRecursive,omitempty"` - IoServiceTimeRecursive []BlkioEntry `json:"ioServiceTimeRecursive,omitempty"` - IoWaitTimeRecursive []BlkioEntry `json:"ioWaitTimeRecursive,omitempty"` - IoMergedRecursive []BlkioEntry `json:"ioMergedRecursive,omitempty"` - IoTimeRecursive []BlkioEntry `json:"ioTimeRecursive,omitempty"` - SectorsRecursive []BlkioEntry `json:"sectorsRecursive,omitempty"` -} - -// Pids holds the stat of the pid usage of the machine -type Pids struct { - Current uint64 `json:"current,omitempty"` - Limit uint64 `json:"limit,omitempty"` -} - -// Throttling holds a cpu throttling information -type Throttling struct { - Periods uint64 `json:"periods,omitempty"` - ThrottledPeriods uint64 `json:"throttledPeriods,omitempty"` - ThrottledTime uint64 `json:"throttledTime,omitempty"` -} - -// CPUUsage holds information regarding cpu usage -type CPUUsage struct { - // Units: nanoseconds. - Total uint64 `json:"total,omitempty"` - Percpu []uint64 `json:"percpu,omitempty"` - Kernel uint64 `json:"kernel"` - User uint64 `json:"user"` -} - -// CPU regroups both a CPU usage and throttling information -type CPU struct { - Usage CPUUsage `json:"usage,omitempty"` - Throttling Throttling `json:"throttling,omitempty"` -} - -// MemoryEntry regroups statistic about a given type of memory -type MemoryEntry struct { - Limit uint64 `json:"limit"` - Usage uint64 `json:"usage,omitempty"` - Max uint64 `json:"max,omitempty"` - Failcnt uint64 `json:"failcnt"` -} - -// Memory holds information regarding the different type of memories available -type Memory struct { - Cache uint64 `json:"cache,omitempty"` - Usage MemoryEntry `json:"usage,omitempty"` - Swap MemoryEntry `json:"swap,omitempty"` - Kernel MemoryEntry `json:"kernel,omitempty"` - KernelTCP MemoryEntry `json:"kernelTCP,omitempty"` - Raw map[string]uint64 `json:"raw,omitempty"` -} diff --git a/specs/spec_linux.go b/specs/spec_linux.go deleted file mode 100644 index 7a2f053..0000000 --- a/specs/spec_linux.go +++ /dev/null @@ -1,12 +0,0 @@ -package specs - -import oci "github.com/opencontainers/runtime-spec/specs-go" - -type ( - // ProcessSpec aliases the platform process specs - ProcessSpec oci.Process - // Spec aliases the platform oci spec - Spec oci.Spec - // Rlimit aliases the platform resource limit - Rlimit oci.Rlimit -) diff --git a/specs/spec_solaris.go b/specs/spec_solaris.go deleted file mode 100644 index 625d27f..0000000 --- a/specs/spec_solaris.go +++ /dev/null @@ -1,8 +0,0 @@ -package specs - -import ocs "github.com/opencontainers/specs/specs-go" - -type ( - ProcessSpec ocs.Process - Spec ocs.Spec -) diff --git a/supervisor/add_process.go b/supervisor/add_process.go deleted file mode 100644 index 29d4e30..0000000 --- a/supervisor/add_process.go +++ /dev/null @@ -1,43 +0,0 @@ -package supervisor - -import ( - "time" - - "github.com/docker/containerd/runtime" - "github.com/docker/containerd/specs" -) - -// AddProcessTask holds everything necessary to add a process to a -// container -type AddProcessTask struct { - baseTask - ID string - PID string - Stdout string - Stderr string - Stdin string - ProcessSpec *specs.ProcessSpec - StartResponse chan StartResponse -} - -func (s *Supervisor) addProcess(t *AddProcessTask) error { - ci, ok := s.containers[t.ID] - if !ok { - return ErrContainerNotFound - } - process, err := ci.container.Exec(t.PID, *t.ProcessSpec, runtime.NewStdio(t.Stdin, t.Stdout, t.Stderr)) - if err != nil { - return err - } - if err := s.monitor.Add(process); err != nil { - return err - } - t.StartResponse <- StartResponse{} - s.notifySubscribers(Event{ - Timestamp: time.Now(), - Type: StateStartProcess, - PID: t.PID, - ID: t.ID, - }) - return nil -} diff --git a/supervisor/checkpoint.go b/supervisor/checkpoint.go deleted file mode 100644 index 394f966..0000000 --- a/supervisor/checkpoint.go +++ /dev/null @@ -1,37 +0,0 @@ -// +build !windows - -package supervisor - -import "github.com/docker/containerd/runtime" - -// CreateCheckpointTask holds needed parameters to create a new checkpoint -type CreateCheckpointTask struct { - baseTask - ID string - CheckpointDir string - Checkpoint *runtime.Checkpoint -} - -func (s *Supervisor) createCheckpoint(t *CreateCheckpointTask) error { - i, ok := s.containers[t.ID] - if !ok { - return ErrContainerNotFound - } - return i.container.Checkpoint(*t.Checkpoint, t.CheckpointDir) -} - -// DeleteCheckpointTask holds needed parameters to delete a checkpoint -type DeleteCheckpointTask struct { - baseTask - ID string - CheckpointDir string - Checkpoint *runtime.Checkpoint -} - -func (s *Supervisor) deleteCheckpoint(t *DeleteCheckpointTask) error { - i, ok := s.containers[t.ID] - if !ok { - return ErrContainerNotFound - } - return i.container.DeleteCheckpoint(t.Checkpoint.Name, t.CheckpointDir) -} diff --git a/supervisor/create.go b/supervisor/create.go deleted file mode 100644 index 8a99574..0000000 --- a/supervisor/create.go +++ /dev/null @@ -1,63 +0,0 @@ -package supervisor - -import ( - "path/filepath" - - "github.com/docker/containerd/runtime" -) - -// StartTask holds needed parameters to create a new container -type StartTask struct { - baseTask - ID string - BundlePath string - Stdout string - Stderr string - Stdin string - StartResponse chan StartResponse - Labels []string - NoPivotRoot bool - Checkpoint *runtime.Checkpoint - CheckpointDir string - Runtime string - RuntimeArgs []string -} - -func (s *Supervisor) start(t *StartTask) error { - rt := s.config.Runtime - rtArgs := s.config.RuntimeArgs - if t.Runtime != "" { - rt = t.Runtime - rtArgs = t.RuntimeArgs - } - container, err := runtime.New(runtime.ContainerOpts{ - Root: s.config.StateDir, - ID: t.ID, - Bundle: t.BundlePath, - Runtime: rt, - RuntimeArgs: rtArgs, - Shim: s.config.ShimName, - Labels: t.Labels, - NoPivotRoot: t.NoPivotRoot, - Timeout: s.config.Timeout, - }) - if err != nil { - return err - } - s.containers[t.ID] = &containerInfo{ - container: container, - } - task := &startTask{ - Err: t.ErrorCh(), - Container: container, - StartResponse: t.StartResponse, - Stdin: t.Stdin, - Stdout: t.Stdout, - Stderr: t.Stderr, - } - if t.Checkpoint != nil { - task.CheckpointPath = filepath.Join(t.CheckpointDir, t.Checkpoint.Name) - } - s.startTasks <- task - return errDeferredResponse -} diff --git a/supervisor/create_solaris.go b/supervisor/create_solaris.go deleted file mode 100644 index 444e55b..0000000 --- a/supervisor/create_solaris.go +++ /dev/null @@ -1,8 +0,0 @@ -package supervisor - -type platformStartTask struct { -} - -// Checkpoint not supported on Solaris -func (task *startTask) setTaskCheckpoint(t *StartTask) { -} diff --git a/supervisor/delete.go b/supervisor/delete.go deleted file mode 100644 index 4df53d8..0000000 --- a/supervisor/delete.go +++ /dev/null @@ -1,44 +0,0 @@ -package supervisor - -import ( - "time" - - "github.com/Sirupsen/logrus" - "github.com/docker/containerd/runtime" -) - -// DeleteTask holds needed parameters to remove a container -type DeleteTask struct { - baseTask - ID string - Status uint32 - PID string - NoEvent bool - Process runtime.Process -} - -func (s *Supervisor) delete(t *DeleteTask) error { - if i, ok := s.containers[t.ID]; ok { - if err := s.deleteContainer(i.container); err != nil { - logrus.WithField("error", err).Error("containerd: deleting container") - } - if t.Process != nil { - t.Process.Wait() - } - if !t.NoEvent { - s.notifySubscribers(Event{ - Type: StateExit, - Timestamp: time.Now(), - ID: t.ID, - Status: t.Status, - PID: t.PID, - }) - } - } - return nil -} - -func (s *Supervisor) deleteContainer(container runtime.Container) error { - delete(s.containers, container.ID()) - return container.Delete() -} diff --git a/supervisor/errors.go b/supervisor/errors.go deleted file mode 100644 index 930807d..0000000 --- a/supervisor/errors.go +++ /dev/null @@ -1,28 +0,0 @@ -package supervisor - -import "errors" - -var ( - // ErrContainerNotFound is returned when the container ID passed - // for a given operation is invalid - ErrContainerNotFound = errors.New("containerd: container not found") - // ErrProcessNotFound is returned when the process ID passed for - // a given operation is invalid - ErrProcessNotFound = errors.New("containerd: process not found for container") - // ErrUnknownContainerStatus is returned when the container status - // cannot be determined - ErrUnknownContainerStatus = errors.New("containerd: unknown container status ") - // ErrUnknownTask is returned when an unknown Task type is - // scheduled (should never happen). - ErrUnknownTask = errors.New("containerd: unknown task type") - - // Internal errors - errShutdown = errors.New("containerd: supervisor is shutdown") - errRootNotAbs = errors.New("containerd: rootfs path is not an absolute path") - errNoContainerForPid = errors.New("containerd: pid not registered for any container") - // internal error where the handler will defer to another for the final response - // - // TODO: we could probably do a typed error with another error channel for this to make it - // less like magic - errDeferredResponse = errors.New("containerd: deferred response") -) diff --git a/supervisor/exit.go b/supervisor/exit.go deleted file mode 100644 index f9f8580..0000000 --- a/supervisor/exit.go +++ /dev/null @@ -1,87 +0,0 @@ -package supervisor - -import ( - "time" - - "github.com/Sirupsen/logrus" - "github.com/docker/containerd/runtime" -) - -// ExitTask holds needed parameters to execute the exit task -type ExitTask struct { - baseTask - Process runtime.Process -} - -func (s *Supervisor) exit(t *ExitTask) error { - proc := t.Process - status, err := proc.ExitStatus() - if err != nil { - logrus.WithFields(logrus.Fields{ - "error": err, - "pid": proc.ID(), - "id": proc.Container().ID(), - "systemPid": proc.SystemPid(), - }).Error("containerd: get exit status") - } - logrus.WithFields(logrus.Fields{ - "pid": proc.ID(), - "status": status, - "id": proc.Container().ID(), - "systemPid": proc.SystemPid(), - }).Debug("containerd: process exited") - - // if the process is the the init process of the container then - // fire a separate event for this process - if proc.ID() != runtime.InitProcessID { - ne := &ExecExitTask{ - ID: proc.Container().ID(), - PID: proc.ID(), - Status: status, - Process: proc, - } - s.execExit(ne) - return nil - } - container := proc.Container() - ne := &DeleteTask{ - ID: container.ID(), - Status: status, - PID: proc.ID(), - Process: proc, - } - s.delete(ne) - return nil -} - -// ExecExitTask holds needed parameters to execute the exec exit task -type ExecExitTask struct { - baseTask - ID string - PID string - Status uint32 - Process runtime.Process -} - -func (s *Supervisor) execExit(t *ExecExitTask) error { - container := t.Process.Container() - // exec process: we remove this process without notifying the main event loop - if err := container.RemoveProcess(t.PID); err != nil { - logrus.WithField("error", err).Error("containerd: find container for pid") - } - // If the exec spawned children which are still using its IO - // waiting here will block until they die or close their IO - // descriptors. - // Hence, we use a go routine to avoid block all other operations - go func() { - t.Process.Wait() - s.notifySubscribers(Event{ - Timestamp: time.Now(), - ID: t.ID, - Type: StateExit, - PID: t.PID, - Status: t.Status, - }) - }() - return nil -} diff --git a/supervisor/get_containers.go b/supervisor/get_containers.go deleted file mode 100644 index 4d9c668..0000000 --- a/supervisor/get_containers.go +++ /dev/null @@ -1,47 +0,0 @@ -package supervisor - -import "github.com/docker/containerd/runtime" - -// GetContainersTask holds needed parameters to retrieve a list of -// containers -type GetContainersTask struct { - baseTask - ID string - GetState func(c runtime.Container) (interface{}, error) - - Containers []runtime.Container - States []interface{} -} - -func (s *Supervisor) getContainers(t *GetContainersTask) error { - - if t.ID != "" { - ci, ok := s.containers[t.ID] - if !ok { - return ErrContainerNotFound - } - t.Containers = append(t.Containers, ci.container) - if t.GetState != nil { - st, err := t.GetState(ci.container) - if err != nil { - return err - } - t.States = append(t.States, st) - } - - return nil - } - - for _, ci := range s.containers { - t.Containers = append(t.Containers, ci.container) - if t.GetState != nil { - st, err := t.GetState(ci.container) - if err != nil { - return err - } - t.States = append(t.States, st) - } - } - - return nil -} diff --git a/supervisor/machine.go b/supervisor/machine.go deleted file mode 100644 index 387c73a..0000000 --- a/supervisor/machine.go +++ /dev/null @@ -1,28 +0,0 @@ -// +build !solaris - -package supervisor - -import "github.com/cloudfoundry/gosigar" - -// Machine holds the current machine cpu count and ram size -type Machine struct { - Cpus int - Memory int64 -} - -// CollectMachineInformation returns information regarding the current -// machine (e.g. CPU count, RAM amount) -func CollectMachineInformation() (Machine, error) { - m := Machine{} - cpu := sigar.CpuList{} - if err := cpu.Get(); err != nil { - return m, err - } - m.Cpus = len(cpu.List) - mem := sigar.Mem{} - if err := mem.Get(); err != nil { - return m, err - } - m.Memory = int64(mem.Total / 1024 / 1024) - return m, nil -} diff --git a/supervisor/machine_solaris.go b/supervisor/machine_solaris.go deleted file mode 100644 index c044705..0000000 --- a/supervisor/machine_solaris.go +++ /dev/null @@ -1,15 +0,0 @@ -package supervisor - -import ( - "errors" -) - -type Machine struct { - Cpus int - Memory int64 -} - -func CollectMachineInformation() (Machine, error) { - m := Machine{} - return m, errors.New("supervisor CollectMachineInformation not implemented on Solaris") -} diff --git a/supervisor/oom.go b/supervisor/oom.go deleted file mode 100644 index 9d8c23d..0000000 --- a/supervisor/oom.go +++ /dev/null @@ -1,23 +0,0 @@ -package supervisor - -import ( - "time" - - "github.com/Sirupsen/logrus" -) - -// OOMTask holds needed parameters to report a container OOM -type OOMTask struct { - baseTask - ID string -} - -func (s *Supervisor) oom(t *OOMTask) error { - logrus.WithField("id", t.ID).Debug("containerd: container oom") - s.notifySubscribers(Event{ - Timestamp: time.Now(), - ID: t.ID, - Type: StateOOM, - }) - return nil -} diff --git a/supervisor/signal.go b/supervisor/signal.go deleted file mode 100644 index 007320d..0000000 --- a/supervisor/signal.go +++ /dev/null @@ -1,28 +0,0 @@ -package supervisor - -import "os" - -// SignalTask holds needed parameters to signal a container -type SignalTask struct { - baseTask - ID string - PID string - Signal os.Signal -} - -func (s *Supervisor) signal(t *SignalTask) error { - i, ok := s.containers[t.ID] - if !ok { - return ErrContainerNotFound - } - processes, err := i.container.Processes() - if err != nil { - return err - } - for _, p := range processes { - if p.ID() == t.PID { - return p.Signal(t.Signal) - } - } - return ErrProcessNotFound -} diff --git a/supervisor/sort.go b/supervisor/sort.go deleted file mode 100644 index 2153b7e..0000000 --- a/supervisor/sort.go +++ /dev/null @@ -1,27 +0,0 @@ -package supervisor - -import ( - "sort" - - "github.com/docker/containerd/runtime" -) - -func sortProcesses(p []runtime.Process) { - sort.Sort(&processSorter{p}) -} - -type processSorter struct { - processes []runtime.Process -} - -func (s *processSorter) Len() int { - return len(s.processes) -} - -func (s *processSorter) Swap(i, j int) { - s.processes[i], s.processes[j] = s.processes[j], s.processes[i] -} - -func (s *processSorter) Less(i, j int) bool { - return s.processes[j].ID() == "init" -} diff --git a/supervisor/sort_test.go b/supervisor/sort_test.go deleted file mode 100644 index 9a0467c..0000000 --- a/supervisor/sort_test.go +++ /dev/null @@ -1,89 +0,0 @@ -package supervisor - -import ( - "flag" - "os" - "sort" - "testing" - - "github.com/docker/containerd/runtime" - "github.com/docker/containerd/specs" -) - -var ( - runtimeTool = flag.String("runtime", "runc", "Runtime to use for this test") -) - -type testProcess struct { - id string -} - -func (p *testProcess) ID() string { - return p.id -} - -func (p *testProcess) Start() error { - return nil -} - -func (p *testProcess) CloseStdin() error { - return nil -} - -func (p *testProcess) Resize(w, h int) error { - return nil -} - -func (p *testProcess) Stdio() runtime.Stdio { - return runtime.Stdio{} -} - -func (p *testProcess) SystemPid() int { - return -1 -} - -func (p *testProcess) ExitFD() int { - return -1 -} - -func (p *testProcess) ExitStatus() (uint32, error) { - return runtime.UnknownStatus, nil -} - -func (p *testProcess) Container() runtime.Container { - return nil -} - -func (p *testProcess) Spec() specs.ProcessSpec { - return specs.ProcessSpec{} -} - -func (p *testProcess) Signal(os.Signal) error { - return nil -} - -func (p *testProcess) Close() error { - return nil -} - -func (p *testProcess) State() runtime.State { - return runtime.Running -} - -func (p *testProcess) Wait() { -} - -func TestSortProcesses(t *testing.T) { - p := []runtime.Process{ - &testProcess{"ls"}, - &testProcess{"other"}, - &testProcess{"init"}, - &testProcess{"other2"}, - } - s := &processSorter{p} - sort.Sort(s) - - if id := p[len(p)-1].ID(); id != "init" { - t.Fatalf("expected init but received %q", id) - } -} diff --git a/supervisor/stats.go b/supervisor/stats.go deleted file mode 100644 index 6fc0797..0000000 --- a/supervisor/stats.go +++ /dev/null @@ -1,28 +0,0 @@ -package supervisor - -import "github.com/docker/containerd/runtime" - -// StatsTask holds needed parameters to retrieve a container statistics -type StatsTask struct { - baseTask - ID string - Stat chan *runtime.Stat -} - -func (s *Supervisor) stats(t *StatsTask) error { - i, ok := s.containers[t.ID] - if !ok { - return ErrContainerNotFound - } - // TODO: use workers for this - go func() { - s, err := i.container.Stats() - if err != nil { - t.ErrorCh() <- err - return - } - t.ErrorCh() <- nil - t.Stat <- s - }() - return errDeferredResponse -} diff --git a/supervisor/supervisor.go b/supervisor/supervisor.go deleted file mode 100644 index fd7ee9a..0000000 --- a/supervisor/supervisor.go +++ /dev/null @@ -1,310 +0,0 @@ -package supervisor - -import ( - "io/ioutil" - "os" - "sync" - "time" - - "github.com/Sirupsen/logrus" - "github.com/docker/containerd/monitor" - "github.com/docker/containerd/runtime" -) - -const ( - defaultBufferSize = 2048 // size of queue in eventloop -) - -type Config struct { - StateDir string - Runtime string - ShimName string - RuntimeArgs []string - Timeout time.Duration - EventRetainCount int -} - -// New returns an initialized Process supervisor. -func New(c Config) (*Supervisor, error) { - startTasks := make(chan *startTask, 10) - if err := os.MkdirAll(c.StateDir, 0755); err != nil { - return nil, err - } - machine, err := CollectMachineInformation() - if err != nil { - return nil, err - } - m, err := monitor.New() - if err != nil { - return nil, err - } - go m.Run() - s := &Supervisor{ - config: c, - containers: make(map[string]*containerInfo), - startTasks: startTasks, - machine: machine, - subscribers: make(map[chan Event]struct{}), - tasks: make(chan Task, defaultBufferSize), - monitor: m, - } - if err := setupEventLog(s, c.EventRetainCount); err != nil { - return nil, err - } - go s.monitorEventHandler() - if err := s.restore(); err != nil { - return nil, err - } - return s, nil -} - -// Supervisor represents a container supervisor -type Supervisor struct { - config Config - containers map[string]*containerInfo - startTasks chan *startTask - // we need a lock around the subscribers map only because additions and deletions from - // the map are via the API so we cannot really control the concurrency - subscriberLock sync.RWMutex - subscribers map[chan Event]struct{} - machine Machine - tasks chan Task - monitor *monitor.Monitor - eventLog []Event - eventLock sync.Mutex -} - -// Stop closes all startTasks and sends a SIGTERM to each container's pid1 then waits for they to -// terminate. After it has handled all the SIGCHILD events it will close the signals chan -// and exit. Stop is a non-blocking call and will return after the containers have been signaled -func (s *Supervisor) Stop() { - // Close the startTasks channel so that no new containers get started - close(s.startTasks) -} - -// Close closes any open files in the supervisor but expects that Stop has been -// callsed so that no more containers are started. -func (s *Supervisor) Close() error { - return nil -} - -// Event represents a container event -type Event struct { - ID string `json:"id"` - Type string `json:"type"` - Timestamp time.Time `json:"timestamp"` - PID string `json:"pid,omitempty"` - Status uint32 `json:"status,omitempty"` -} - -// Events returns an event channel that external consumers can use to receive updates -// on container events -func (s *Supervisor) Events(from time.Time, storedOnly bool, id string) chan Event { - c := make(chan Event, defaultBufferSize) - if storedOnly { - defer s.Unsubscribe(c) - } - s.subscriberLock.Lock() - defer s.subscriberLock.Unlock() - if !from.IsZero() { - // replay old event - s.eventLock.Lock() - past := s.eventLog[:] - s.eventLock.Unlock() - for _, e := range past { - if e.Timestamp.After(from) { - if id == "" || e.ID == id { - c <- e - } - } - } - } - if storedOnly { - close(c) - } else { - s.subscribers[c] = struct{}{} - } - return c -} - -// Unsubscribe removes the provided channel from receiving any more events -func (s *Supervisor) Unsubscribe(sub chan Event) { - s.subscriberLock.Lock() - defer s.subscriberLock.Unlock() - if _, ok := s.subscribers[sub]; ok { - delete(s.subscribers, sub) - close(sub) - } -} - -// notifySubscribers will send the provided event to the external subscribers -// of the events channel -func (s *Supervisor) notifySubscribers(e Event) { - s.subscriberLock.RLock() - defer s.subscriberLock.RUnlock() - for sub := range s.subscribers { - // do a non-blocking send for the channel - select { - case sub <- e: - default: - logrus.WithField("event", e.Type).Warn("containerd: event not sent to subscriber") - } - } -} - -// Start is a non-blocking call that runs the supervisor for monitoring contianer processes and -// executing new containers. -// -// This event loop is the only thing that is allowed to modify state of containers and processes -// therefore it is save to do operations in the handlers that modify state of the system or -// state of the Supervisor -func (s *Supervisor) Start() error { - logrus.WithFields(logrus.Fields{ - "stateDir": s.config.StateDir, - "runtime": s.config.Runtime, - "runtimeArgs": s.config.RuntimeArgs, - "memory": s.machine.Memory, - "cpus": s.machine.Cpus, - }).Debug("containerd: supervisor running") - go func() { - for i := range s.tasks { - s.handleTask(i) - } - }() - return nil -} - -// Machine returns the machine information for which the -// supervisor is executing on. -func (s *Supervisor) Machine() Machine { - return s.machine -} - -// SendTask sends the provided event the the supervisors main event loop -func (s *Supervisor) SendTask(evt Task) { - s.tasks <- evt -} - -func (s *Supervisor) monitorEventHandler() { - for e := range s.monitor.Events() { - switch t := e.(type) { - case runtime.Process: - if err := s.monitor.Remove(e); err != nil { - logrus.WithField("error", err).Error("containerd: remove process event FD from monitor") - } - if err := t.Close(); err != nil { - logrus.WithField("error", err).Error("containerd: close process event FD") - } - ev := &ExitTask{ - Process: t, - } - s.SendTask(ev) - case runtime.OOM: - if t.Removed() { - if err := s.monitor.Remove(e); err != nil { - logrus.WithField("error", err).Error("containerd: remove oom event FD from monitor") - } - if err := t.Close(); err != nil { - logrus.WithField("error", err).Error("containerd: close oom event FD") - } - // don't send an event on the close of this FD - continue - } - ev := &OOMTask{ - ID: t.ContainerID(), - } - s.SendTask(ev) - } - } -} - -func (s *Supervisor) restore() error { - dirs, err := ioutil.ReadDir(s.config.StateDir) - if err != nil { - return err - } - for _, d := range dirs { - if !d.IsDir() { - continue - } - id := d.Name() - container, err := runtime.Load(s.config.StateDir, id, s.config.ShimName, s.config.Timeout) - if err != nil { - return err - } - processes, err := container.Processes() - if err != nil { - return err - } - - s.containers[id] = &containerInfo{ - container: container, - } - oom, err := container.OOM() - if err != nil { - logrus.WithField("error", err).Error("containerd: get oom FD") - } - if err := s.monitor.Add(oom); err != nil && err != runtime.ErrContainerExited { - logrus.WithField("error", err).Error("containerd: notify OOM events") - } - logrus.WithField("id", id).Debug("containerd: container restored") - var exitedProcesses []runtime.Process - for _, p := range processes { - if p.State() == runtime.Running { - if err := s.monitor.Add(p); err != nil { - return err - } - } else { - exitedProcesses = append(exitedProcesses, p) - } - } - if len(exitedProcesses) > 0 { - // sort processes so that init is fired last because that is how the kernel sends the - // exit events - sortProcesses(exitedProcesses) - for _, p := range exitedProcesses { - e := &ExitTask{ - Process: p, - } - s.SendTask(e) - } - } - } - return nil -} - -func (s *Supervisor) handleTask(i Task) { - var err error - switch t := i.(type) { - case *AddProcessTask: - err = s.addProcess(t) - case *CreateCheckpointTask: - err = s.createCheckpoint(t) - case *DeleteCheckpointTask: - err = s.deleteCheckpoint(t) - case *StartTask: - err = s.start(t) - case *DeleteTask: - err = s.delete(t) - case *ExitTask: - err = s.exit(t) - case *GetContainersTask: - err = s.getContainers(t) - case *SignalTask: - err = s.signal(t) - case *StatsTask: - err = s.stats(t) - case *UpdateTask: - err = s.updateContainer(t) - case *UpdateProcessTask: - err = s.updateProcess(t) - case *OOMTask: - err = s.oom(t) - default: - err = ErrUnknownTask - } - if err != errDeferredResponse { - i.ErrorCh() <- err - close(i.ErrorCh()) - } -} diff --git a/supervisor/task.go b/supervisor/task.go deleted file mode 100644 index 4d6d1c5..0000000 --- a/supervisor/task.go +++ /dev/null @@ -1,33 +0,0 @@ -package supervisor - -import ( - "sync" - - "github.com/docker/containerd/runtime" -) - -// StartResponse is the response containing a started container -type StartResponse struct { - Container runtime.Container -} - -// Task executes an action returning an error chan with either nil or -// the error from executing the task -type Task interface { - // ErrorCh returns a channel used to report and error from an async task - ErrorCh() chan error -} - -type baseTask struct { - errCh chan error - mu sync.Mutex -} - -func (t *baseTask) ErrorCh() chan error { - t.mu.Lock() - defer t.mu.Unlock() - if t.errCh == nil { - t.errCh = make(chan error, 1) - } - return t.errCh -} diff --git a/supervisor/types.go b/supervisor/types.go deleted file mode 100644 index 2e36fce..0000000 --- a/supervisor/types.go +++ /dev/null @@ -1,12 +0,0 @@ -package supervisor - -// State constants used in Event types -const ( - StateStart = "start-container" - StatePause = "pause" - StateResume = "resume" - StateExit = "exit" - StateStartProcess = "start-process" - StateOOM = "oom" - StateLive = "live" -) diff --git a/supervisor/update.go b/supervisor/update.go deleted file mode 100644 index f86a648..0000000 --- a/supervisor/update.go +++ /dev/null @@ -1,95 +0,0 @@ -package supervisor - -import ( - "time" - - "github.com/docker/containerd/runtime" -) - -// UpdateTask holds needed parameters to update a container resource constraints -type UpdateTask struct { - baseTask - ID string - State runtime.State - Resources *runtime.Resource -} - -func (s *Supervisor) updateContainer(t *UpdateTask) error { - i, ok := s.containers[t.ID] - if !ok { - return ErrContainerNotFound - } - container := i.container - if t.State != "" { - switch t.State { - case runtime.Running: - if err := container.Resume(); err != nil { - return err - } - s.notifySubscribers(Event{ - ID: t.ID, - Type: StateResume, - Timestamp: time.Now(), - }) - case runtime.Paused: - if err := container.Pause(); err != nil { - return err - } - s.notifySubscribers(Event{ - ID: t.ID, - Type: StatePause, - Timestamp: time.Now(), - }) - default: - return ErrUnknownContainerStatus - } - return nil - } - if t.Resources != nil { - return container.UpdateResources(t.Resources) - } - return nil -} - -// UpdateProcessTask holds needed parameters to update a container -// process terminal size or close its stdin -type UpdateProcessTask struct { - baseTask - ID string - PID string - CloseStdin bool - Width int - Height int -} - -func (s *Supervisor) updateProcess(t *UpdateProcessTask) error { - i, ok := s.containers[t.ID] - if !ok { - return ErrContainerNotFound - } - processes, err := i.container.Processes() - if err != nil { - return err - } - var process runtime.Process - for _, p := range processes { - if p.ID() == t.PID { - process = p - break - } - } - if process == nil { - return ErrProcessNotFound - } - if t.CloseStdin { - if err := process.CloseStdin(); err != nil { - return err - } - } - if t.Width > 0 || t.Height > 0 { - if err := process.Resize(t.Width, t.Height); err != nil { - return err - } - } - return nil -} diff --git a/supervisor/utils.go b/supervisor/utils.go deleted file mode 100644 index 138f873..0000000 --- a/supervisor/utils.go +++ /dev/null @@ -1,101 +0,0 @@ -package supervisor - -import ( - "encoding/json" - "io" - "os" - "path/filepath" - "time" - - "github.com/Sirupsen/logrus" - "github.com/docker/containerd/runtime" -) - -type containerInfo struct { - container runtime.Container -} - -func setupEventLog(s *Supervisor, retainCount int) error { - if err := readEventLog(s); err != nil { - return err - } - logrus.WithField("count", len(s.eventLog)).Debug("containerd: read past events") - events := s.Events(time.Time{}, false, "") - return eventLogger(s, filepath.Join(s.config.StateDir, "events.log"), events, retainCount) -} - -func eventLogger(s *Supervisor, path string, events chan Event, retainCount int) error { - f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND|os.O_TRUNC, 0755) - if err != nil { - return err - } - go func() { - var ( - count = len(s.eventLog) - enc = json.NewEncoder(f) - ) - for e := range events { - // if we have a specified retain count make sure the truncate the event - // log if it grows past the specified number of events to keep. - if retainCount > 0 { - if count > retainCount { - logrus.Debug("truncating event log") - // close the log file - if f != nil { - f.Close() - } - slice := retainCount - 1 - l := len(s.eventLog) - if slice >= l { - slice = l - } - s.eventLock.Lock() - s.eventLog = s.eventLog[len(s.eventLog)-slice:] - s.eventLock.Unlock() - if f, err = os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND|os.O_TRUNC, 0755); err != nil { - logrus.WithField("error", err).Error("containerd: open event to journal") - continue - } - enc = json.NewEncoder(f) - count = 0 - for _, le := range s.eventLog { - if err := enc.Encode(le); err != nil { - logrus.WithField("error", err).Error("containerd: write event to journal") - } - } - } - } - s.eventLock.Lock() - s.eventLog = append(s.eventLog, e) - s.eventLock.Unlock() - count++ - if err := enc.Encode(e); err != nil { - logrus.WithField("error", err).Error("containerd: write event to journal") - } - } - }() - return nil -} - -func readEventLog(s *Supervisor) error { - f, err := os.Open(filepath.Join(s.config.StateDir, "events.log")) - if err != nil { - if os.IsNotExist(err) { - return nil - } - return err - } - defer f.Close() - dec := json.NewDecoder(f) - for { - var e Event - if err := dec.Decode(&e); err != nil { - if err == io.EOF { - break - } - return err - } - s.eventLog = append(s.eventLog, e) - } - return nil -} diff --git a/supervisor/worker.go b/supervisor/worker.go deleted file mode 100644 index 5e3b70a..0000000 --- a/supervisor/worker.go +++ /dev/null @@ -1,103 +0,0 @@ -package supervisor - -import ( - "sync" - "time" - - "github.com/Sirupsen/logrus" - "github.com/docker/containerd/runtime" -) - -// Worker interface -type Worker interface { - Start() -} - -type startTask struct { - Container runtime.Container - CheckpointPath string - Stdin string - Stdout string - Stderr string - Err chan error - StartResponse chan StartResponse -} - -// NewWorker return a new initialized worker -func NewWorker(s *Supervisor, wg *sync.WaitGroup) Worker { - return &worker{ - s: s, - wg: wg, - } -} - -type worker struct { - wg *sync.WaitGroup - s *Supervisor -} - -// Start runs a loop in charge of starting new containers -func (w *worker) Start() { - defer w.wg.Done() - for t := range w.s.startTasks { - process, err := t.Container.Start(t.CheckpointPath, runtime.NewStdio(t.Stdin, t.Stdout, t.Stderr)) - if err != nil { - logrus.WithFields(logrus.Fields{ - "error": err, - "id": t.Container.ID(), - }).Error("containerd: start container") - t.Err <- err - evt := &DeleteTask{ - ID: t.Container.ID(), - NoEvent: true, - Process: process, - } - w.s.SendTask(evt) - continue - } - oom, err := t.Container.OOM() - if err != nil { - logrus.WithField("error", err).Error("containerd: get oom FD") - } - if err := w.s.monitor.Add(oom); err != nil && err != runtime.ErrContainerExited { - if process.State() != runtime.Stopped { - logrus.WithField("error", err).Error("containerd: notify OOM events") - } - } - if err := w.s.monitor.Add(process); err != nil { - logrus.WithField("error", err).Error("containerd: add process to monitor") - t.Err <- err - evt := &DeleteTask{ - ID: t.Container.ID(), - NoEvent: true, - Process: process, - } - w.s.SendTask(evt) - continue - } - // only call process start if we aren't restoring from a checkpoint - // if we have restored from a checkpoint then the process is already started - if t.CheckpointPath == "" { - if err := process.Start(); err != nil { - logrus.WithField("error", err).Error("containerd: start init process") - t.Err <- err - evt := &DeleteTask{ - ID: t.Container.ID(), - NoEvent: true, - Process: process, - } - w.s.SendTask(evt) - continue - } - } - t.Err <- nil - t.StartResponse <- StartResponse{ - Container: t.Container, - } - w.s.notifySubscribers(Event{ - Timestamp: time.Now(), - ID: t.Container.ID(), - Type: StateStart, - }) - } -} diff --git a/testutils/testutils.go b/testutils/testutils.go deleted file mode 100644 index 2feb0cc..0000000 --- a/testutils/testutils.go +++ /dev/null @@ -1,70 +0,0 @@ -package testutils - -import ( - "fmt" - "os" - "os/exec" - "path/filepath" - "strings" -) - -// GetTestOutDir returns the output directory for testing and benchmark artifacts -func GetTestOutDir() string { - out, _ := exec.Command("git", "rev-parse", "--show-toplevel").CombinedOutput() - repoRoot := string(out) - prefix := filepath.Join(strings.TrimSpace(repoRoot), "output") - return prefix -} - -var ( - // ArchivesDir holds the location of the available rootfs - ArchivesDir = filepath.Join("test-artifacts", "archives") - // BundlesRoot holds the location where OCI Bundles are stored - BundlesRoot = filepath.Join("test-artifacts", "oci-bundles") - // OutputDirFormat holds the standard format used when creating a - // new test output directory - OutputDirFormat = filepath.Join("test-artifacts", "runs", "%s") - // RefOciSpecsPath holds the path to the generic OCI config - RefOciSpecsPath = filepath.Join(BundlesRoot, "config.json") - // StateDir holds the path to the directory used by the containerd - // started by tests - StateDir = "/run/containerd-bench-test" -) - -// untarRootfs untars the given `source` tarPath into `destination/rootfs` -func untarRootfs(source string, destination string) error { - rootfs := filepath.Join(destination, "rootfs") - - if err := os.MkdirAll(rootfs, 0755); err != nil { - fmt.Println("untarRootfs os.MkdirAll failed with err %v", err) - return nil - } - tar := exec.Command("tar", "-C", rootfs, "-xf", source) - return tar.Run() -} - -// GenerateReferenceSpecs generates a default OCI specs via `runc spec` -func GenerateReferenceSpecs(destination string) error { - if _, err := os.Stat(filepath.Join(destination, "config.json")); err == nil { - return nil - } - specs := exec.Command("runc", "spec") - specs.Dir = destination - return specs.Run() -} - -// CreateBundle generates a valid OCI bundle from the given rootfs -func CreateBundle(source, name string) error { - bundlePath := filepath.Join(BundlesRoot, name) - - if err := untarRootfs(filepath.Join(ArchivesDir, source+".tar"), bundlePath); err != nil { - return fmt.Errorf("Failed to untar %s.tar: %v", source, err) - } - - return nil -} - -// CreateBusyboxBundle generates a bundle based on the busybox rootfs -func CreateBusyboxBundle(name string) error { - return CreateBundle("busybox", name) -}