Remove bundles from API
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
1dc5d652ac
commit
ab8586b7c5
48 changed files with 3287 additions and 5946 deletions
File diff suppressed because it is too large
Load diff
|
@ -3,116 +3,54 @@ syntax = "proto3";
|
|||
package containerd.v1.services;
|
||||
|
||||
import "google/protobuf/empty.proto";
|
||||
import "google/protobuf/any.proto";
|
||||
import "gogoproto/gogo.proto";
|
||||
import "github.com/docker/containerd/api/types/mount/mount.proto";
|
||||
import "github.com/docker/containerd/api/types/container/container.proto";
|
||||
import "github.com/docker/containerd/api/types/process/process.proto";
|
||||
|
||||
service ExecutionService {
|
||||
rpc CreateContainer(CreateContainerRequest) returns (CreateContainerResponse);
|
||||
rpc StartContainer(StartContainerRequest) returns (google.protobuf.Empty);
|
||||
rpc UpdateContainer(UpdateContainerRequest) returns (google.protobuf.Empty);
|
||||
rpc PauseContainer(PauseContainerRequest) returns (google.protobuf.Empty);
|
||||
rpc ResumeContainer(ResumeContainerRequest) returns (google.protobuf.Empty);
|
||||
rpc DeleteContainer(DeleteContainerRequest) returns (google.protobuf.Empty);
|
||||
rpc GetContainer(GetContainerRequest) returns (GetContainerResponse);
|
||||
rpc ListContainers(ListContainersRequest) returns (ListContainersResponse);
|
||||
|
||||
rpc StartProcess(StartProcessRequest) returns (StartProcessResponse);
|
||||
rpc GetProcess(GetProcessRequest) returns (GetProcessResponse);
|
||||
rpc SignalProcess(SignalProcessRequest) returns (google.protobuf.Empty);
|
||||
rpc DeleteProcess(DeleteProcessRequest) returns (google.protobuf.Empty);
|
||||
rpc ListProcesses(ListProcessesRequest) returns (ListProcessesResponse);
|
||||
service ContainerService {
|
||||
rpc Create(CreateRequest) returns (CreateResponse);
|
||||
rpc Start(StartRequest) returns (google.protobuf.Empty);
|
||||
rpc Delete(DeleteRequest) returns (google.protobuf.Empty);
|
||||
rpc List(ListRequest) returns (ListResponse);
|
||||
rpc Events(EventsRequest) returns (stream containerd.v1.types.Event);
|
||||
}
|
||||
|
||||
message StartContainerRequest {
|
||||
message CreateRequest {
|
||||
string id = 1 [(gogoproto.customname) = "ID"];
|
||||
google.protobuf.Any spec = 2;
|
||||
repeated containerd.v1.types.Mount rootfs = 3;
|
||||
string runtime = 4;
|
||||
string stdin = 5;
|
||||
string stdout = 6;
|
||||
string stderr = 7;
|
||||
bool terminal = 8;
|
||||
}
|
||||
|
||||
|
||||
message CreateContainerRequest {
|
||||
message CreateResponse {
|
||||
string id = 1 [(gogoproto.customname) = "ID"];
|
||||
string bundle_path = 2;
|
||||
bool console = 3;
|
||||
string stdin = 4;
|
||||
string stdout = 5;
|
||||
string stderr = 6;
|
||||
}
|
||||
|
||||
message CreateContainerResponse {
|
||||
types.Container container = 1;
|
||||
types.Process initProcess = 2;
|
||||
}
|
||||
|
||||
message DeleteContainerRequest {
|
||||
string id = 1 [(gogoproto.customname) = "ID"];
|
||||
}
|
||||
|
||||
message ListContainersRequest {
|
||||
repeated string owner = 1;
|
||||
}
|
||||
|
||||
message ListContainersResponse {
|
||||
repeated types.Container containers = 1;
|
||||
}
|
||||
|
||||
message StartProcessRequest {
|
||||
string container_id = 1 [(gogoproto.customname) = "ContainerID"];
|
||||
types.Process process = 2;
|
||||
bool console = 3;
|
||||
string stdin = 4;
|
||||
string stdout = 5;
|
||||
string stderr = 6;
|
||||
}
|
||||
|
||||
message StartProcessResponse {
|
||||
types.Process process = 1;
|
||||
}
|
||||
|
||||
message GetContainerRequest {
|
||||
string id = 1 [(gogoproto.customname) = "ID"];
|
||||
}
|
||||
|
||||
message GetContainerResponse {
|
||||
types.Container container = 1;
|
||||
}
|
||||
|
||||
message UpdateContainerRequest {
|
||||
string container_id = 1 [(gogoproto.customname) = "ContainerID"];
|
||||
string bundle_path = 2;
|
||||
}
|
||||
|
||||
message PauseContainerRequest {
|
||||
string id = 1 [(gogoproto.customname) = "ID"];
|
||||
}
|
||||
|
||||
message ResumeContainerRequest {
|
||||
string id = 1 [(gogoproto.customname) = "ID"];
|
||||
}
|
||||
|
||||
message GetProcessRequest {
|
||||
string container_id = 1 [(gogoproto.customname) = "ContainerID"];
|
||||
uint32 pid = 2;
|
||||
}
|
||||
|
||||
message GetProcessResponse {
|
||||
types.Process process = 1;
|
||||
message StartRequest {
|
||||
string id = 1 [(gogoproto.customname) = "ID"];
|
||||
}
|
||||
|
||||
message SignalProcessRequest {
|
||||
string container_id = 1 [(gogoproto.customname) = "ContainerID"];
|
||||
uint32 pid = 2;
|
||||
uint32 signal = 3;
|
||||
message DeleteRequest {
|
||||
string id = 1 [(gogoproto.customname) = "ID"];
|
||||
}
|
||||
|
||||
message DeleteProcessRequest {
|
||||
string container_id = 1 [(gogoproto.customname) = "ContainerID"];
|
||||
uint32 pid = 2;
|
||||
message DeleteResponse {
|
||||
string id = 1 [(gogoproto.customname) = "ID"];
|
||||
uint32 exit_status = 2;
|
||||
}
|
||||
|
||||
message ListProcessesRequest {
|
||||
string container_id = 1 [(gogoproto.customname) = "ContainerID"];
|
||||
message ListRequest {
|
||||
}
|
||||
|
||||
message ListProcessesResponse {
|
||||
repeated types.Process processes = 1;
|
||||
message ListResponse {
|
||||
repeated containerd.v1.types.Container containers = 1;
|
||||
}
|
||||
|
||||
message EventsRequest {
|
||||
}
|
||||
|
|
|
@ -19,11 +19,11 @@
|
|||
ExecResponse
|
||||
PtyRequest
|
||||
EventsRequest
|
||||
Event
|
||||
StateRequest
|
||||
StateResponse
|
||||
PauseRequest
|
||||
ResumeRequest
|
||||
ExitRequest
|
||||
*/
|
||||
package shim
|
||||
|
||||
|
@ -32,8 +32,8 @@ import fmt "fmt"
|
|||
import math "math"
|
||||
import google_protobuf "github.com/golang/protobuf/ptypes/empty"
|
||||
import _ "github.com/gogo/protobuf/gogoproto"
|
||||
import containerd_v1_types2 "github.com/docker/containerd/api/types/process"
|
||||
import containerd_v1_types "github.com/docker/containerd/api/types/user"
|
||||
import containerd_v1_types "github.com/docker/containerd/api/types/mount"
|
||||
import containerd_v1_types1 "github.com/docker/containerd/api/types/container"
|
||||
|
||||
import (
|
||||
context "golang.org/x/net/context"
|
||||
|
@ -56,45 +56,16 @@ var _ = math.Inf
|
|||
// proto package needs to be updated.
|
||||
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
type EventType int32
|
||||
|
||||
const (
|
||||
EventType_EXIT EventType = 0
|
||||
EventType_OOM EventType = 1
|
||||
EventType_CREATE EventType = 2
|
||||
EventType_START EventType = 3
|
||||
EventType_EXEC_ADDED EventType = 4
|
||||
)
|
||||
|
||||
var EventType_name = map[int32]string{
|
||||
0: "EXIT",
|
||||
1: "OOM",
|
||||
2: "CREATE",
|
||||
3: "START",
|
||||
4: "EXEC_ADDED",
|
||||
}
|
||||
var EventType_value = map[string]int32{
|
||||
"EXIT": 0,
|
||||
"OOM": 1,
|
||||
"CREATE": 2,
|
||||
"START": 3,
|
||||
"EXEC_ADDED": 4,
|
||||
}
|
||||
|
||||
func (x EventType) String() string {
|
||||
return proto.EnumName(EventType_name, int32(x))
|
||||
}
|
||||
func (EventType) EnumDescriptor() ([]byte, []int) { return fileDescriptorShim, []int{0} }
|
||||
|
||||
type CreateRequest struct {
|
||||
ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Bundle string `protobuf:"bytes,2,opt,name=bundle,proto3" json:"bundle,omitempty"`
|
||||
Runtime string `protobuf:"bytes,3,opt,name=runtime,proto3" json:"runtime,omitempty"`
|
||||
NoPivot bool `protobuf:"varint,4,opt,name=no_pivot,json=noPivot,proto3" json:"no_pivot,omitempty"`
|
||||
Terminal bool `protobuf:"varint,5,opt,name=terminal,proto3" json:"terminal,omitempty"`
|
||||
Stdin string `protobuf:"bytes,6,opt,name=stdin,proto3" json:"stdin,omitempty"`
|
||||
Stdout string `protobuf:"bytes,7,opt,name=stdout,proto3" json:"stdout,omitempty"`
|
||||
Stderr string `protobuf:"bytes,8,opt,name=stderr,proto3" json:"stderr,omitempty"`
|
||||
ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Bundle string `protobuf:"bytes,2,opt,name=bundle,proto3" json:"bundle,omitempty"`
|
||||
Runtime string `protobuf:"bytes,3,opt,name=runtime,proto3" json:"runtime,omitempty"`
|
||||
NoPivot bool `protobuf:"varint,4,opt,name=no_pivot,json=noPivot,proto3" json:"no_pivot,omitempty"`
|
||||
Terminal bool `protobuf:"varint,5,opt,name=terminal,proto3" json:"terminal,omitempty"`
|
||||
Stdin string `protobuf:"bytes,6,opt,name=stdin,proto3" json:"stdin,omitempty"`
|
||||
Stdout string `protobuf:"bytes,7,opt,name=stdout,proto3" json:"stdout,omitempty"`
|
||||
Stderr string `protobuf:"bytes,8,opt,name=stderr,proto3" json:"stderr,omitempty"`
|
||||
Rootfs []*containerd_v1_types.Mount `protobuf:"bytes,9,rep,name=rootfs" json:"rootfs,omitempty"`
|
||||
}
|
||||
|
||||
func (m *CreateRequest) Reset() { *m = CreateRequest{} }
|
||||
|
@ -133,19 +104,19 @@ func (*DeleteResponse) ProtoMessage() {}
|
|||
func (*DeleteResponse) Descriptor() ([]byte, []int) { return fileDescriptorShim, []int{4} }
|
||||
|
||||
type ExecRequest struct {
|
||||
Terminal bool `protobuf:"varint,1,opt,name=terminal,proto3" json:"terminal,omitempty"`
|
||||
Stdin string `protobuf:"bytes,2,opt,name=stdin,proto3" json:"stdin,omitempty"`
|
||||
Stdout string `protobuf:"bytes,3,opt,name=stdout,proto3" json:"stdout,omitempty"`
|
||||
Stderr string `protobuf:"bytes,4,opt,name=stderr,proto3" json:"stderr,omitempty"`
|
||||
SelinuxLabel string `protobuf:"bytes,5,opt,name=selinux_label,json=selinuxLabel,proto3" json:"selinux_label,omitempty"`
|
||||
User *containerd_v1_types.User `protobuf:"bytes,6,opt,name=user" json:"user,omitempty"`
|
||||
Args []string `protobuf:"bytes,7,rep,name=args" json:"args,omitempty"`
|
||||
Env []string `protobuf:"bytes,8,rep,name=env" json:"env,omitempty"`
|
||||
Cwd string `protobuf:"bytes,9,opt,name=cwd,proto3" json:"cwd,omitempty"`
|
||||
Capabilities []string `protobuf:"bytes,10,rep,name=capabilities" json:"capabilities,omitempty"`
|
||||
Rlimits []*Rlimit `protobuf:"bytes,11,rep,name=rlimits" json:"rlimits,omitempty"`
|
||||
NoNewPrivileges bool `protobuf:"varint,12,opt,name=no_new_privileges,json=noNewPrivileges,proto3" json:"no_new_privileges,omitempty"`
|
||||
ApparmorProfile string `protobuf:"bytes,13,opt,name=apparmor_profile,json=apparmorProfile,proto3" json:"apparmor_profile,omitempty"`
|
||||
Terminal bool `protobuf:"varint,1,opt,name=terminal,proto3" json:"terminal,omitempty"`
|
||||
Stdin string `protobuf:"bytes,2,opt,name=stdin,proto3" json:"stdin,omitempty"`
|
||||
Stdout string `protobuf:"bytes,3,opt,name=stdout,proto3" json:"stdout,omitempty"`
|
||||
Stderr string `protobuf:"bytes,4,opt,name=stderr,proto3" json:"stderr,omitempty"`
|
||||
SelinuxLabel string `protobuf:"bytes,5,opt,name=selinux_label,json=selinuxLabel,proto3" json:"selinux_label,omitempty"`
|
||||
User *containerd_v1_types1.User `protobuf:"bytes,6,opt,name=user" json:"user,omitempty"`
|
||||
Args []string `protobuf:"bytes,7,rep,name=args" json:"args,omitempty"`
|
||||
Env []string `protobuf:"bytes,8,rep,name=env" json:"env,omitempty"`
|
||||
Cwd string `protobuf:"bytes,9,opt,name=cwd,proto3" json:"cwd,omitempty"`
|
||||
Capabilities []string `protobuf:"bytes,10,rep,name=capabilities" json:"capabilities,omitempty"`
|
||||
Rlimits []*Rlimit `protobuf:"bytes,11,rep,name=rlimits" json:"rlimits,omitempty"`
|
||||
NoNewPrivileges bool `protobuf:"varint,12,opt,name=no_new_privileges,json=noNewPrivileges,proto3" json:"no_new_privileges,omitempty"`
|
||||
ApparmorProfile string `protobuf:"bytes,13,opt,name=apparmor_profile,json=apparmorProfile,proto3" json:"apparmor_profile,omitempty"`
|
||||
}
|
||||
|
||||
func (m *ExecRequest) Reset() { *m = ExecRequest{} }
|
||||
|
@ -187,49 +158,44 @@ func (m *EventsRequest) Reset() { *m = EventsRequest{} }
|
|||
func (*EventsRequest) ProtoMessage() {}
|
||||
func (*EventsRequest) Descriptor() ([]byte, []int) { return fileDescriptorShim, []int{9} }
|
||||
|
||||
// should be moved to api/types/event maybe
|
||||
type Event struct {
|
||||
ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Type EventType `protobuf:"varint,2,opt,name=type,proto3,enum=containerd.v1.services.EventType" json:"type,omitempty"`
|
||||
Pid uint32 `protobuf:"varint,3,opt,name=pid,proto3" json:"pid,omitempty"`
|
||||
ExitStatus uint32 `protobuf:"varint,4,opt,name=exit_status,json=exitStatus,proto3" json:"exit_status,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Event) Reset() { *m = Event{} }
|
||||
func (*Event) ProtoMessage() {}
|
||||
func (*Event) Descriptor() ([]byte, []int) { return fileDescriptorShim, []int{10} }
|
||||
|
||||
type StateRequest struct {
|
||||
}
|
||||
|
||||
func (m *StateRequest) Reset() { *m = StateRequest{} }
|
||||
func (*StateRequest) ProtoMessage() {}
|
||||
func (*StateRequest) Descriptor() ([]byte, []int) { return fileDescriptorShim, []int{11} }
|
||||
func (*StateRequest) Descriptor() ([]byte, []int) { return fileDescriptorShim, []int{10} }
|
||||
|
||||
type StateResponse struct {
|
||||
ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Bundle string `protobuf:"bytes,2,opt,name=bundle,proto3" json:"bundle,omitempty"`
|
||||
InitPid uint32 `protobuf:"varint,3,opt,name=initPid,proto3" json:"initPid,omitempty"`
|
||||
Processes []*containerd_v1_types2.Process `protobuf:"bytes,4,rep,name=processes" json:"processes,omitempty"`
|
||||
Pid uint32 `protobuf:"varint,3,opt,name=pid,proto3" json:"pid,omitempty"`
|
||||
Processes []*containerd_v1_types1.Process `protobuf:"bytes,4,rep,name=processes" json:"processes,omitempty"`
|
||||
}
|
||||
|
||||
func (m *StateResponse) Reset() { *m = StateResponse{} }
|
||||
func (*StateResponse) ProtoMessage() {}
|
||||
func (*StateResponse) Descriptor() ([]byte, []int) { return fileDescriptorShim, []int{12} }
|
||||
func (*StateResponse) Descriptor() ([]byte, []int) { return fileDescriptorShim, []int{11} }
|
||||
|
||||
type PauseRequest struct {
|
||||
}
|
||||
|
||||
func (m *PauseRequest) Reset() { *m = PauseRequest{} }
|
||||
func (*PauseRequest) ProtoMessage() {}
|
||||
func (*PauseRequest) Descriptor() ([]byte, []int) { return fileDescriptorShim, []int{13} }
|
||||
func (*PauseRequest) Descriptor() ([]byte, []int) { return fileDescriptorShim, []int{12} }
|
||||
|
||||
type ResumeRequest struct {
|
||||
}
|
||||
|
||||
func (m *ResumeRequest) Reset() { *m = ResumeRequest{} }
|
||||
func (*ResumeRequest) ProtoMessage() {}
|
||||
func (*ResumeRequest) Descriptor() ([]byte, []int) { return fileDescriptorShim, []int{14} }
|
||||
func (*ResumeRequest) Descriptor() ([]byte, []int) { return fileDescriptorShim, []int{13} }
|
||||
|
||||
type ExitRequest struct {
|
||||
}
|
||||
|
||||
func (m *ExitRequest) Reset() { *m = ExitRequest{} }
|
||||
func (*ExitRequest) ProtoMessage() {}
|
||||
func (*ExitRequest) Descriptor() ([]byte, []int) { return fileDescriptorShim, []int{14} }
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*CreateRequest)(nil), "containerd.v1.services.CreateRequest")
|
||||
|
@ -242,12 +208,11 @@ func init() {
|
|||
proto.RegisterType((*ExecResponse)(nil), "containerd.v1.services.ExecResponse")
|
||||
proto.RegisterType((*PtyRequest)(nil), "containerd.v1.services.PtyRequest")
|
||||
proto.RegisterType((*EventsRequest)(nil), "containerd.v1.services.EventsRequest")
|
||||
proto.RegisterType((*Event)(nil), "containerd.v1.services.Event")
|
||||
proto.RegisterType((*StateRequest)(nil), "containerd.v1.services.StateRequest")
|
||||
proto.RegisterType((*StateResponse)(nil), "containerd.v1.services.StateResponse")
|
||||
proto.RegisterType((*PauseRequest)(nil), "containerd.v1.services.PauseRequest")
|
||||
proto.RegisterType((*ResumeRequest)(nil), "containerd.v1.services.ResumeRequest")
|
||||
proto.RegisterEnum("containerd.v1.services.EventType", EventType_name, EventType_value)
|
||||
proto.RegisterType((*ExitRequest)(nil), "containerd.v1.services.ExitRequest")
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
@ -270,6 +235,7 @@ type ShimClient interface {
|
|||
State(ctx context.Context, in *StateRequest, opts ...grpc.CallOption) (*StateResponse, error)
|
||||
Pause(ctx context.Context, in *PauseRequest, opts ...grpc.CallOption) (*google_protobuf.Empty, error)
|
||||
Resume(ctx context.Context, in *ResumeRequest, opts ...grpc.CallOption) (*google_protobuf.Empty, error)
|
||||
Exit(ctx context.Context, in *ExitRequest, opts ...grpc.CallOption) (*google_protobuf.Empty, error)
|
||||
}
|
||||
|
||||
type shimClient struct {
|
||||
|
@ -341,7 +307,7 @@ func (c *shimClient) Events(ctx context.Context, in *EventsRequest, opts ...grpc
|
|||
}
|
||||
|
||||
type Shim_EventsClient interface {
|
||||
Recv() (*Event, error)
|
||||
Recv() (*containerd_v1_types1.Event, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
|
@ -349,8 +315,8 @@ type shimEventsClient struct {
|
|||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *shimEventsClient) Recv() (*Event, error) {
|
||||
m := new(Event)
|
||||
func (x *shimEventsClient) Recv() (*containerd_v1_types1.Event, error) {
|
||||
m := new(containerd_v1_types1.Event)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -384,6 +350,15 @@ func (c *shimClient) Resume(ctx context.Context, in *ResumeRequest, opts ...grpc
|
|||
return out, nil
|
||||
}
|
||||
|
||||
func (c *shimClient) Exit(ctx context.Context, in *ExitRequest, opts ...grpc.CallOption) (*google_protobuf.Empty, error) {
|
||||
out := new(google_protobuf.Empty)
|
||||
err := grpc.Invoke(ctx, "/containerd.v1.services.Shim/Exit", in, out, c.cc, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Server API for Shim service
|
||||
|
||||
type ShimServer interface {
|
||||
|
@ -396,6 +371,7 @@ type ShimServer interface {
|
|||
State(context.Context, *StateRequest) (*StateResponse, error)
|
||||
Pause(context.Context, *PauseRequest) (*google_protobuf.Empty, error)
|
||||
Resume(context.Context, *ResumeRequest) (*google_protobuf.Empty, error)
|
||||
Exit(context.Context, *ExitRequest) (*google_protobuf.Empty, error)
|
||||
}
|
||||
|
||||
func RegisterShimServer(s *grpc.Server, srv ShimServer) {
|
||||
|
@ -501,7 +477,7 @@ func _Shim_Events_Handler(srv interface{}, stream grpc.ServerStream) error {
|
|||
}
|
||||
|
||||
type Shim_EventsServer interface {
|
||||
Send(*Event) error
|
||||
Send(*containerd_v1_types1.Event) error
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
|
@ -509,7 +485,7 @@ type shimEventsServer struct {
|
|||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *shimEventsServer) Send(m *Event) error {
|
||||
func (x *shimEventsServer) Send(m *containerd_v1_types1.Event) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
|
@ -567,6 +543,24 @@ func _Shim_Resume_Handler(srv interface{}, ctx context.Context, dec func(interfa
|
|||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Shim_Exit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ExitRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ShimServer).Exit(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/containerd.v1.services.Shim/Exit",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ShimServer).Exit(ctx, req.(*ExitRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _Shim_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "containerd.v1.services.Shim",
|
||||
HandlerType: (*ShimServer)(nil),
|
||||
|
@ -603,6 +597,10 @@ var _Shim_serviceDesc = grpc.ServiceDesc{
|
|||
MethodName: "Resume",
|
||||
Handler: _Shim_Resume_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Exit",
|
||||
Handler: _Shim_Exit_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
|
@ -685,6 +683,18 @@ func (m *CreateRequest) MarshalTo(dAtA []byte) (int, error) {
|
|||
i = encodeVarintShim(dAtA, i, uint64(len(m.Stderr)))
|
||||
i += copy(dAtA[i:], m.Stderr)
|
||||
}
|
||||
if len(m.Rootfs) > 0 {
|
||||
for _, msg := range m.Rootfs {
|
||||
dAtA[i] = 0x4a
|
||||
i++
|
||||
i = encodeVarintShim(dAtA, i, uint64(msg.Size()))
|
||||
n, err := msg.MarshalTo(dAtA[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n
|
||||
}
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
|
@ -1024,45 +1034,6 @@ func (m *EventsRequest) MarshalTo(dAtA []byte) (int, error) {
|
|||
return i, nil
|
||||
}
|
||||
|
||||
func (m *Event) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalTo(dAtA)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *Event) MarshalTo(dAtA []byte) (int, error) {
|
||||
var i int
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.ID) > 0 {
|
||||
dAtA[i] = 0xa
|
||||
i++
|
||||
i = encodeVarintShim(dAtA, i, uint64(len(m.ID)))
|
||||
i += copy(dAtA[i:], m.ID)
|
||||
}
|
||||
if m.Type != 0 {
|
||||
dAtA[i] = 0x10
|
||||
i++
|
||||
i = encodeVarintShim(dAtA, i, uint64(m.Type))
|
||||
}
|
||||
if m.Pid != 0 {
|
||||
dAtA[i] = 0x18
|
||||
i++
|
||||
i = encodeVarintShim(dAtA, i, uint64(m.Pid))
|
||||
}
|
||||
if m.ExitStatus != 0 {
|
||||
dAtA[i] = 0x20
|
||||
i++
|
||||
i = encodeVarintShim(dAtA, i, uint64(m.ExitStatus))
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func (m *StateRequest) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
|
@ -1108,10 +1079,10 @@ func (m *StateResponse) MarshalTo(dAtA []byte) (int, error) {
|
|||
i = encodeVarintShim(dAtA, i, uint64(len(m.Bundle)))
|
||||
i += copy(dAtA[i:], m.Bundle)
|
||||
}
|
||||
if m.InitPid != 0 {
|
||||
if m.Pid != 0 {
|
||||
dAtA[i] = 0x18
|
||||
i++
|
||||
i = encodeVarintShim(dAtA, i, uint64(m.InitPid))
|
||||
i = encodeVarintShim(dAtA, i, uint64(m.Pid))
|
||||
}
|
||||
if len(m.Processes) > 0 {
|
||||
for _, msg := range m.Processes {
|
||||
|
@ -1164,6 +1135,24 @@ func (m *ResumeRequest) MarshalTo(dAtA []byte) (int, error) {
|
|||
return i, nil
|
||||
}
|
||||
|
||||
func (m *ExitRequest) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalTo(dAtA)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *ExitRequest) MarshalTo(dAtA []byte) (int, error) {
|
||||
var i int
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func encodeFixed64Shim(dAtA []byte, offset int, v uint64) int {
|
||||
dAtA[offset] = uint8(v)
|
||||
dAtA[offset+1] = uint8(v >> 8)
|
||||
|
@ -1224,6 +1213,12 @@ func (m *CreateRequest) Size() (n int) {
|
|||
if l > 0 {
|
||||
n += 1 + l + sovShim(uint64(l))
|
||||
}
|
||||
if len(m.Rootfs) > 0 {
|
||||
for _, e := range m.Rootfs {
|
||||
l = e.Size()
|
||||
n += 1 + l + sovShim(uint64(l))
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
|
@ -1370,25 +1365,6 @@ func (m *EventsRequest) Size() (n int) {
|
|||
return n
|
||||
}
|
||||
|
||||
func (m *Event) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
l = len(m.ID)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovShim(uint64(l))
|
||||
}
|
||||
if m.Type != 0 {
|
||||
n += 1 + sovShim(uint64(m.Type))
|
||||
}
|
||||
if m.Pid != 0 {
|
||||
n += 1 + sovShim(uint64(m.Pid))
|
||||
}
|
||||
if m.ExitStatus != 0 {
|
||||
n += 1 + sovShim(uint64(m.ExitStatus))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *StateRequest) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
|
@ -1406,8 +1382,8 @@ func (m *StateResponse) Size() (n int) {
|
|||
if l > 0 {
|
||||
n += 1 + l + sovShim(uint64(l))
|
||||
}
|
||||
if m.InitPid != 0 {
|
||||
n += 1 + sovShim(uint64(m.InitPid))
|
||||
if m.Pid != 0 {
|
||||
n += 1 + sovShim(uint64(m.Pid))
|
||||
}
|
||||
if len(m.Processes) > 0 {
|
||||
for _, e := range m.Processes {
|
||||
|
@ -1430,6 +1406,12 @@ func (m *ResumeRequest) Size() (n int) {
|
|||
return n
|
||||
}
|
||||
|
||||
func (m *ExitRequest) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
return n
|
||||
}
|
||||
|
||||
func sovShim(x uint64) (n int) {
|
||||
for {
|
||||
n++
|
||||
|
@ -1456,6 +1438,7 @@ func (this *CreateRequest) String() string {
|
|||
`Stdin:` + fmt.Sprintf("%v", this.Stdin) + `,`,
|
||||
`Stdout:` + fmt.Sprintf("%v", this.Stdout) + `,`,
|
||||
`Stderr:` + fmt.Sprintf("%v", this.Stderr) + `,`,
|
||||
`Rootfs:` + strings.Replace(fmt.Sprintf("%v", this.Rootfs), "Mount", "containerd_v1_types.Mount", 1) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
|
@ -1509,7 +1492,7 @@ func (this *ExecRequest) String() string {
|
|||
`Stdout:` + fmt.Sprintf("%v", this.Stdout) + `,`,
|
||||
`Stderr:` + fmt.Sprintf("%v", this.Stderr) + `,`,
|
||||
`SelinuxLabel:` + fmt.Sprintf("%v", this.SelinuxLabel) + `,`,
|
||||
`User:` + strings.Replace(fmt.Sprintf("%v", this.User), "User", "containerd_v1_types.User", 1) + `,`,
|
||||
`User:` + strings.Replace(fmt.Sprintf("%v", this.User), "User", "containerd_v1_types1.User", 1) + `,`,
|
||||
`Args:` + fmt.Sprintf("%v", this.Args) + `,`,
|
||||
`Env:` + fmt.Sprintf("%v", this.Env) + `,`,
|
||||
`Cwd:` + fmt.Sprintf("%v", this.Cwd) + `,`,
|
||||
|
@ -1564,19 +1547,6 @@ func (this *EventsRequest) String() string {
|
|||
}, "")
|
||||
return s
|
||||
}
|
||||
func (this *Event) String() string {
|
||||
if this == nil {
|
||||
return "nil"
|
||||
}
|
||||
s := strings.Join([]string{`&Event{`,
|
||||
`ID:` + fmt.Sprintf("%v", this.ID) + `,`,
|
||||
`Type:` + fmt.Sprintf("%v", this.Type) + `,`,
|
||||
`Pid:` + fmt.Sprintf("%v", this.Pid) + `,`,
|
||||
`ExitStatus:` + fmt.Sprintf("%v", this.ExitStatus) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
}
|
||||
func (this *StateRequest) String() string {
|
||||
if this == nil {
|
||||
return "nil"
|
||||
|
@ -1593,8 +1563,8 @@ func (this *StateResponse) String() string {
|
|||
s := strings.Join([]string{`&StateResponse{`,
|
||||
`ID:` + fmt.Sprintf("%v", this.ID) + `,`,
|
||||
`Bundle:` + fmt.Sprintf("%v", this.Bundle) + `,`,
|
||||
`InitPid:` + fmt.Sprintf("%v", this.InitPid) + `,`,
|
||||
`Processes:` + strings.Replace(fmt.Sprintf("%v", this.Processes), "Process", "containerd_v1_types2.Process", 1) + `,`,
|
||||
`Pid:` + fmt.Sprintf("%v", this.Pid) + `,`,
|
||||
`Processes:` + strings.Replace(fmt.Sprintf("%v", this.Processes), "Process", "containerd_v1_types1.Process", 1) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
|
@ -1617,6 +1587,15 @@ func (this *ResumeRequest) String() string {
|
|||
}, "")
|
||||
return s
|
||||
}
|
||||
func (this *ExitRequest) String() string {
|
||||
if this == nil {
|
||||
return "nil"
|
||||
}
|
||||
s := strings.Join([]string{`&ExitRequest{`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
}
|
||||
func valueToStringShim(v interface{}) string {
|
||||
rv := reflect.ValueOf(v)
|
||||
if rv.IsNil() {
|
||||
|
@ -1868,6 +1847,37 @@ func (m *CreateRequest) Unmarshal(dAtA []byte) error {
|
|||
}
|
||||
m.Stderr = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 9:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Rootfs", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowShim
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthShim
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Rootfs = append(m.Rootfs, &containerd_v1_types.Mount{})
|
||||
if err := m.Rootfs[len(m.Rootfs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipShim(dAtA[iNdEx:])
|
||||
|
@ -2338,7 +2348,7 @@ func (m *ExecRequest) Unmarshal(dAtA []byte) error {
|
|||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.User == nil {
|
||||
m.User = &containerd_v1_types.User{}
|
||||
m.User = &containerd_v1_types1.User{}
|
||||
}
|
||||
if err := m.User.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
|
@ -2904,142 +2914,6 @@ func (m *EventsRequest) Unmarshal(dAtA []byte) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
func (m *Event) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowShim
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: Event: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: Event: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowShim
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthShim
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.ID = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType)
|
||||
}
|
||||
m.Type = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowShim
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.Type |= (EventType(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 3:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Pid", wireType)
|
||||
}
|
||||
m.Pid = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowShim
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.Pid |= (uint32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 4:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ExitStatus", wireType)
|
||||
}
|
||||
m.ExitStatus = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowShim
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.ExitStatus |= (uint32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipShim(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthShim
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *StateRequest) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
|
@ -3179,9 +3053,9 @@ func (m *StateResponse) Unmarshal(dAtA []byte) error {
|
|||
iNdEx = postIndex
|
||||
case 3:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field InitPid", wireType)
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Pid", wireType)
|
||||
}
|
||||
m.InitPid = 0
|
||||
m.Pid = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowShim
|
||||
|
@ -3191,7 +3065,7 @@ func (m *StateResponse) Unmarshal(dAtA []byte) error {
|
|||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.InitPid |= (uint32(b) & 0x7F) << shift
|
||||
m.Pid |= (uint32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
|
@ -3222,7 +3096,7 @@ func (m *StateResponse) Unmarshal(dAtA []byte) error {
|
|||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Processes = append(m.Processes, &containerd_v1_types2.Process{})
|
||||
m.Processes = append(m.Processes, &containerd_v1_types1.Process{})
|
||||
if err := m.Processes[len(m.Processes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -3348,6 +3222,56 @@ func (m *ResumeRequest) Unmarshal(dAtA []byte) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
func (m *ExitRequest) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowShim
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: ExitRequest: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: ExitRequest: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipShim(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthShim
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func skipShim(dAtA []byte) (n int, err error) {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
|
@ -3458,66 +3382,63 @@ func init() {
|
|||
}
|
||||
|
||||
var fileDescriptorShim = []byte{
|
||||
// 976 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x9c, 0x55, 0x4f, 0x6f, 0xe3, 0x44,
|
||||
0x14, 0xaf, 0x13, 0xe7, 0xdf, 0x6b, 0xdd, 0x86, 0xd1, 0xaa, 0xf2, 0x06, 0xc8, 0x76, 0xbd, 0xbb,
|
||||
0xa8, 0xac, 0x84, 0xc3, 0x16, 0x81, 0x00, 0x71, 0xe9, 0x36, 0x16, 0x5a, 0x69, 0x61, 0x83, 0x1b,
|
||||
0xc4, 0xde, 0x22, 0x27, 0x7e, 0x4d, 0x46, 0x38, 0xb6, 0x99, 0x19, 0xa7, 0xed, 0x8d, 0x2b, 0x1f,
|
||||
0x80, 0xef, 0xc1, 0xc7, 0xd8, 0x0b, 0x12, 0x27, 0xc4, 0x09, 0xb1, 0xf9, 0x24, 0x68, 0x66, 0xec,
|
||||
0xa4, 0xd9, 0xad, 0x5b, 0xc4, 0x25, 0x79, 0xef, 0xe7, 0xdf, 0xbc, 0x79, 0xff, 0x07, 0xbe, 0x98,
|
||||
0x52, 0x31, 0xcb, 0xc6, 0xee, 0x24, 0x99, 0xf7, 0xc2, 0x64, 0xf2, 0x23, 0xb2, 0xde, 0x24, 0x89,
|
||||
0x45, 0x40, 0x63, 0x64, 0x61, 0x2f, 0x48, 0x69, 0x8f, 0x23, 0x5b, 0xd0, 0x09, 0xf2, 0x1e, 0x9f,
|
||||
0xd1, 0xb9, 0xfa, 0x71, 0x53, 0x96, 0x88, 0x84, 0xec, 0xaf, 0x89, 0xee, 0xe2, 0x89, 0x5b, 0xf0,
|
||||
0x3a, 0xef, 0x4e, 0x93, 0x64, 0x1a, 0x61, 0x4f, 0xb1, 0xc6, 0xd9, 0x59, 0x0f, 0xe7, 0xa9, 0xb8,
|
||||
0xd4, 0x87, 0x3a, 0x77, 0xa6, 0xc9, 0x34, 0x51, 0x62, 0x4f, 0x4a, 0x39, 0xfa, 0xd5, 0xad, 0x5e,
|
||||
0x88, 0xcb, 0x14, 0xb9, 0x34, 0x39, 0x41, 0xbe, 0xfa, 0xcf, 0x4f, 0x7f, 0xf6, 0x1f, 0x4f, 0x67,
|
||||
0x1c, 0x99, 0xfa, 0xd1, 0xe7, 0x9c, 0x3f, 0x0d, 0xb0, 0x4e, 0x18, 0x06, 0x02, 0x7d, 0xfc, 0x29,
|
||||
0x43, 0x2e, 0xc8, 0x3e, 0x54, 0x68, 0x68, 0x1b, 0x07, 0xc6, 0x61, 0xeb, 0x69, 0x7d, 0xf9, 0xf7,
|
||||
0xbd, 0xca, 0xb3, 0xbe, 0x5f, 0xa1, 0x21, 0xd9, 0x87, 0xfa, 0x38, 0x8b, 0xc3, 0x08, 0xed, 0x8a,
|
||||
0xfc, 0xe6, 0xe7, 0x1a, 0xb1, 0xa1, 0xc1, 0xb2, 0x58, 0xd0, 0x39, 0xda, 0x55, 0xf5, 0xa1, 0x50,
|
||||
0xc9, 0x5d, 0x68, 0xc6, 0xc9, 0x28, 0xa5, 0x8b, 0x44, 0xd8, 0xe6, 0x81, 0x71, 0xd8, 0xf4, 0x1b,
|
||||
0x71, 0x32, 0x90, 0x2a, 0xe9, 0x40, 0x53, 0x20, 0x9b, 0xd3, 0x38, 0x88, 0xec, 0x9a, 0xfa, 0xb4,
|
||||
0xd2, 0xc9, 0x1d, 0xa8, 0x71, 0x11, 0xd2, 0xd8, 0xae, 0x2b, 0x73, 0x5a, 0x91, 0xd7, 0x73, 0x11,
|
||||
0x26, 0x99, 0xb0, 0x1b, 0xfa, 0x7a, 0xad, 0xe5, 0x38, 0x32, 0x66, 0x37, 0x57, 0x38, 0x32, 0xe6,
|
||||
0x38, 0xb0, 0x5b, 0xc4, 0xc5, 0xd3, 0x24, 0xe6, 0x48, 0xda, 0x50, 0x4d, 0xf3, 0xc8, 0x2c, 0x5f,
|
||||
0x8a, 0xce, 0x2e, 0xec, 0x9c, 0x8a, 0x80, 0x89, 0x3c, 0x74, 0xe7, 0x3e, 0x58, 0x7d, 0x8c, 0x70,
|
||||
0x9d, 0x8b, 0xb7, 0x8f, 0x3c, 0x81, 0xdd, 0x82, 0x92, 0x9b, 0xbd, 0x07, 0xdb, 0x78, 0x41, 0xc5,
|
||||
0x88, 0x8b, 0x40, 0x64, 0x3c, 0xe7, 0x82, 0x84, 0x4e, 0x15, 0xe2, 0xfc, 0x56, 0x85, 0x6d, 0xef,
|
||||
0x02, 0x27, 0x85, 0xd1, 0xab, 0xb1, 0x1b, 0x65, 0xb1, 0x57, 0xae, 0x8f, 0xbd, 0x5a, 0x12, 0xbb,
|
||||
0x79, 0x35, 0x76, 0xf2, 0x00, 0x2c, 0x8e, 0x11, 0x8d, 0xb3, 0x8b, 0x51, 0x14, 0x8c, 0x51, 0xa7,
|
||||
0xb8, 0xe5, 0xef, 0xe4, 0xe0, 0x73, 0x89, 0x91, 0x8f, 0xc0, 0x94, 0x7d, 0xa0, 0xb2, 0xbc, 0x7d,
|
||||
0x74, 0xd7, 0xdd, 0xec, 0x64, 0xd5, 0x2d, 0xee, 0xf7, 0x1c, 0x99, 0xaf, 0x68, 0x84, 0x80, 0x19,
|
||||
0xb0, 0x29, 0xb7, 0x1b, 0x07, 0xd5, 0xc3, 0x96, 0xaf, 0x64, 0x99, 0x1e, 0x8c, 0x17, 0x76, 0x53,
|
||||
0x41, 0x52, 0x94, 0xc8, 0xe4, 0x3c, 0xb4, 0x5b, 0xea, 0x3e, 0x29, 0x12, 0x07, 0x76, 0x26, 0x41,
|
||||
0x1a, 0x8c, 0x69, 0x44, 0x05, 0x45, 0x6e, 0x83, 0x22, 0x6f, 0x60, 0xe4, 0x73, 0x68, 0xb0, 0x88,
|
||||
0xce, 0xa9, 0xe0, 0xf6, 0xf6, 0x41, 0xf5, 0x70, 0xfb, 0xa8, 0xeb, 0x5e, 0x3f, 0x57, 0xae, 0xaf,
|
||||
0x68, 0x7e, 0x41, 0x27, 0x8f, 0xe1, 0x9d, 0x38, 0x19, 0xc5, 0x78, 0x3e, 0x4a, 0x19, 0x5d, 0xd0,
|
||||
0x08, 0xa7, 0xc8, 0xed, 0x1d, 0x95, 0xd4, 0xbd, 0x38, 0xf9, 0x16, 0xcf, 0x07, 0x2b, 0x98, 0x7c,
|
||||
0x08, 0xed, 0x20, 0x4d, 0x03, 0x36, 0x4f, 0xd8, 0x28, 0x65, 0xc9, 0x19, 0x8d, 0xd0, 0xb6, 0x94,
|
||||
0xa3, 0x7b, 0x05, 0x3e, 0xd0, 0xb0, 0xd3, 0x87, 0xba, 0xbe, 0x49, 0x86, 0x2d, 0x53, 0xa1, 0xe7,
|
||||
0xc1, 0x57, 0xb2, 0xc4, 0x66, 0x01, 0x0b, 0x55, 0x8d, 0x4c, 0x5f, 0xc9, 0x12, 0xe3, 0xc9, 0x99,
|
||||
0x2e, 0x90, 0xe9, 0x2b, 0xd9, 0x39, 0x80, 0x1d, 0x5d, 0xf7, 0xd2, 0x06, 0x7c, 0x0e, 0x30, 0x10,
|
||||
0x97, 0xa5, 0xdd, 0x26, 0xdb, 0xe1, 0x9c, 0x86, 0x62, 0xa6, 0xae, 0xb2, 0x7c, 0xad, 0xc8, 0xb2,
|
||||
0xcf, 0x90, 0x4e, 0x67, 0xfa, 0x36, 0xcb, 0xcf, 0x35, 0x67, 0x0f, 0x2c, 0x6f, 0x81, 0xb1, 0xe0,
|
||||
0x45, 0x3f, 0xff, 0x62, 0x40, 0x4d, 0x21, 0xa5, 0x43, 0xfd, 0x69, 0x1e, 0x9e, 0xb4, 0xbf, 0x7b,
|
||||
0x74, 0xbf, 0x2c, 0xed, 0xca, 0xc8, 0xf0, 0x32, 0xc5, 0x3c, 0x03, 0xb9, 0xa7, 0xd5, 0xb5, 0xa7,
|
||||
0x6f, 0x4c, 0x81, 0xf9, 0xd6, 0x14, 0xe8, 0x59, 0x5b, 0x8d, 0x96, 0xf3, 0xab, 0x01, 0x56, 0x0e,
|
||||
0xe4, 0xe9, 0xf9, 0x1f, 0x8b, 0x87, 0xc6, 0x54, 0x0c, 0x56, 0x8e, 0x14, 0x2a, 0xf9, 0x12, 0x5a,
|
||||
0xf9, 0x76, 0x44, 0xe9, 0x8a, 0xec, 0xa8, 0xf7, 0xae, 0xed, 0xef, 0x81, 0x66, 0xf9, 0x6b, 0xba,
|
||||
0xf4, 0x73, 0x10, 0x64, 0x7c, 0xe5, 0xe7, 0x1e, 0x58, 0x3e, 0xf2, 0x6c, 0x5e, 0x00, 0x8f, 0x3d,
|
||||
0x68, 0xad, 0xd2, 0x41, 0x9a, 0x60, 0x7a, 0x2f, 0x9f, 0x0d, 0xdb, 0x5b, 0xa4, 0x01, 0xd5, 0x17,
|
||||
0x2f, 0xbe, 0x69, 0x1b, 0x04, 0xa0, 0x7e, 0xe2, 0x7b, 0xc7, 0x43, 0xaf, 0x5d, 0x21, 0x2d, 0xa8,
|
||||
0x9d, 0x0e, 0x8f, 0xfd, 0x61, 0xbb, 0x4a, 0x76, 0x01, 0xbc, 0x97, 0xde, 0xc9, 0xe8, 0xb8, 0xdf,
|
||||
0xf7, 0xfa, 0x6d, 0xf3, 0xe8, 0xf7, 0x1a, 0x98, 0xa7, 0x33, 0x3a, 0x27, 0x3f, 0x40, 0x5d, 0x2f,
|
||||
0x2a, 0xf2, 0xa8, 0x2c, 0xfd, 0x1b, 0x0b, 0xba, 0xf3, 0xc1, 0x6d, 0xb4, 0x3c, 0x9f, 0x1e, 0xd4,
|
||||
0xd4, 0x76, 0x23, 0x0f, 0xcb, 0x0e, 0x5c, 0x5d, 0x7e, 0x9d, 0x7d, 0x57, 0xbf, 0x59, 0x6e, 0xf1,
|
||||
0x66, 0xb9, 0x9e, 0x7c, 0xb3, 0xa4, 0x7f, 0x7a, 0xe3, 0x95, 0xfb, 0xb7, 0xb1, 0x34, 0xcb, 0xfd,
|
||||
0x7b, 0x63, 0x71, 0x7e, 0x07, 0xa6, 0x1c, 0x0f, 0xf2, 0xa0, 0xb4, 0xeb, 0xd6, 0x4b, 0xb3, 0xf3,
|
||||
0xf0, 0x66, 0x52, 0x6e, 0xf2, 0x18, 0xaa, 0x03, 0x71, 0x49, 0x9c, 0x32, 0xf2, 0x7a, 0xd8, 0x4a,
|
||||
0xc3, 0x1d, 0x40, 0x5d, 0x0f, 0x51, 0x79, 0xb8, 0x1b, 0x43, 0xd6, 0x79, 0xff, 0x46, 0xda, 0xc7,
|
||||
0x06, 0x19, 0xaa, 0x3a, 0x08, 0xbc, 0xb1, 0x0e, 0xeb, 0xf4, 0x3d, 0xba, 0x85, 0xb5, 0xae, 0xae,
|
||||
0xea, 0xd3, 0x72, 0xab, 0x57, 0xdb, 0xb8, 0x34, 0xdc, 0xaf, 0xa1, 0xae, 0xdb, 0xbb, 0x3c, 0xdc,
|
||||
0x8d, 0xf6, 0x2f, 0x33, 0xf4, 0xd4, 0x7e, 0xf5, 0xba, 0xbb, 0xf5, 0xd7, 0xeb, 0xee, 0xd6, 0xcf,
|
||||
0xcb, 0xae, 0xf1, 0x6a, 0xd9, 0x35, 0xfe, 0x58, 0x76, 0x8d, 0x7f, 0x96, 0x5d, 0x63, 0x5c, 0x57,
|
||||
0xcc, 0x4f, 0xfe, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x7d, 0x28, 0xed, 0x88, 0x67, 0x09, 0x00, 0x00,
|
||||
// 918 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x55, 0xc1, 0x6f, 0xe3, 0xc4,
|
||||
0x17, 0x5e, 0x27, 0xa9, 0x9b, 0xbc, 0xc4, 0xed, 0xfe, 0x46, 0xab, 0x6a, 0x36, 0x3f, 0x94, 0x0d,
|
||||
0xde, 0x5d, 0x54, 0x90, 0x70, 0xd8, 0x72, 0x59, 0x38, 0xc1, 0x6e, 0x2b, 0x84, 0xb4, 0x8b, 0x82,
|
||||
0x0b, 0xe2, 0x18, 0x39, 0xf1, 0x6b, 0x32, 0xc2, 0xf6, 0x98, 0x99, 0x71, 0xda, 0xde, 0x38, 0x23,
|
||||
0x21, 0xfe, 0x15, 0xfe, 0x8c, 0x3d, 0x72, 0xe4, 0x84, 0xd8, 0xfc, 0x25, 0x68, 0x66, 0xec, 0xa4,
|
||||
0x81, 0xb8, 0x85, 0x4b, 0xf4, 0xde, 0x97, 0x6f, 0x66, 0xde, 0x7c, 0xef, 0x9b, 0x67, 0xf8, 0x64,
|
||||
0xce, 0xd4, 0xa2, 0x98, 0x06, 0x33, 0x9e, 0x8e, 0x62, 0x3e, 0xfb, 0x1e, 0xc5, 0x68, 0xc6, 0x33,
|
||||
0x15, 0xb1, 0x0c, 0x45, 0x3c, 0x8a, 0x72, 0x36, 0x92, 0x28, 0x96, 0x6c, 0x86, 0x72, 0x24, 0x17,
|
||||
0x2c, 0x35, 0x3f, 0x41, 0x2e, 0xb8, 0xe2, 0xe4, 0x68, 0x43, 0x0c, 0x96, 0xcf, 0x82, 0x8a, 0xd7,
|
||||
0xff, 0xff, 0x9c, 0xf3, 0x79, 0x82, 0x23, 0xc3, 0x9a, 0x16, 0x17, 0x23, 0x4c, 0x73, 0x75, 0x6d,
|
||||
0x17, 0xf5, 0x1f, 0xcc, 0xf9, 0x9c, 0x9b, 0x70, 0xa4, 0xa3, 0x12, 0x7d, 0x7e, 0x67, 0x15, 0xea,
|
||||
0x3a, 0x47, 0x39, 0x4a, 0x79, 0x91, 0x29, 0xfb, 0x5b, 0xae, 0xfc, 0xec, 0x5f, 0xae, 0x5c, 0x83,
|
||||
0x9b, 0xc8, 0xee, 0xe0, 0xff, 0xd4, 0x00, 0xef, 0xa5, 0xc0, 0x48, 0x61, 0x88, 0x3f, 0x14, 0x28,
|
||||
0x15, 0x39, 0x82, 0x06, 0x8b, 0xa9, 0x33, 0x74, 0x8e, 0x3b, 0x2f, 0xdc, 0xd5, 0x1f, 0x8f, 0x1a,
|
||||
0x5f, 0x9e, 0x86, 0x0d, 0x16, 0x93, 0x23, 0x70, 0xa7, 0x45, 0x16, 0x27, 0x48, 0x1b, 0xfa, 0xbf,
|
||||
0xb0, 0xcc, 0x08, 0x85, 0x7d, 0x51, 0x64, 0x8a, 0xa5, 0x48, 0x9b, 0xe6, 0x8f, 0x2a, 0x25, 0x0f,
|
||||
0xa1, 0x9d, 0xf1, 0x49, 0xce, 0x96, 0x5c, 0xd1, 0xd6, 0xd0, 0x39, 0x6e, 0x87, 0xfb, 0x19, 0x1f,
|
||||
0xeb, 0x94, 0xf4, 0xa1, 0xad, 0x50, 0xa4, 0x2c, 0x8b, 0x12, 0xba, 0x67, 0xfe, 0x5a, 0xe7, 0xe4,
|
||||
0x01, 0xec, 0x49, 0x15, 0xb3, 0x8c, 0xba, 0x66, 0x3b, 0x9b, 0xe8, 0xe3, 0xa5, 0x8a, 0x79, 0xa1,
|
||||
0xe8, 0xbe, 0x3d, 0xde, 0x66, 0x25, 0x8e, 0x42, 0xd0, 0xf6, 0x1a, 0x47, 0x21, 0xc8, 0x09, 0xb8,
|
||||
0x82, 0x73, 0x75, 0x21, 0x69, 0x67, 0xd8, 0x3c, 0xee, 0x9e, 0xf4, 0x83, 0xed, 0x86, 0x19, 0x61,
|
||||
0x82, 0xd7, 0x5a, 0xcc, 0xb0, 0x64, 0xfa, 0x3e, 0x1c, 0x54, 0x5a, 0xc8, 0x9c, 0x67, 0x12, 0xc9,
|
||||
0x7d, 0x68, 0xe6, 0xa5, 0x1a, 0x5e, 0xa8, 0x43, 0xff, 0x00, 0x7a, 0xe7, 0x2a, 0x12, 0xaa, 0x94,
|
||||
0xcb, 0x7f, 0x17, 0xbc, 0x53, 0x4c, 0x70, 0xa3, 0xdf, 0x3f, 0x97, 0x3c, 0x83, 0x83, 0x8a, 0x52,
|
||||
0x6e, 0xfb, 0x08, 0xba, 0x78, 0xc5, 0xd4, 0x44, 0xaa, 0x48, 0x15, 0xb2, 0xe4, 0x82, 0x86, 0xce,
|
||||
0x0d, 0xe2, 0xff, 0xda, 0x84, 0xee, 0xd9, 0x15, 0xce, 0xaa, 0x4d, 0x6f, 0xea, 0xe5, 0xd4, 0xe9,
|
||||
0xd5, 0xd8, 0xad, 0x57, 0xb3, 0x46, 0xaf, 0xd6, 0x96, 0x5e, 0x8f, 0xc1, 0x93, 0x98, 0xb0, 0xac,
|
||||
0xb8, 0x9a, 0x24, 0xd1, 0x14, 0x6d, 0x5b, 0x3a, 0x61, 0xaf, 0x04, 0x5f, 0x69, 0x8c, 0x7c, 0x08,
|
||||
0xad, 0x42, 0xa2, 0x30, 0x9d, 0xe9, 0x9e, 0x3c, 0xdc, 0x29, 0xe9, 0xb7, 0x12, 0x45, 0x68, 0x68,
|
||||
0x84, 0x40, 0x2b, 0x12, 0x73, 0x49, 0xf7, 0x87, 0xcd, 0xe3, 0x4e, 0x68, 0x62, 0x2d, 0x0f, 0x66,
|
||||
0x4b, 0xda, 0x36, 0x90, 0x0e, 0x35, 0x32, 0xbb, 0x8c, 0x69, 0xc7, 0x9c, 0xa7, 0x43, 0xe2, 0x43,
|
||||
0x6f, 0x16, 0xe5, 0xd1, 0x94, 0x25, 0x4c, 0x31, 0x94, 0x14, 0x0c, 0x79, 0x0b, 0x23, 0xcf, 0x61,
|
||||
0x5f, 0x24, 0x2c, 0x65, 0x4a, 0xd2, 0xae, 0x69, 0xf0, 0x20, 0xd8, 0xfd, 0x22, 0x83, 0xd0, 0xd0,
|
||||
0xc2, 0x8a, 0x4e, 0x3e, 0x80, 0xff, 0x65, 0x7c, 0x92, 0xe1, 0xe5, 0x24, 0x17, 0x6c, 0xc9, 0x12,
|
||||
0x9c, 0xa3, 0xa4, 0x3d, 0x23, 0xea, 0x61, 0xc6, 0xbf, 0xc2, 0xcb, 0xf1, 0x1a, 0x26, 0xef, 0xc3,
|
||||
0xfd, 0x28, 0xcf, 0x23, 0x91, 0x72, 0x31, 0xc9, 0x05, 0xbf, 0x60, 0x09, 0x52, 0xcf, 0x14, 0x7a,
|
||||
0x58, 0xe1, 0x63, 0x0b, 0xfb, 0xa7, 0xe0, 0xda, 0x93, 0xf4, 0xb5, 0xb5, 0x14, 0xf6, 0x0d, 0x85,
|
||||
0x26, 0xd6, 0xd8, 0x22, 0x12, 0xb1, 0xe9, 0x51, 0x2b, 0x34, 0xb1, 0xc6, 0x24, 0xbf, 0xb0, 0x0d,
|
||||
0x6a, 0x85, 0x26, 0xf6, 0x87, 0xd0, 0xb3, 0x7d, 0xaf, 0x35, 0xe0, 0x2b, 0x80, 0xb1, 0xba, 0xae,
|
||||
0x75, 0x9b, 0xb6, 0xc3, 0x25, 0x8b, 0xd5, 0xc2, 0x1c, 0xe5, 0x85, 0x36, 0xd1, 0x6d, 0x5f, 0x20,
|
||||
0x9b, 0x2f, 0xec, 0x69, 0x5e, 0x58, 0x66, 0xfe, 0x21, 0x78, 0x67, 0x4b, 0xcc, 0x94, 0xac, 0xfc,
|
||||
0x6c, 0xfd, 0xbd, 0xb6, 0xb3, 0xff, 0xb3, 0x03, 0x5e, 0x09, 0x94, 0x25, 0xfd, 0xd7, 0x01, 0x51,
|
||||
0x96, 0xd8, 0xdc, 0x94, 0xf8, 0x29, 0x74, 0x72, 0xc1, 0x67, 0x28, 0x25, 0x4a, 0xda, 0x32, 0xdd,
|
||||
0x7b, 0x67, 0xa7, 0x97, 0xc6, 0x96, 0x15, 0x6e, 0xe8, 0xba, 0xbe, 0x71, 0x54, 0xc8, 0x75, 0x7d,
|
||||
0x87, 0xe0, 0x85, 0x28, 0x8b, 0x74, 0x0d, 0x78, 0xfa, 0xe5, 0xb0, 0xea, 0x7d, 0x9e, 0xfc, 0xe2,
|
||||
0x42, 0xeb, 0x7c, 0xc1, 0x52, 0xf2, 0x1d, 0xb8, 0xf6, 0x71, 0x93, 0xa7, 0x75, 0x4e, 0xd9, 0x1a,
|
||||
0x84, 0xfd, 0xf7, 0xee, 0xa2, 0x95, 0x7a, 0x9c, 0xc1, 0x9e, 0x99, 0x08, 0xe4, 0x49, 0xdd, 0x82,
|
||||
0x9b, 0x03, 0xa3, 0x7f, 0x14, 0xd8, 0x2f, 0x44, 0x50, 0x7d, 0x21, 0x82, 0x33, 0xfd, 0x85, 0xd0,
|
||||
0xf5, 0xd9, 0x29, 0x51, 0x5f, 0xdf, 0xd6, 0xa0, 0xa9, 0xaf, 0xef, 0x6f, 0xc3, 0xe6, 0x6b, 0x68,
|
||||
0x69, 0x4b, 0x91, 0xc7, 0x75, 0xfc, 0x1b, 0x83, 0xa6, 0xff, 0xe4, 0x76, 0x52, 0xb9, 0xe5, 0xe7,
|
||||
0xd0, 0x1c, 0xab, 0x6b, 0xe2, 0xd7, 0x91, 0x37, 0x06, 0xad, 0xbd, 0xee, 0x6b, 0x70, 0xad, 0xf1,
|
||||
0xea, 0xaf, 0xbb, 0x65, 0xcc, 0xfe, 0xee, 0x01, 0x6e, 0x38, 0x1f, 0x39, 0xe4, 0x1b, 0xd3, 0x04,
|
||||
0x85, 0xb7, 0x36, 0x61, 0xa3, 0xdd, 0xd3, 0x3b, 0x58, 0x9b, 0xd6, 0x1a, 0xb3, 0xd5, 0xef, 0x7a,
|
||||
0xd3, 0x8b, 0xb5, 0x77, 0xfd, 0x02, 0x5c, 0xeb, 0xd1, 0xfa, 0xbb, 0x6e, 0x79, 0xb8, 0x76, 0xa3,
|
||||
0x97, 0xba, 0x95, 0x4c, 0xdd, 0xd6, 0x4a, 0x76, 0x97, 0xd1, 0x5e, 0xd0, 0x37, 0x6f, 0x07, 0xf7,
|
||||
0x7e, 0x7f, 0x3b, 0xb8, 0xf7, 0xe3, 0x6a, 0xe0, 0xbc, 0x59, 0x0d, 0x9c, 0xdf, 0x56, 0x03, 0xe7,
|
||||
0xcf, 0xd5, 0xc0, 0x99, 0xba, 0x86, 0xf9, 0xf1, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb2, 0x82,
|
||||
0x40, 0x80, 0x17, 0x09, 0x00, 0x00,
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ package containerd.v1.services;
|
|||
|
||||
import "google/protobuf/empty.proto";
|
||||
import "gogoproto/gogo.proto";
|
||||
import "github.com/docker/containerd/api/types/process/process.proto";
|
||||
import "github.com/docker/containerd/api/types/user/user.proto";
|
||||
import "github.com/docker/containerd/api/types/mount/mount.proto";
|
||||
import "github.com/docker/containerd/api/types/container/container.proto";
|
||||
|
||||
service Shim {
|
||||
rpc Create(CreateRequest) returns (CreateResponse);
|
||||
|
@ -13,10 +13,11 @@ service Shim {
|
|||
rpc Delete(DeleteRequest) returns (DeleteResponse);
|
||||
rpc Exec(ExecRequest) returns (ExecResponse);
|
||||
rpc Pty(PtyRequest) returns (google.protobuf.Empty);
|
||||
rpc Events(EventsRequest) returns (stream Event);
|
||||
rpc Events(EventsRequest) returns (stream containerd.v1.types.Event);
|
||||
rpc State(StateRequest) returns (StateResponse);
|
||||
rpc Pause(PauseRequest) returns (google.protobuf.Empty);
|
||||
rpc Resume(ResumeRequest) returns (google.protobuf.Empty);
|
||||
rpc Exit(ExitRequest) returns (google.protobuf.Empty);
|
||||
}
|
||||
|
||||
message CreateRequest {
|
||||
|
@ -28,6 +29,7 @@ message CreateRequest {
|
|||
string stdin = 6;
|
||||
string stdout = 7;
|
||||
string stderr = 8;
|
||||
repeated containerd.v1.types.Mount rootfs = 9;
|
||||
}
|
||||
|
||||
message CreateResponse {
|
||||
|
@ -51,7 +53,7 @@ message ExecRequest {
|
|||
string stdout = 3;
|
||||
string stderr = 4;
|
||||
string selinux_label = 5;
|
||||
types.User user = 6;
|
||||
containerd.v1.types.User user = 6;
|
||||
repeated string args = 7;
|
||||
repeated string env = 8;
|
||||
string cwd = 9;
|
||||
|
@ -80,34 +82,22 @@ message PtyRequest {
|
|||
message EventsRequest {
|
||||
}
|
||||
|
||||
enum EventType {
|
||||
EXIT = 0;
|
||||
OOM = 1;
|
||||
CREATE = 2;
|
||||
START = 3;
|
||||
EXEC_ADDED = 4;
|
||||
}
|
||||
|
||||
// should be moved to api/types/event maybe
|
||||
message Event {
|
||||
string id = 1 [(gogoproto.customname) = "ID"];
|
||||
EventType type = 2;
|
||||
uint32 pid = 3;
|
||||
uint32 exit_status = 4;
|
||||
}
|
||||
|
||||
message StateRequest {
|
||||
}
|
||||
|
||||
message StateResponse {
|
||||
string id = 1 [(gogoproto.customname) = "ID"];
|
||||
string bundle = 2;
|
||||
uint32 initPid = 3;
|
||||
repeated types.Process processes = 4;
|
||||
uint32 pid = 3;
|
||||
repeated containerd.v1.types.Process processes = 4;
|
||||
}
|
||||
|
||||
|
||||
message PauseRequest {
|
||||
}
|
||||
|
||||
message ResumeRequest {
|
||||
}
|
||||
|
||||
message ExitRequest {
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -3,10 +3,50 @@ syntax = "proto3";
|
|||
package containerd.v1.types;
|
||||
|
||||
import "gogoproto/gogo.proto";
|
||||
import "github.com/docker/containerd/api/types/state/state.proto";
|
||||
|
||||
enum Status {
|
||||
CREATED = 0;
|
||||
RUNNING = 1;
|
||||
STOPPED = 2;
|
||||
PAUSED = 3;
|
||||
}
|
||||
|
||||
message Container {
|
||||
string id = 1 [(gogoproto.customname) = "ID"];
|
||||
string bundle = 2;
|
||||
State state = 4;
|
||||
uint32 pid = 2;
|
||||
Status status = 3;
|
||||
}
|
||||
|
||||
message Process {
|
||||
uint32 pid = 1;
|
||||
repeated string args = 2;
|
||||
repeated string env = 3;
|
||||
User user = 4;
|
||||
string cwd = 5;
|
||||
bool terminal = 6;
|
||||
uint32 exit_status = 7;
|
||||
Status status = 8;
|
||||
}
|
||||
|
||||
message User {
|
||||
uint32 uid = 1;
|
||||
uint32 gid = 2;
|
||||
repeated uint32 additional_gids = 3;
|
||||
}
|
||||
|
||||
message Event {
|
||||
string id = 1 [(gogoproto.customname) = "ID"];
|
||||
|
||||
enum EventType {
|
||||
EXIT = 0;
|
||||
OOM = 1;
|
||||
CREATE = 2;
|
||||
START = 3;
|
||||
EXEC_ADDED = 4;
|
||||
PAUSED = 5;
|
||||
}
|
||||
|
||||
EventType type = 2;
|
||||
uint32 pid = 3;
|
||||
uint32 exit_status = 4;
|
||||
}
|
||||
|
|
|
@ -472,19 +472,18 @@ func init() {
|
|||
}
|
||||
|
||||
var fileDescriptorMount = []byte{
|
||||
// 212 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x4c, 0x8e, 0xb1, 0x4a, 0x43, 0x31,
|
||||
0x14, 0x86, 0x1b, 0x5b, 0x2b, 0xcd, 0x18, 0x41, 0x82, 0x43, 0x28, 0x4e, 0x5d, 0x4c, 0x10, 0x17,
|
||||
0x67, 0x77, 0x97, 0xbe, 0xc1, 0xbd, 0x69, 0x8c, 0x41, 0x9a, 0x13, 0x72, 0x4f, 0x04, 0x37, 0x1f,
|
||||
0xef, 0x8e, 0x8e, 0x8e, 0xde, 0x3c, 0x89, 0xdc, 0x13, 0xc5, 0x2e, 0x87, 0xff, 0xfb, 0xf9, 0xf9,
|
||||
0x38, 0xfc, 0xc1, 0x07, 0x7c, 0x29, 0xbd, 0xb6, 0x70, 0x34, 0x07, 0xb0, 0xaf, 0x2e, 0x1b, 0x0b,
|
||||
0x11, 0xbb, 0x10, 0x5d, 0x3e, 0x98, 0x2e, 0x05, 0x83, 0xef, 0xc9, 0x0d, 0xe6, 0x08, 0x25, 0x62,
|
||||
0xbb, 0x3a, 0x65, 0x40, 0x10, 0x97, 0xff, 0x3b, 0xfd, 0x76, 0xa7, 0x69, 0x76, 0x7d, 0x7b, 0xa2,
|
||||
0xf3, 0xe0, 0xc1, 0xd0, 0xb6, 0x2f, 0xcf, 0x44, 0x04, 0x94, 0x9a, 0xe3, 0xc6, 0xf1, 0xf3, 0xa7,
|
||||
0x59, 0x29, 0x04, 0x5f, 0xcd, 0x02, 0xc9, 0xb6, 0x6c, 0xb7, 0xd9, 0x53, 0x16, 0x57, 0x7c, 0x3d,
|
||||
0x40, 0xc9, 0xd6, 0xc9, 0x33, 0x6a, 0x7f, 0x69, 0xee, 0xb1, 0xcb, 0xde, 0xa1, 0x5c, 0xb6, 0xbe,
|
||||
0x91, 0x90, 0xfc, 0x02, 0x12, 0x06, 0x88, 0x83, 0x5c, 0x6d, 0x97, 0xbb, 0xcd, 0xfe, 0x0f, 0x1f,
|
||||
0xe5, 0x38, 0xa9, 0xc5, 0xd7, 0xa4, 0x16, 0x1f, 0x55, 0xb1, 0xb1, 0x2a, 0xf6, 0x59, 0x15, 0xfb,
|
||||
0xae, 0x8a, 0xf5, 0x6b, 0xfa, 0xe3, 0xfe, 0x27, 0x00, 0x00, 0xff, 0xff, 0x0f, 0xcf, 0x31, 0x1e,
|
||||
0x07, 0x01, 0x00, 0x00,
|
||||
// 204 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xb2, 0x48, 0xcf, 0x2c, 0xc9,
|
||||
0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xc9, 0x4f, 0xce, 0x4e, 0x2d, 0xd2, 0x4f, 0xce,
|
||||
0xcf, 0x2b, 0x49, 0xcc, 0xcc, 0x4b, 0x2d, 0x4a, 0xd1, 0x4f, 0x2c, 0xc8, 0xd4, 0x2f, 0xa9, 0x2c,
|
||||
0x48, 0x2d, 0xd6, 0xcf, 0xcd, 0x2f, 0xcd, 0x2b, 0x81, 0x90, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9,
|
||||
0x42, 0xc2, 0x08, 0x75, 0x7a, 0x65, 0x86, 0x7a, 0x60, 0x65, 0x52, 0x22, 0xe9, 0xf9, 0xe9, 0xf9,
|
||||
0x60, 0x79, 0x7d, 0x10, 0x0b, 0xa2, 0x54, 0x29, 0x95, 0x8b, 0xd5, 0x17, 0xa4, 0x53, 0x48, 0x88,
|
||||
0x8b, 0x05, 0xa4, 0x4e, 0x82, 0x51, 0x81, 0x51, 0x83, 0x33, 0x08, 0xcc, 0x16, 0x12, 0xe3, 0x62,
|
||||
0x2b, 0xce, 0x2f, 0x2d, 0x4a, 0x4e, 0x95, 0x60, 0x02, 0x8b, 0x42, 0x79, 0x20, 0xf1, 0x92, 0xc4,
|
||||
0xa2, 0xf4, 0xd4, 0x12, 0x09, 0x66, 0x88, 0x38, 0x84, 0x27, 0x24, 0xc1, 0xc5, 0x9e, 0x5f, 0x50,
|
||||
0x92, 0x99, 0x9f, 0x57, 0x2c, 0xc1, 0xa2, 0xc0, 0xac, 0xc1, 0x19, 0x04, 0xe3, 0x3a, 0x49, 0x9c,
|
||||
0x78, 0x28, 0xc7, 0x70, 0xe3, 0xa1, 0x1c, 0x43, 0xc3, 0x23, 0x39, 0xc6, 0x13, 0x8f, 0xe4, 0x18,
|
||||
0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x31, 0x89, 0x0d, 0xec, 0x0e, 0x63, 0x40, 0x00,
|
||||
0x00, 0x00, 0xff, 0xff, 0xf3, 0x5c, 0x4b, 0x3a, 0xee, 0x00, 0x00, 0x00,
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ syntax = "proto3";
|
|||
|
||||
package containerd.v1.types;
|
||||
|
||||
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
||||
import "gogoproto/gogo.proto";
|
||||
|
||||
// Mount describes mounts for a container.
|
||||
//
|
||||
|
|
|
@ -1,625 +0,0 @@
|
|||
// Code generated by protoc-gen-gogo.
|
||||
// source: github.com/docker/containerd/api/types/process/process.proto
|
||||
// DO NOT EDIT!
|
||||
|
||||
/*
|
||||
Package process is a generated protocol buffer package.
|
||||
|
||||
It is generated from these files:
|
||||
github.com/docker/containerd/api/types/process/process.proto
|
||||
|
||||
It has these top-level messages:
|
||||
Process
|
||||
*/
|
||||
package process
|
||||
|
||||
import proto "github.com/gogo/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
import containerd_v1_types "github.com/docker/containerd/api/types/user"
|
||||
import containerd_v1_types1 "github.com/docker/containerd/api/types/state"
|
||||
|
||||
import strings "strings"
|
||||
import reflect "reflect"
|
||||
|
||||
import io "io"
|
||||
|
||||
// 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.GoGoProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
type Process struct {
|
||||
Pid uint32 `protobuf:"varint,1,opt,name=pid,proto3" json:"pid,omitempty"`
|
||||
Args []string `protobuf:"bytes,2,rep,name=args" json:"args,omitempty"`
|
||||
Env []string `protobuf:"bytes,3,rep,name=env" json:"env,omitempty"`
|
||||
User *containerd_v1_types.User `protobuf:"bytes,4,opt,name=user" json:"user,omitempty"`
|
||||
Cwd string `protobuf:"bytes,5,opt,name=cwd,proto3" json:"cwd,omitempty"`
|
||||
Terminal bool `protobuf:"varint,6,opt,name=terminal,proto3" json:"terminal,omitempty"`
|
||||
State containerd_v1_types1.State `protobuf:"varint,7,opt,name=state,proto3,enum=containerd.v1.types.State" json:"state,omitempty"`
|
||||
ExitStatus uint32 `protobuf:"varint,8,opt,name=exit_status,json=exitStatus,proto3" json:"exit_status,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Process) Reset() { *m = Process{} }
|
||||
func (*Process) ProtoMessage() {}
|
||||
func (*Process) Descriptor() ([]byte, []int) { return fileDescriptorProcess, []int{0} }
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Process)(nil), "containerd.v1.types.Process")
|
||||
}
|
||||
func (m *Process) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalTo(dAtA)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *Process) MarshalTo(dAtA []byte) (int, error) {
|
||||
var i int
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if m.Pid != 0 {
|
||||
dAtA[i] = 0x8
|
||||
i++
|
||||
i = encodeVarintProcess(dAtA, i, uint64(m.Pid))
|
||||
}
|
||||
if len(m.Args) > 0 {
|
||||
for _, s := range m.Args {
|
||||
dAtA[i] = 0x12
|
||||
i++
|
||||
l = len(s)
|
||||
for l >= 1<<7 {
|
||||
dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
|
||||
l >>= 7
|
||||
i++
|
||||
}
|
||||
dAtA[i] = uint8(l)
|
||||
i++
|
||||
i += copy(dAtA[i:], s)
|
||||
}
|
||||
}
|
||||
if len(m.Env) > 0 {
|
||||
for _, s := range m.Env {
|
||||
dAtA[i] = 0x1a
|
||||
i++
|
||||
l = len(s)
|
||||
for l >= 1<<7 {
|
||||
dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
|
||||
l >>= 7
|
||||
i++
|
||||
}
|
||||
dAtA[i] = uint8(l)
|
||||
i++
|
||||
i += copy(dAtA[i:], s)
|
||||
}
|
||||
}
|
||||
if m.User != nil {
|
||||
dAtA[i] = 0x22
|
||||
i++
|
||||
i = encodeVarintProcess(dAtA, i, uint64(m.User.Size()))
|
||||
n1, err := m.User.MarshalTo(dAtA[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n1
|
||||
}
|
||||
if len(m.Cwd) > 0 {
|
||||
dAtA[i] = 0x2a
|
||||
i++
|
||||
i = encodeVarintProcess(dAtA, i, uint64(len(m.Cwd)))
|
||||
i += copy(dAtA[i:], m.Cwd)
|
||||
}
|
||||
if m.Terminal {
|
||||
dAtA[i] = 0x30
|
||||
i++
|
||||
if m.Terminal {
|
||||
dAtA[i] = 1
|
||||
} else {
|
||||
dAtA[i] = 0
|
||||
}
|
||||
i++
|
||||
}
|
||||
if m.State != 0 {
|
||||
dAtA[i] = 0x38
|
||||
i++
|
||||
i = encodeVarintProcess(dAtA, i, uint64(m.State))
|
||||
}
|
||||
if m.ExitStatus != 0 {
|
||||
dAtA[i] = 0x40
|
||||
i++
|
||||
i = encodeVarintProcess(dAtA, i, uint64(m.ExitStatus))
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func encodeFixed64Process(dAtA []byte, offset int, v uint64) int {
|
||||
dAtA[offset] = uint8(v)
|
||||
dAtA[offset+1] = uint8(v >> 8)
|
||||
dAtA[offset+2] = uint8(v >> 16)
|
||||
dAtA[offset+3] = uint8(v >> 24)
|
||||
dAtA[offset+4] = uint8(v >> 32)
|
||||
dAtA[offset+5] = uint8(v >> 40)
|
||||
dAtA[offset+6] = uint8(v >> 48)
|
||||
dAtA[offset+7] = uint8(v >> 56)
|
||||
return offset + 8
|
||||
}
|
||||
func encodeFixed32Process(dAtA []byte, offset int, v uint32) int {
|
||||
dAtA[offset] = uint8(v)
|
||||
dAtA[offset+1] = uint8(v >> 8)
|
||||
dAtA[offset+2] = uint8(v >> 16)
|
||||
dAtA[offset+3] = uint8(v >> 24)
|
||||
return offset + 4
|
||||
}
|
||||
func encodeVarintProcess(dAtA []byte, offset int, v uint64) int {
|
||||
for v >= 1<<7 {
|
||||
dAtA[offset] = uint8(v&0x7f | 0x80)
|
||||
v >>= 7
|
||||
offset++
|
||||
}
|
||||
dAtA[offset] = uint8(v)
|
||||
return offset + 1
|
||||
}
|
||||
func (m *Process) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
if m.Pid != 0 {
|
||||
n += 1 + sovProcess(uint64(m.Pid))
|
||||
}
|
||||
if len(m.Args) > 0 {
|
||||
for _, s := range m.Args {
|
||||
l = len(s)
|
||||
n += 1 + l + sovProcess(uint64(l))
|
||||
}
|
||||
}
|
||||
if len(m.Env) > 0 {
|
||||
for _, s := range m.Env {
|
||||
l = len(s)
|
||||
n += 1 + l + sovProcess(uint64(l))
|
||||
}
|
||||
}
|
||||
if m.User != nil {
|
||||
l = m.User.Size()
|
||||
n += 1 + l + sovProcess(uint64(l))
|
||||
}
|
||||
l = len(m.Cwd)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovProcess(uint64(l))
|
||||
}
|
||||
if m.Terminal {
|
||||
n += 2
|
||||
}
|
||||
if m.State != 0 {
|
||||
n += 1 + sovProcess(uint64(m.State))
|
||||
}
|
||||
if m.ExitStatus != 0 {
|
||||
n += 1 + sovProcess(uint64(m.ExitStatus))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func sovProcess(x uint64) (n int) {
|
||||
for {
|
||||
n++
|
||||
x >>= 7
|
||||
if x == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
func sozProcess(x uint64) (n int) {
|
||||
return sovProcess(uint64((x << 1) ^ uint64((int64(x) >> 63))))
|
||||
}
|
||||
func (this *Process) String() string {
|
||||
if this == nil {
|
||||
return "nil"
|
||||
}
|
||||
s := strings.Join([]string{`&Process{`,
|
||||
`Pid:` + fmt.Sprintf("%v", this.Pid) + `,`,
|
||||
`Args:` + fmt.Sprintf("%v", this.Args) + `,`,
|
||||
`Env:` + fmt.Sprintf("%v", this.Env) + `,`,
|
||||
`User:` + strings.Replace(fmt.Sprintf("%v", this.User), "User", "containerd_v1_types.User", 1) + `,`,
|
||||
`Cwd:` + fmt.Sprintf("%v", this.Cwd) + `,`,
|
||||
`Terminal:` + fmt.Sprintf("%v", this.Terminal) + `,`,
|
||||
`State:` + fmt.Sprintf("%v", this.State) + `,`,
|
||||
`ExitStatus:` + fmt.Sprintf("%v", this.ExitStatus) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
}
|
||||
func valueToStringProcess(v interface{}) string {
|
||||
rv := reflect.ValueOf(v)
|
||||
if rv.IsNil() {
|
||||
return "nil"
|
||||
}
|
||||
pv := reflect.Indirect(rv).Interface()
|
||||
return fmt.Sprintf("*%v", pv)
|
||||
}
|
||||
func (m *Process) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowProcess
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: Process: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: Process: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Pid", wireType)
|
||||
}
|
||||
m.Pid = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowProcess
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.Pid |= (uint32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Args", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowProcess
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthProcess
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Args = append(m.Args, string(dAtA[iNdEx:postIndex]))
|
||||
iNdEx = postIndex
|
||||
case 3:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Env", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowProcess
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthProcess
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Env = append(m.Env, string(dAtA[iNdEx:postIndex]))
|
||||
iNdEx = postIndex
|
||||
case 4:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field User", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowProcess
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthProcess
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.User == nil {
|
||||
m.User = &containerd_v1_types.User{}
|
||||
}
|
||||
if err := m.User.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 5:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Cwd", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowProcess
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthProcess
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Cwd = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 6:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Terminal", wireType)
|
||||
}
|
||||
var v int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowProcess
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
v |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.Terminal = bool(v != 0)
|
||||
case 7:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field State", wireType)
|
||||
}
|
||||
m.State = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowProcess
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.State |= (containerd_v1_types1.State(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 8:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ExitStatus", wireType)
|
||||
}
|
||||
m.ExitStatus = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowProcess
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.ExitStatus |= (uint32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipProcess(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthProcess
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func skipProcess(dAtA []byte) (n int, err error) {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowProcess
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
wireType := int(wire & 0x7)
|
||||
switch wireType {
|
||||
case 0:
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowProcess
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx++
|
||||
if dAtA[iNdEx-1] < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 1:
|
||||
iNdEx += 8
|
||||
return iNdEx, nil
|
||||
case 2:
|
||||
var length int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowProcess
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
length |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
iNdEx += length
|
||||
if length < 0 {
|
||||
return 0, ErrInvalidLengthProcess
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 3:
|
||||
for {
|
||||
var innerWire uint64
|
||||
var start int = iNdEx
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowProcess
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
innerWire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
innerWireType := int(innerWire & 0x7)
|
||||
if innerWireType == 4 {
|
||||
break
|
||||
}
|
||||
next, err := skipProcess(dAtA[start:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
iNdEx = start + next
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 4:
|
||||
return iNdEx, nil
|
||||
case 5:
|
||||
iNdEx += 4
|
||||
return iNdEx, nil
|
||||
default:
|
||||
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
||||
}
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
var (
|
||||
ErrInvalidLengthProcess = fmt.Errorf("proto: negative length found during unmarshaling")
|
||||
ErrIntOverflowProcess = fmt.Errorf("proto: integer overflow")
|
||||
)
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("github.com/docker/containerd/api/types/process/process.proto", fileDescriptorProcess)
|
||||
}
|
||||
|
||||
var fileDescriptorProcess = []byte{
|
||||
// 297 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x8c, 0x90, 0xb1, 0x4e, 0xc3, 0x30,
|
||||
0x10, 0x86, 0x7b, 0x34, 0x6d, 0x83, 0x2b, 0x10, 0x32, 0x8b, 0xc9, 0x60, 0x2c, 0xa6, 0x2c, 0x38,
|
||||
0x50, 0x24, 0xc4, 0xc0, 0xc4, 0x13, 0xa0, 0x54, 0xcc, 0x28, 0x75, 0xac, 0x62, 0x41, 0xe3, 0xc8,
|
||||
0x76, 0x5a, 0xd8, 0x78, 0xbc, 0x8e, 0x8c, 0x8c, 0x34, 0x6f, 0xc0, 0x1b, 0x20, 0x3b, 0x52, 0x59,
|
||||
0x3a, 0x74, 0x39, 0xdf, 0xfd, 0xfa, 0xee, 0xd7, 0x7f, 0x46, 0xf7, 0x73, 0xe5, 0x5e, 0x9a, 0x19,
|
||||
0x17, 0x7a, 0x91, 0x95, 0x5a, 0xbc, 0x4a, 0x93, 0x09, 0x5d, 0xb9, 0x42, 0x55, 0xd2, 0x94, 0x59,
|
||||
0x51, 0xab, 0xcc, 0x7d, 0xd4, 0xd2, 0x66, 0xb5, 0xd1, 0x42, 0xda, 0xed, 0xcb, 0x6b, 0xa3, 0x9d,
|
||||
0xc6, 0xa7, 0xff, 0x2c, 0x5f, 0x5e, 0xf3, 0x80, 0x26, 0xb7, 0x7b, 0x5a, 0x36, 0x56, 0x9a, 0x50,
|
||||
0x3a, 0xb3, 0xe4, 0x6e, 0xcf, 0x3d, 0xeb, 0x0a, 0x27, 0xbb, 0xda, 0x6d, 0x5e, 0xfc, 0x02, 0x1a,
|
||||
0x3d, 0x76, 0xc1, 0xf0, 0x09, 0xea, 0xd7, 0xaa, 0x24, 0xc0, 0x20, 0x3d, 0xca, 0x7d, 0x8b, 0x31,
|
||||
0x8a, 0x0a, 0x33, 0xb7, 0xe4, 0x80, 0xf5, 0xd3, 0xc3, 0x3c, 0xf4, 0x9e, 0x92, 0xd5, 0x92, 0xf4,
|
||||
0x83, 0xe4, 0x5b, 0x7c, 0x89, 0x22, 0x9f, 0x85, 0x44, 0x0c, 0xd2, 0xf1, 0xe4, 0x8c, 0xef, 0xb8,
|
||||
0x8c, 0x3f, 0x59, 0x69, 0xf2, 0x80, 0x79, 0x03, 0xb1, 0x2a, 0xc9, 0x80, 0x81, 0x37, 0x10, 0xab,
|
||||
0x12, 0x27, 0x28, 0x76, 0xd2, 0x2c, 0x54, 0x55, 0xbc, 0x91, 0x21, 0x83, 0x34, 0xce, 0xb7, 0x33,
|
||||
0xbe, 0x42, 0x83, 0x90, 0x97, 0x8c, 0x18, 0xa4, 0xc7, 0x93, 0x64, 0xa7, 0xfb, 0xd4, 0x13, 0x79,
|
||||
0x07, 0xe2, 0x73, 0x34, 0x96, 0xef, 0xca, 0x3d, 0xfb, 0xa9, 0xb1, 0x24, 0x0e, 0xe7, 0x20, 0x2f,
|
||||
0x4d, 0x83, 0xf2, 0x40, 0xd6, 0x1b, 0xda, 0xfb, 0xde, 0xd0, 0xde, 0x67, 0x4b, 0x61, 0xdd, 0x52,
|
||||
0xf8, 0x6a, 0x29, 0xfc, 0xb4, 0x14, 0x66, 0xc3, 0xf0, 0x29, 0x37, 0x7f, 0x01, 0x00, 0x00, 0xff,
|
||||
0xff, 0x19, 0xf5, 0x94, 0x44, 0xdb, 0x01, 0x00, 0x00,
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package containerd.v1.types;
|
||||
|
||||
import "github.com/docker/containerd/api/types/user/user.proto";
|
||||
import "github.com/docker/containerd/api/types/state/state.proto";
|
||||
|
||||
message Process {
|
||||
uint32 pid = 1;
|
||||
repeated string args = 2;
|
||||
repeated string env = 3;
|
||||
User user = 4;
|
||||
string cwd = 5;
|
||||
bool terminal = 6;
|
||||
State state = 7; // only used by shim at the moment
|
||||
uint32 exit_status = 8;
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
// Code generated by protoc-gen-gogo.
|
||||
// source: github.com/docker/containerd/api/types/state/state.proto
|
||||
// DO NOT EDIT!
|
||||
|
||||
/*
|
||||
Package state is a generated protocol buffer package.
|
||||
|
||||
It is generated from these files:
|
||||
github.com/docker/containerd/api/types/state/state.proto
|
||||
|
||||
It has these top-level messages:
|
||||
*/
|
||||
package state
|
||||
|
||||
import proto "github.com/gogo/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
|
||||
// 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.GoGoProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
// At the moment we have same State type for Container and Process
|
||||
type State int32
|
||||
|
||||
const (
|
||||
State_UNKNOWN State = 0
|
||||
State_CREATED State = 1
|
||||
State_RUNNING State = 2
|
||||
State_STOPPED State = 3
|
||||
State_PAUSED State = 4
|
||||
)
|
||||
|
||||
var State_name = map[int32]string{
|
||||
0: "UNKNOWN",
|
||||
1: "CREATED",
|
||||
2: "RUNNING",
|
||||
3: "STOPPED",
|
||||
4: "PAUSED",
|
||||
}
|
||||
var State_value = map[string]int32{
|
||||
"UNKNOWN": 0,
|
||||
"CREATED": 1,
|
||||
"RUNNING": 2,
|
||||
"STOPPED": 3,
|
||||
"PAUSED": 4,
|
||||
}
|
||||
|
||||
func (x State) String() string {
|
||||
return proto.EnumName(State_name, int32(x))
|
||||
}
|
||||
func (State) EnumDescriptor() ([]byte, []int) { return fileDescriptorState, []int{0} }
|
||||
|
||||
func init() {
|
||||
proto.RegisterEnum("containerd.v1.types.State", State_name, State_value)
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("github.com/docker/containerd/api/types/state/state.proto", fileDescriptorState)
|
||||
}
|
||||
|
||||
var fileDescriptorState = []byte{
|
||||
// 184 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xb2, 0x48, 0xcf, 0x2c, 0xc9,
|
||||
0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xc9, 0x4f, 0xce, 0x4e, 0x2d, 0xd2, 0x4f, 0xce,
|
||||
0xcf, 0x2b, 0x49, 0xcc, 0xcc, 0x4b, 0x2d, 0x4a, 0xd1, 0x4f, 0x2c, 0xc8, 0xd4, 0x2f, 0xa9, 0x2c,
|
||||
0x48, 0x2d, 0xd6, 0x2f, 0x2e, 0x49, 0x2c, 0x49, 0x85, 0x90, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9,
|
||||
0x42, 0xc2, 0x08, 0x75, 0x7a, 0x65, 0x86, 0x7a, 0x60, 0x65, 0x5a, 0xee, 0x5c, 0xac, 0xc1, 0x20,
|
||||
0x35, 0x42, 0xdc, 0x5c, 0xec, 0xa1, 0x7e, 0xde, 0x7e, 0xfe, 0xe1, 0x7e, 0x02, 0x0c, 0x20, 0x8e,
|
||||
0x73, 0x90, 0xab, 0x63, 0x88, 0xab, 0x8b, 0x00, 0x23, 0x88, 0x13, 0x14, 0xea, 0xe7, 0xe7, 0xe9,
|
||||
0xe7, 0x2e, 0xc0, 0x04, 0xe2, 0x04, 0x87, 0xf8, 0x07, 0x04, 0xb8, 0xba, 0x08, 0x30, 0x0b, 0x71,
|
||||
0x71, 0xb1, 0x05, 0x38, 0x86, 0x06, 0xbb, 0xba, 0x08, 0xb0, 0x38, 0x49, 0x9c, 0x78, 0x28, 0xc7,
|
||||
0x70, 0xe3, 0xa1, 0x1c, 0x43, 0xc3, 0x23, 0x39, 0xc6, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92,
|
||||
0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x31, 0x89, 0x0d, 0x6c, 0xbd, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff,
|
||||
0xcd, 0xc9, 0x58, 0x29, 0xba, 0x00, 0x00, 0x00,
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package containerd.v1.types;
|
||||
|
||||
// At the moment we have same State type for Container and Process
|
||||
enum State {
|
||||
UNKNOWN = 0;
|
||||
CREATED = 1;
|
||||
RUNNING = 2;
|
||||
STOPPED = 3;
|
||||
PAUSED = 4;
|
||||
}
|
|
@ -1,446 +0,0 @@
|
|||
// Code generated by protoc-gen-gogo.
|
||||
// source: github.com/docker/containerd/api/types/user/user.proto
|
||||
// DO NOT EDIT!
|
||||
|
||||
/*
|
||||
Package user is a generated protocol buffer package.
|
||||
|
||||
It is generated from these files:
|
||||
github.com/docker/containerd/api/types/user/user.proto
|
||||
|
||||
It has these top-level messages:
|
||||
User
|
||||
*/
|
||||
package user
|
||||
|
||||
import proto "github.com/gogo/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
|
||||
import strings "strings"
|
||||
import reflect "reflect"
|
||||
|
||||
import io "io"
|
||||
|
||||
// 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.GoGoProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
type User struct {
|
||||
Uid uint32 `protobuf:"varint,1,opt,name=uid,proto3" json:"uid,omitempty"`
|
||||
Gid uint32 `protobuf:"varint,2,opt,name=gid,proto3" json:"gid,omitempty"`
|
||||
AdditionalGids []uint32 `protobuf:"varint,3,rep,packed,name=additional_gids,json=additionalGids" json:"additional_gids,omitempty"`
|
||||
}
|
||||
|
||||
func (m *User) Reset() { *m = User{} }
|
||||
func (*User) ProtoMessage() {}
|
||||
func (*User) Descriptor() ([]byte, []int) { return fileDescriptorUser, []int{0} }
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*User)(nil), "containerd.v1.types.User")
|
||||
}
|
||||
func (m *User) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalTo(dAtA)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *User) MarshalTo(dAtA []byte) (int, error) {
|
||||
var i int
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if m.Uid != 0 {
|
||||
dAtA[i] = 0x8
|
||||
i++
|
||||
i = encodeVarintUser(dAtA, i, uint64(m.Uid))
|
||||
}
|
||||
if m.Gid != 0 {
|
||||
dAtA[i] = 0x10
|
||||
i++
|
||||
i = encodeVarintUser(dAtA, i, uint64(m.Gid))
|
||||
}
|
||||
if len(m.AdditionalGids) > 0 {
|
||||
dAtA2 := make([]byte, len(m.AdditionalGids)*10)
|
||||
var j1 int
|
||||
for _, num := range m.AdditionalGids {
|
||||
for num >= 1<<7 {
|
||||
dAtA2[j1] = uint8(uint64(num)&0x7f | 0x80)
|
||||
num >>= 7
|
||||
j1++
|
||||
}
|
||||
dAtA2[j1] = uint8(num)
|
||||
j1++
|
||||
}
|
||||
dAtA[i] = 0x1a
|
||||
i++
|
||||
i = encodeVarintUser(dAtA, i, uint64(j1))
|
||||
i += copy(dAtA[i:], dAtA2[:j1])
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func encodeFixed64User(dAtA []byte, offset int, v uint64) int {
|
||||
dAtA[offset] = uint8(v)
|
||||
dAtA[offset+1] = uint8(v >> 8)
|
||||
dAtA[offset+2] = uint8(v >> 16)
|
||||
dAtA[offset+3] = uint8(v >> 24)
|
||||
dAtA[offset+4] = uint8(v >> 32)
|
||||
dAtA[offset+5] = uint8(v >> 40)
|
||||
dAtA[offset+6] = uint8(v >> 48)
|
||||
dAtA[offset+7] = uint8(v >> 56)
|
||||
return offset + 8
|
||||
}
|
||||
func encodeFixed32User(dAtA []byte, offset int, v uint32) int {
|
||||
dAtA[offset] = uint8(v)
|
||||
dAtA[offset+1] = uint8(v >> 8)
|
||||
dAtA[offset+2] = uint8(v >> 16)
|
||||
dAtA[offset+3] = uint8(v >> 24)
|
||||
return offset + 4
|
||||
}
|
||||
func encodeVarintUser(dAtA []byte, offset int, v uint64) int {
|
||||
for v >= 1<<7 {
|
||||
dAtA[offset] = uint8(v&0x7f | 0x80)
|
||||
v >>= 7
|
||||
offset++
|
||||
}
|
||||
dAtA[offset] = uint8(v)
|
||||
return offset + 1
|
||||
}
|
||||
func (m *User) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
if m.Uid != 0 {
|
||||
n += 1 + sovUser(uint64(m.Uid))
|
||||
}
|
||||
if m.Gid != 0 {
|
||||
n += 1 + sovUser(uint64(m.Gid))
|
||||
}
|
||||
if len(m.AdditionalGids) > 0 {
|
||||
l = 0
|
||||
for _, e := range m.AdditionalGids {
|
||||
l += sovUser(uint64(e))
|
||||
}
|
||||
n += 1 + sovUser(uint64(l)) + l
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func sovUser(x uint64) (n int) {
|
||||
for {
|
||||
n++
|
||||
x >>= 7
|
||||
if x == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
func sozUser(x uint64) (n int) {
|
||||
return sovUser(uint64((x << 1) ^ uint64((int64(x) >> 63))))
|
||||
}
|
||||
func (this *User) String() string {
|
||||
if this == nil {
|
||||
return "nil"
|
||||
}
|
||||
s := strings.Join([]string{`&User{`,
|
||||
`Uid:` + fmt.Sprintf("%v", this.Uid) + `,`,
|
||||
`Gid:` + fmt.Sprintf("%v", this.Gid) + `,`,
|
||||
`AdditionalGids:` + fmt.Sprintf("%v", this.AdditionalGids) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
}
|
||||
func valueToStringUser(v interface{}) string {
|
||||
rv := reflect.ValueOf(v)
|
||||
if rv.IsNil() {
|
||||
return "nil"
|
||||
}
|
||||
pv := reflect.Indirect(rv).Interface()
|
||||
return fmt.Sprintf("*%v", pv)
|
||||
}
|
||||
func (m *User) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowUser
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: User: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: User: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Uid", wireType)
|
||||
}
|
||||
m.Uid = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowUser
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.Uid |= (uint32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Gid", wireType)
|
||||
}
|
||||
m.Gid = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowUser
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.Gid |= (uint32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 3:
|
||||
if wireType == 2 {
|
||||
var packedLen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowUser
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
packedLen |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if packedLen < 0 {
|
||||
return ErrInvalidLengthUser
|
||||
}
|
||||
postIndex := iNdEx + packedLen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
for iNdEx < postIndex {
|
||||
var v uint32
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowUser
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
v |= (uint32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.AdditionalGids = append(m.AdditionalGids, v)
|
||||
}
|
||||
} else if wireType == 0 {
|
||||
var v uint32
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowUser
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
v |= (uint32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.AdditionalGids = append(m.AdditionalGids, v)
|
||||
} else {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field AdditionalGids", wireType)
|
||||
}
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipUser(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthUser
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func skipUser(dAtA []byte) (n int, err error) {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowUser
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
wireType := int(wire & 0x7)
|
||||
switch wireType {
|
||||
case 0:
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowUser
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx++
|
||||
if dAtA[iNdEx-1] < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 1:
|
||||
iNdEx += 8
|
||||
return iNdEx, nil
|
||||
case 2:
|
||||
var length int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowUser
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
length |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
iNdEx += length
|
||||
if length < 0 {
|
||||
return 0, ErrInvalidLengthUser
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 3:
|
||||
for {
|
||||
var innerWire uint64
|
||||
var start int = iNdEx
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowUser
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
innerWire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
innerWireType := int(innerWire & 0x7)
|
||||
if innerWireType == 4 {
|
||||
break
|
||||
}
|
||||
next, err := skipUser(dAtA[start:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
iNdEx = start + next
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 4:
|
||||
return iNdEx, nil
|
||||
case 5:
|
||||
iNdEx += 4
|
||||
return iNdEx, nil
|
||||
default:
|
||||
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
||||
}
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
var (
|
||||
ErrInvalidLengthUser = fmt.Errorf("proto: negative length found during unmarshaling")
|
||||
ErrIntOverflowUser = fmt.Errorf("proto: integer overflow")
|
||||
)
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("github.com/docker/containerd/api/types/user/user.proto", fileDescriptorUser)
|
||||
}
|
||||
|
||||
var fileDescriptorUser = []byte{
|
||||
// 188 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x32, 0x4b, 0xcf, 0x2c, 0xc9,
|
||||
0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xc9, 0x4f, 0xce, 0x4e, 0x2d, 0xd2, 0x4f, 0xce,
|
||||
0xcf, 0x2b, 0x49, 0xcc, 0xcc, 0x4b, 0x2d, 0x4a, 0xd1, 0x4f, 0x2c, 0xc8, 0xd4, 0x2f, 0xa9, 0x2c,
|
||||
0x48, 0x2d, 0xd6, 0x2f, 0x2d, 0x4e, 0x2d, 0x02, 0x13, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42,
|
||||
0xc2, 0x08, 0x55, 0x7a, 0x65, 0x86, 0x7a, 0x60, 0x45, 0x4a, 0xc1, 0x5c, 0x2c, 0xa1, 0xc5, 0xa9,
|
||||
0x45, 0x42, 0x02, 0x5c, 0xcc, 0xa5, 0x99, 0x29, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0xbc, 0x41, 0x20,
|
||||
0x26, 0x48, 0x24, 0x3d, 0x33, 0x45, 0x82, 0x09, 0x22, 0x92, 0x9e, 0x99, 0x22, 0xa4, 0xce, 0xc5,
|
||||
0x9f, 0x98, 0x92, 0x92, 0x59, 0x92, 0x99, 0x9f, 0x97, 0x98, 0x13, 0x9f, 0x9e, 0x99, 0x52, 0x2c,
|
||||
0xc1, 0xac, 0xc0, 0xac, 0xc1, 0x1b, 0xc4, 0x87, 0x10, 0x76, 0xcf, 0x4c, 0x29, 0x76, 0x92, 0x38,
|
||||
0xf1, 0x50, 0x8e, 0xe1, 0xc6, 0x43, 0x39, 0x86, 0x86, 0x47, 0x72, 0x8c, 0x27, 0x1e, 0xc9, 0x31,
|
||||
0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0x63, 0x12, 0x1b, 0xd8, 0x29, 0xc6, 0x80, 0x00,
|
||||
0x00, 0x00, 0xff, 0xff, 0x39, 0x97, 0xe1, 0xe0, 0xc4, 0x00, 0x00, 0x00,
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package containerd.v1.types;
|
||||
|
||||
message User {
|
||||
uint32 uid = 1;
|
||||
uint32 gid = 2;
|
||||
repeated uint32 additional_gids = 3;
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
package bundle
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const configName = "config.json"
|
||||
|
||||
func New(path string, s *specs.Spec) (*Bundle, error) {
|
||||
if err := os.Mkdir(path, 0700); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b := &Bundle{
|
||||
Path: path,
|
||||
}
|
||||
if err := os.Mkdir(filepath.Join(path, "rootfs"), 0700); err != nil {
|
||||
b.Delete()
|
||||
return nil, err
|
||||
}
|
||||
f, err := os.Create(filepath.Join(path, configName))
|
||||
if err != nil {
|
||||
b.Delete()
|
||||
return nil, err
|
||||
}
|
||||
err = json.NewEncoder(f).Encode(s)
|
||||
f.Close()
|
||||
if err != nil {
|
||||
b.Delete()
|
||||
return nil, err
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func Load(path string) (*Bundle, error) {
|
||||
fi, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to access %q", path)
|
||||
}
|
||||
if !fi.IsDir() {
|
||||
return nil, errors.Errorf("%q is not a directory", path)
|
||||
}
|
||||
|
||||
return &Bundle{
|
||||
Path: path,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type Bundle struct {
|
||||
Path string
|
||||
}
|
||||
|
||||
func (b *Bundle) Config() (*specs.Spec, error) {
|
||||
var s specs.Spec
|
||||
f, err := os.Open(filepath.Join(b.Path, configName))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = json.NewDecoder(f).Decode(&s)
|
||||
f.Close()
|
||||
return &s, err
|
||||
}
|
||||
|
||||
func (b *Bundle) Delete() error {
|
||||
return os.RemoveAll(b.Path)
|
||||
}
|
|
@ -2,6 +2,7 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
|
@ -52,6 +53,9 @@ func main() {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := setupRoot(); err != nil {
|
||||
return err
|
||||
}
|
||||
var (
|
||||
server = grpc.NewServer()
|
||||
sv = shim.New()
|
||||
|
@ -84,7 +88,7 @@ func setupSignals() (chan os.Signal, error) {
|
|||
// serve serves the grpc API over a unix socket at the provided path
|
||||
// this function does not block
|
||||
func serve(server *grpc.Server, path string) error {
|
||||
l, err := utils.CreateUnixSocket(path)
|
||||
l, err := net.FileListener(os.NewFile(3, "socket"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -126,3 +130,8 @@ func handleSignals(signals chan os.Signal, server *grpc.Server, service *shim.Se
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// setupRoot sets up the root as the shim is started in its own mount namespace
|
||||
func setupRoot() error {
|
||||
return syscall.Mount("", "/", "", syscall.MS_SLAVE|syscall.MS_REC, "")
|
||||
}
|
||||
|
|
|
@ -3,16 +3,12 @@ package main
|
|||
import (
|
||||
_ "expvar"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/signal"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
gocontext "golang.org/x/net/context"
|
||||
"google.golang.org/grpc"
|
||||
|
@ -20,17 +16,13 @@ import (
|
|||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/containerd"
|
||||
api "github.com/docker/containerd/api/services/execution"
|
||||
"github.com/docker/containerd/events"
|
||||
_ "github.com/docker/containerd/linux"
|
||||
"github.com/docker/containerd/log"
|
||||
"github.com/docker/containerd/supervisor"
|
||||
"github.com/docker/containerd/services/execution"
|
||||
"github.com/docker/containerd/utils"
|
||||
metrics "github.com/docker/go-metrics"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/urfave/cli"
|
||||
|
||||
natsd "github.com/nats-io/gnatsd/server"
|
||||
"github.com/nats-io/go-nats"
|
||||
stand "github.com/nats-io/nats-streaming-server/server"
|
||||
)
|
||||
|
||||
const usage = `
|
||||
|
@ -43,10 +35,7 @@ const usage = `
|
|||
high performance container runtime
|
||||
`
|
||||
|
||||
const (
|
||||
StanClusterID = "containerd"
|
||||
stanClientID = "containerd"
|
||||
)
|
||||
var global = log.WithModule(gocontext.Background(), "containerd")
|
||||
|
||||
func main() {
|
||||
app := cli.NewApp()
|
||||
|
@ -83,108 +72,36 @@ func main() {
|
|||
Usage: "tcp address to serve metrics on",
|
||||
Value: "127.0.0.1:7897",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "events-address, e",
|
||||
Usage: "nats address to serve events on",
|
||||
Value: nats.DefaultURL,
|
||||
},
|
||||
}
|
||||
app.Before = func(context *cli.Context) error {
|
||||
if context.GlobalBool("debug") {
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
}
|
||||
if logLevel := context.GlobalString("log-level"); logLevel != "" {
|
||||
lvl, err := logrus.ParseLevel(logLevel)
|
||||
if err != nil {
|
||||
lvl = logrus.InfoLevel
|
||||
fmt.Fprintf(os.Stderr, "Unable to parse logging level: %s\n, and being defaulted to info", logLevel)
|
||||
}
|
||||
logrus.SetLevel(lvl)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
app.Before = before
|
||||
app.Action = func(context *cli.Context) error {
|
||||
start := time.Now()
|
||||
// start the signal handler as soon as we can to make sure that
|
||||
// we don't miss any signals during boot
|
||||
signals := make(chan os.Signal, 2048)
|
||||
signal.Notify(signals, syscall.SIGTERM, syscall.SIGINT, syscall.SIGUSR1)
|
||||
|
||||
ctx := log.WithModule(gocontext.Background(), "containerd")
|
||||
if address := context.GlobalString("metrics-address"); address != "" {
|
||||
log.G(ctx).WithField("metrics-address", address).Info("listening and serving metrics")
|
||||
go serveMetrics(ctx, address)
|
||||
}
|
||||
|
||||
ea := context.GlobalString("events-address")
|
||||
log.G(ctx).WithField("events-address", ea).Info("starting nats-streaming-server")
|
||||
s, err := startNATSServer(ea)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
defer s.Shutdown()
|
||||
|
||||
debugPath := context.GlobalString("debug-socket")
|
||||
if debugPath == "" {
|
||||
return errors.New("--debug-socket path cannot be empty")
|
||||
}
|
||||
d, err := utils.CreateUnixSocket(debugPath)
|
||||
log.G(global).Info("starting containerd boot...")
|
||||
runtimes, err := loadRuntimes(context)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//publish profiling and debug socket.
|
||||
log.G(ctx).WithField("socket", debugPath).Info("starting profiler handlers")
|
||||
log.G(ctx).WithFields(logrus.Fields{"expvars": "/debug/vars", "socket": debugPath}).Debug("serving expvars requests")
|
||||
log.G(ctx).WithFields(logrus.Fields{"pprof": "/debug/pprof", "socket": debugPath}).Debug("serving pprof requests")
|
||||
go serveProfiler(ctx, d)
|
||||
|
||||
path := context.GlobalString("socket")
|
||||
if path == "" {
|
||||
return errors.New("--socket path cannot be empty")
|
||||
}
|
||||
l, err := utils.CreateUnixSocket(path)
|
||||
supervisor, err := containerd.NewSupervisor(log.WithModule(global, "execution"), runtimes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get events publisher
|
||||
natsPoster, err := events.NewNATSPoster(StanClusterID, stanClientID)
|
||||
if err != nil {
|
||||
// start debug and metrics APIs
|
||||
if err := serveDebugAPI(context); err != nil {
|
||||
return err
|
||||
}
|
||||
execCtx := log.WithModule(ctx, "execution")
|
||||
execCtx = events.WithPoster(execCtx, natsPoster)
|
||||
execService, err := supervisor.New(execCtx, context.GlobalString("root"))
|
||||
if err != nil {
|
||||
serveMetricsAPI(context)
|
||||
// start the GRPC api with the execution service registered
|
||||
server := newGRPCServer(execution.New(supervisor))
|
||||
if err := serveGRPC(context, server); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Intercept the GRPC call in order to populate the correct module path
|
||||
interceptor := func(ctx gocontext.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||
ctx = log.WithModule(ctx, "containerd")
|
||||
switch info.Server.(type) {
|
||||
case api.ExecutionServiceServer:
|
||||
ctx = log.WithModule(ctx, "execution")
|
||||
ctx = events.WithPoster(ctx, natsPoster)
|
||||
default:
|
||||
fmt.Printf("Unknown type: %#v\n", info.Server)
|
||||
}
|
||||
return handler(ctx, req)
|
||||
}
|
||||
server := grpc.NewServer(grpc.UnaryInterceptor(interceptor))
|
||||
api.RegisterExecutionServiceServer(server, execService)
|
||||
log.G(ctx).WithField("socket", l.Addr()).Info("start serving GRPC API")
|
||||
go serveGRPC(ctx, server, l)
|
||||
|
||||
for s := range signals {
|
||||
switch s {
|
||||
case syscall.SIGUSR1:
|
||||
dumpStacks(ctx)
|
||||
default:
|
||||
log.G(ctx).WithField("signal", s).Info("stopping GRPC server")
|
||||
server.Stop()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return nil
|
||||
log.G(global).Infof("containerd successfully booted in %fs", time.Now().Sub(start).Seconds())
|
||||
return handleSignals(signals, server)
|
||||
}
|
||||
if err := app.Run(os.Args); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "containerd: %s\n", err)
|
||||
|
@ -192,81 +109,123 @@ func main() {
|
|||
}
|
||||
}
|
||||
|
||||
func serveMetrics(ctx gocontext.Context, address string) {
|
||||
func before(context *cli.Context) error {
|
||||
if context.GlobalBool("debug") {
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
}
|
||||
if l := context.GlobalString("log-level"); l != "" {
|
||||
lvl, err := logrus.ParseLevel(l)
|
||||
if err != nil {
|
||||
lvl = logrus.InfoLevel
|
||||
fmt.Fprintf(os.Stderr, "Unable to parse logging level: %s\n, and being defaulted to info", l)
|
||||
}
|
||||
logrus.SetLevel(lvl)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func serveMetricsAPI(context *cli.Context) {
|
||||
if addr := context.GlobalString("metrics-address"); addr != "" {
|
||||
log.G(global).WithField("metrics", addr).Info("starting metrics API...")
|
||||
h := newMetricsHandler()
|
||||
go func() {
|
||||
if err := http.ListenAndServe(addr, h); err != nil {
|
||||
log.G(global).WithError(err).Fatal("serve metrics API")
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
func newMetricsHandler() http.Handler {
|
||||
m := http.NewServeMux()
|
||||
m.Handle("/metrics", metrics.Handler())
|
||||
if err := http.ListenAndServe(address, m); err != nil {
|
||||
log.G(ctx).WithError(err).Fatal("metrics server failure")
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func serveGRPC(ctx gocontext.Context, server *grpc.Server, l net.Listener) {
|
||||
defer l.Close()
|
||||
if err := server.Serve(l); err != nil {
|
||||
log.G(ctx).WithError(err).Fatal("GRPC server failure")
|
||||
func serveDebugAPI(context *cli.Context) error {
|
||||
path := context.GlobalString("debug-socket")
|
||||
if path == "" {
|
||||
return errors.New("--debug-socket path cannot be empty")
|
||||
}
|
||||
}
|
||||
|
||||
func serveProfiler(ctx gocontext.Context, l net.Listener) {
|
||||
defer l.Close()
|
||||
if err := http.Serve(l, nil); err != nil {
|
||||
log.G(ctx).WithError(err).Fatal("profiler server failure")
|
||||
l, err := utils.CreateUnixSocket(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// DumpStacks dumps the runtime stack.
|
||||
func dumpStacks(ctx gocontext.Context) {
|
||||
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]
|
||||
log.G(ctx).Infof("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===", buf)
|
||||
}
|
||||
|
||||
func startNATSServer(address string) (s *stand.StanServer, err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
s = nil
|
||||
if _, ok := r.(error); !ok {
|
||||
err = fmt.Errorf("failed to start NATS server: %v", r)
|
||||
} else {
|
||||
err = r.(error)
|
||||
}
|
||||
log.G(global).WithField("debug", path).Info("starting debug API...")
|
||||
go func() {
|
||||
defer l.Close()
|
||||
// pprof and expvars are imported and automatically register their endpoints
|
||||
// under /debug
|
||||
if err := http.Serve(l, nil); err != nil {
|
||||
log.G(global).WithError(err).Fatal("serve debug API")
|
||||
}
|
||||
}()
|
||||
so, no, err := getServerOptions(address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s = stand.RunServerWithOpts(so, no)
|
||||
|
||||
return s, err
|
||||
return nil
|
||||
}
|
||||
|
||||
func getServerOptions(address string) (*stand.Options, *natsd.Options, error) {
|
||||
url, err := url.Parse(address)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrapf(err, "failed to parse address url %q", address)
|
||||
func loadRuntimes(context *cli.Context) (map[string]containerd.Runtime, error) {
|
||||
var (
|
||||
root = context.GlobalString("root")
|
||||
o = make(map[string]containerd.Runtime)
|
||||
)
|
||||
for _, name := range containerd.Runtimes() {
|
||||
r, err := containerd.NewRuntime(name, root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
o[name] = r
|
||||
log.G(global).WithField("runtime", name).Info("load runtime")
|
||||
}
|
||||
|
||||
no := stand.DefaultNatsServerOptions
|
||||
parts := strings.Split(url.Host, ":")
|
||||
if len(parts) == 2 {
|
||||
no.Port, err = strconv.Atoi(parts[1])
|
||||
} else {
|
||||
no.Port = nats.DefaultPort
|
||||
}
|
||||
no.Host = parts[0]
|
||||
|
||||
so := stand.GetDefaultOptions()
|
||||
so.ID = StanClusterID
|
||||
|
||||
return so, &no, nil
|
||||
return o, nil
|
||||
}
|
||||
|
||||
func newGRPCServer(service api.ContainerServiceServer) *grpc.Server {
|
||||
s := grpc.NewServer(grpc.UnaryInterceptor(interceptor))
|
||||
api.RegisterContainerServiceServer(s, service)
|
||||
return s
|
||||
}
|
||||
|
||||
func serveGRPC(context *cli.Context, server *grpc.Server) error {
|
||||
path := context.GlobalString("socket")
|
||||
if path == "" {
|
||||
return errors.New("--socket path cannot be empty")
|
||||
}
|
||||
l, err := utils.CreateUnixSocket(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go func() {
|
||||
defer l.Close()
|
||||
if err := server.Serve(l); err != nil {
|
||||
log.G(global).WithError(err).Fatal("serve GRPC")
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
||||
func interceptor(ctx gocontext.Context,
|
||||
req interface{},
|
||||
info *grpc.UnaryServerInfo,
|
||||
handler grpc.UnaryHandler,
|
||||
) (interface{}, error) {
|
||||
ctx = log.WithModule(ctx, "containerd")
|
||||
switch info.Server.(type) {
|
||||
case api.ContainerServiceServer:
|
||||
ctx = log.WithModule(global, "execution")
|
||||
default:
|
||||
fmt.Printf("unknown GRPC server type: %#v\n", info.Server)
|
||||
}
|
||||
return handler(global, req)
|
||||
}
|
||||
|
||||
func handleSignals(signals chan os.Signal, server *grpc.Server) error {
|
||||
for s := range signals {
|
||||
log.G(global).WithField("signal", s).Debug("received signal")
|
||||
switch s {
|
||||
default:
|
||||
server.Stop()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -10,43 +10,20 @@ import (
|
|||
|
||||
var deleteCommand = cli.Command{
|
||||
Name: "delete",
|
||||
Usage: "delete a process from containerd store",
|
||||
Usage: "delete an existing container",
|
||||
ArgsUsage: "CONTAINER",
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "pid, p",
|
||||
Usage: "process id to be deleted",
|
||||
},
|
||||
},
|
||||
Action: func(context *cli.Context) error {
|
||||
executionService, err := getExecutionService(context)
|
||||
containers, err := getExecutionService(context)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
id := context.Args().First()
|
||||
if id == "" {
|
||||
return errors.New("container id must be provided")
|
||||
return errors.New(" id must be provided")
|
||||
}
|
||||
|
||||
pid := uint32(context.Int64("pid"))
|
||||
if pid != 0 {
|
||||
_, err = executionService.DeleteProcess(gocontext.Background(), &execution.DeleteProcessRequest{
|
||||
ContainerID: id,
|
||||
Pid: pid,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if _, err := executionService.DeleteContainer(gocontext.Background(), &execution.DeleteContainerRequest{
|
||||
_, err = containers.Delete(gocontext.Background(), &execution.DeleteRequest{
|
||||
ID: id,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,61 +1,47 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
gocontext "context"
|
||||
"fmt"
|
||||
"os"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/nats-io/go-nats"
|
||||
"github.com/docker/containerd/api/services/execution"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var eventsCommand = cli.Command{
|
||||
Name: "events",
|
||||
Usage: "display containerd events",
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "subject, s",
|
||||
Usage: "subjects filter",
|
||||
Value: "containerd.>",
|
||||
},
|
||||
},
|
||||
Action: func(context *cli.Context) error {
|
||||
nc, err := nats.Connect(nats.DefaultURL)
|
||||
containers, err := getExecutionService(context)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nec, err := nats.NewEncodedConn(nc, nats.JSON_ENCODER)
|
||||
if err != nil {
|
||||
nc.Close()
|
||||
return err
|
||||
}
|
||||
defer nec.Close()
|
||||
|
||||
evCh := make(chan *nats.Msg, 64)
|
||||
sub, err := nec.Subscribe(context.String("subject"), func(e *nats.Msg) {
|
||||
evCh <- e
|
||||
})
|
||||
events, err := containers.Events(gocontext.Background(), &execution.EventsRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer sub.Unsubscribe()
|
||||
|
||||
w := tabwriter.NewWriter(os.Stdout, 10, 1, 3, ' ', 0)
|
||||
fmt.Fprintln(w, "TYPE\tID\tPID\tEXIT_STATUS")
|
||||
for {
|
||||
e, more := <-evCh
|
||||
if !more {
|
||||
break
|
||||
}
|
||||
|
||||
var prettyJSON bytes.Buffer
|
||||
|
||||
err := json.Indent(&prettyJSON, e.Data, "", "\t")
|
||||
e, err := events.Recv()
|
||||
if err != nil {
|
||||
fmt.Println(string(e.Data))
|
||||
} else {
|
||||
fmt.Println(prettyJSON.String())
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprintf(w,
|
||||
"%s\t%s\t%d\t%d\n",
|
||||
e.Type.String(),
|
||||
e.ID,
|
||||
e.Pid,
|
||||
e.ExitStatus,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.Flush(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
gocontext "context"
|
||||
|
||||
"github.com/docker/containerd/api/services/execution"
|
||||
"github.com/docker/containerd/api/types/process"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var execCommand = cli.Command{
|
||||
Name: "exec",
|
||||
Usage: "exec a new process in a running container",
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "id, i",
|
||||
Usage: "target container id",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "cwd, c",
|
||||
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",
|
||||
},
|
||||
},
|
||||
Action: func(context *cli.Context) error {
|
||||
executionService, err := getExecutionService(context)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tmpDir, err := getTempDir(time.Now().Format("2006-02-01_15:04:05"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
id := context.String("id")
|
||||
sOpts := &execution.StartProcessRequest{
|
||||
ContainerID: id,
|
||||
Process: &process.Process{
|
||||
Cwd: context.String("cwd"),
|
||||
Terminal: context.Bool("tty"),
|
||||
Args: context.Args(),
|
||||
Env: context.StringSlice("env"),
|
||||
},
|
||||
Stdin: filepath.Join(tmpDir, "stdin"),
|
||||
Stdout: filepath.Join(tmpDir, "stdout"),
|
||||
Stderr: filepath.Join(tmpDir, "stderr"),
|
||||
Console: context.Bool("tty"),
|
||||
}
|
||||
|
||||
fwg, err := prepareStdio(sOpts.Stdin, sOpts.Stdout, sOpts.Stderr, sOpts.Console)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sr, err := executionService.StartProcess(gocontext.Background(), sOpts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = executionService.DeleteProcess(gocontext.Background(), &execution.DeleteProcessRequest{
|
||||
ContainerID: id,
|
||||
Pid: sr.Process.Pid,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Ensure we read all io
|
||||
fwg.Wait()
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
gocontext "context"
|
||||
"errors"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/docker/containerd/api/services/execution"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var inspectCommand = cli.Command{
|
||||
Name: "inspect",
|
||||
Usage: "inspect a container",
|
||||
ArgsUsage: "CONTAINER",
|
||||
Action: func(context *cli.Context) error {
|
||||
executionService, err := getExecutionService(context)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
id := context.Args().First()
|
||||
if id == "" {
|
||||
return errors.New("container id must be provided")
|
||||
}
|
||||
getResponse, err := executionService.GetContainer(gocontext.Background(),
|
||||
&execution.GetContainerRequest{ID: id})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
listProcResponse, err := executionService.ListProcesses(gocontext.Background(),
|
||||
&execution.ListProcessesRequest{ContainerID: id})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dumper := spew.NewDefaultConfig()
|
||||
dumper.Indent = "\t"
|
||||
dumper.DisableMethods = true
|
||||
dumper.DisablePointerAddresses = true
|
||||
dumper.Dump(getResponse, listProcResponse)
|
||||
return nil
|
||||
},
|
||||
}
|
|
@ -3,6 +3,8 @@ package main
|
|||
import (
|
||||
gocontext "context"
|
||||
"fmt"
|
||||
"os"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/docker/containerd/api/services/execution"
|
||||
"github.com/urfave/cli"
|
||||
|
@ -12,29 +14,27 @@ var listCommand = cli.Command{
|
|||
Name: "list",
|
||||
Usage: "list containers",
|
||||
Action: func(context *cli.Context) error {
|
||||
executionService, err := getExecutionService(context)
|
||||
containers, err := getExecutionService(context)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
listResponse, err := executionService.ListContainers(gocontext.Background(), &execution.ListContainersRequest{
|
||||
Owner: []string{},
|
||||
})
|
||||
response, err := containers.List(gocontext.Background(), &execution.ListRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("ID\tSTATUS\tPROCS\tBUNDLE")
|
||||
for _, c := range listResponse.Containers {
|
||||
listProcResponse, err := executionService.ListProcesses(gocontext.Background(),
|
||||
&execution.ListProcessesRequest{ContainerID: c.ID})
|
||||
if err != nil {
|
||||
w := tabwriter.NewWriter(os.Stdout, 10, 1, 3, ' ', 0)
|
||||
fmt.Fprintln(w, "ID\tPID\tSTATUS")
|
||||
for _, c := range response.Containers {
|
||||
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\n",
|
||||
c.ID,
|
||||
c.Pid,
|
||||
c.Status.String(),
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.Flush(); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("%s\t%s\t%d\t%s\n",
|
||||
c.ID,
|
||||
c.State,
|
||||
len(listProcResponse.Processes),
|
||||
c.Bundle,
|
||||
)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
|
|
|
@ -35,11 +35,9 @@ containerd client
|
|||
}
|
||||
app.Commands = []cli.Command{
|
||||
runCommand,
|
||||
execCommand,
|
||||
eventsCommand,
|
||||
deleteCommand,
|
||||
listCommand,
|
||||
inspectCommand,
|
||||
shimCommand,
|
||||
pprofCommand,
|
||||
}
|
||||
|
|
262
cmd/ctr/run.go
262
cmd/ctr/run.go
|
@ -3,148 +3,232 @@ package main
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
gocontext "context"
|
||||
|
||||
"runtime"
|
||||
|
||||
"github.com/crosbymichael/console"
|
||||
"github.com/docker/containerd/api/services/execution"
|
||||
execEvents "github.com/docker/containerd/execution"
|
||||
"github.com/nats-io/go-nats"
|
||||
"github.com/nats-io/go-nats-streaming"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/docker/containerd/api/types/mount"
|
||||
protobuf "github.com/gogo/protobuf/types"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var rwm = "rwm"
|
||||
|
||||
func spec(id string, args []string, tty bool) *specs.Spec {
|
||||
return &specs.Spec{
|
||||
Version: specs.Version,
|
||||
Platform: specs.Platform{
|
||||
OS: runtime.GOOS,
|
||||
Arch: runtime.GOARCH,
|
||||
},
|
||||
Root: specs.Root{
|
||||
Path: "rootfs",
|
||||
Readonly: true,
|
||||
},
|
||||
Process: specs.Process{
|
||||
Args: args,
|
||||
Env: []string{
|
||||
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
},
|
||||
Terminal: tty,
|
||||
Cwd: "/",
|
||||
NoNewPrivileges: true,
|
||||
},
|
||||
Mounts: []specs.Mount{
|
||||
{
|
||||
Destination: "/proc",
|
||||
Type: "proc",
|
||||
Source: "proc",
|
||||
},
|
||||
{
|
||||
Destination: "/dev",
|
||||
Type: "tmpfs",
|
||||
Source: "tmpfs",
|
||||
Options: []string{"nosuid", "strictatime", "mode=755", "size=65536k"},
|
||||
},
|
||||
{
|
||||
Destination: "/dev/pts",
|
||||
Type: "devpts",
|
||||
Source: "devpts",
|
||||
Options: []string{"nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620", "gid=5"},
|
||||
},
|
||||
{
|
||||
Destination: "/dev/shm",
|
||||
Type: "tmpfs",
|
||||
Source: "shm",
|
||||
Options: []string{"nosuid", "noexec", "nodev", "mode=1777", "size=65536k"},
|
||||
},
|
||||
{
|
||||
Destination: "/dev/mqueue",
|
||||
Type: "mqueue",
|
||||
Source: "mqueue",
|
||||
Options: []string{"nosuid", "noexec", "nodev"},
|
||||
},
|
||||
{
|
||||
Destination: "/sys",
|
||||
Type: "sysfs",
|
||||
Source: "sysfs",
|
||||
Options: []string{"nosuid", "noexec", "nodev"},
|
||||
},
|
||||
{
|
||||
Destination: "/run",
|
||||
Type: "tmpfs",
|
||||
Source: "tmpfs",
|
||||
Options: []string{"nosuid", "strictatime", "mode=755", "size=65536k"},
|
||||
},
|
||||
{
|
||||
Destination: "/etc/resolv.conf",
|
||||
Type: "bind",
|
||||
Source: "/etc/resolv.conf",
|
||||
Options: []string{"rbind", "ro"},
|
||||
},
|
||||
{
|
||||
Destination: "/etc/hosts",
|
||||
Type: "bind",
|
||||
Source: "/etc/hosts",
|
||||
Options: []string{"rbind", "ro"},
|
||||
},
|
||||
{
|
||||
Destination: "/etc/localtime",
|
||||
Type: "bind",
|
||||
Source: "/etc/localtime",
|
||||
Options: []string{"rbind", "ro"},
|
||||
},
|
||||
},
|
||||
Hostname: id,
|
||||
Linux: &specs.Linux{
|
||||
Resources: &specs.LinuxResources{
|
||||
Devices: []specs.LinuxDeviceCgroup{
|
||||
{
|
||||
Allow: false,
|
||||
Access: &rwm,
|
||||
},
|
||||
},
|
||||
},
|
||||
Namespaces: []specs.LinuxNamespace{
|
||||
{
|
||||
Type: "pid",
|
||||
},
|
||||
{
|
||||
Type: "ipc",
|
||||
},
|
||||
{
|
||||
Type: "uts",
|
||||
},
|
||||
{
|
||||
Type: "mount",
|
||||
},
|
||||
{
|
||||
Type: "network",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
var runCommand = cli.Command{
|
||||
Name: "run",
|
||||
Usage: "run a container",
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "bundle, b",
|
||||
Usage: "path to the container's bundle",
|
||||
Name: "id",
|
||||
Usage: "id of the container",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "tty, t",
|
||||
Name: "tty,t",
|
||||
Usage: "allocate a TTY for the container",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "rootfs,r",
|
||||
Usage: "path to the container's root filesystem",
|
||||
},
|
||||
},
|
||||
Action: func(context *cli.Context) error {
|
||||
id := context.Args().First()
|
||||
id := context.String("id")
|
||||
if id == "" {
|
||||
return fmt.Errorf("container id must be provided")
|
||||
}
|
||||
executionService, err := getExecutionService(context)
|
||||
|
||||
containers, err := getExecutionService(context)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// setup our event subscriber
|
||||
sc, err := stan.Connect("containerd", "ctr", stan.ConnectWait(5*time.Second))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer sc.Close()
|
||||
|
||||
evCh := make(chan *execEvents.ContainerEvent, 64)
|
||||
sub, err := sc.Subscribe(fmt.Sprintf("containers.%s", id), func(m *stan.Msg) {
|
||||
var e execEvents.ContainerEvent
|
||||
|
||||
err := json.Unmarshal(m.Data, &e)
|
||||
if err != nil {
|
||||
fmt.Printf("failed to unmarshal event: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
evCh <- &e
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer sub.Unsubscribe()
|
||||
|
||||
tmpDir, err := getTempDir(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
bundle, err := filepath.Abs(context.String("bundle"))
|
||||
events, err := containers.Events(gocontext.Background(), &execution.EventsRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
crOpts := &execution.CreateContainerRequest{
|
||||
ID: id,
|
||||
BundlePath: bundle,
|
||||
Console: context.Bool("tty"),
|
||||
Stdin: filepath.Join(tmpDir, "stdin"),
|
||||
Stdout: filepath.Join(tmpDir, "stdout"),
|
||||
Stderr: filepath.Join(tmpDir, "stderr"),
|
||||
// for ctr right now just do a bind mount
|
||||
rootfs := []*mount.Mount{
|
||||
{
|
||||
Type: "bind",
|
||||
Source: context.String("rootfs"),
|
||||
Options: []string{
|
||||
"rw",
|
||||
"rbind",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if crOpts.Console {
|
||||
s := spec(id, []string(context.Args()), context.Bool("tty"))
|
||||
data, err := json.Marshal(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
create := &execution.CreateRequest{
|
||||
ID: id,
|
||||
Spec: &protobuf.Any{
|
||||
TypeUrl: specs.Version,
|
||||
Value: data,
|
||||
},
|
||||
Rootfs: rootfs,
|
||||
Runtime: "linux",
|
||||
Terminal: context.Bool("tty"),
|
||||
Stdin: filepath.Join(tmpDir, "stdin"),
|
||||
Stdout: filepath.Join(tmpDir, "stdout"),
|
||||
Stderr: filepath.Join(tmpDir, "stderr"),
|
||||
}
|
||||
if create.Terminal {
|
||||
con := console.Current()
|
||||
defer con.Reset()
|
||||
if err := con.SetRaw(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
fwg, err := prepareStdio(crOpts.Stdin, crOpts.Stdout, crOpts.Stderr, crOpts.Console)
|
||||
fwg, err := prepareStdio(create.Stdin, create.Stdout, create.Stderr, create.Terminal)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cr, err := executionService.CreateContainer(gocontext.Background(), crOpts)
|
||||
response, err := containers.Create(gocontext.Background(), create)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "CreateContainer RPC failed")
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := executionService.StartContainer(gocontext.Background(), &execution.StartContainerRequest{
|
||||
ID: cr.Container.ID,
|
||||
if _, err := containers.Start(gocontext.Background(), &execution.StartRequest{
|
||||
ID: response.ID,
|
||||
}); err != nil {
|
||||
return errors.Wrap(err, "StartContainer RPC failed")
|
||||
return err
|
||||
}
|
||||
|
||||
var ec uint32
|
||||
eventLoop:
|
||||
for {
|
||||
select {
|
||||
case e, more := <-evCh:
|
||||
if !more {
|
||||
break eventLoop
|
||||
}
|
||||
|
||||
if e.Type != "exit" {
|
||||
continue
|
||||
}
|
||||
|
||||
if e.ID == cr.Container.ID && e.Pid == cr.InitProcess.Pid {
|
||||
ec = e.ExitStatus
|
||||
break eventLoop
|
||||
}
|
||||
case <-time.After(1 * time.Second):
|
||||
if sc.NatsConn().Status() != nats.CONNECTED {
|
||||
break eventLoop
|
||||
}
|
||||
}
|
||||
status, err := waitContainer(events, response)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := executionService.DeleteContainer(gocontext.Background(), &execution.DeleteContainerRequest{
|
||||
ID: cr.Container.ID,
|
||||
if _, err := containers.Delete(gocontext.Background(), &execution.DeleteRequest{
|
||||
ID: response.ID,
|
||||
}); err != nil {
|
||||
return errors.Wrap(err, "DeleteContainer RPC failed")
|
||||
return err
|
||||
}
|
||||
|
||||
// Ensure we read all io
|
||||
fwg.Wait()
|
||||
|
||||
if ec != 0 {
|
||||
return cli.NewExitError("", int(ec))
|
||||
if status != 0 {
|
||||
return cli.NewExitError("", int(status))
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
gocontext "context"
|
||||
|
||||
"github.com/docker/containerd/api/services/execution"
|
||||
"github.com/docker/containerd/api/types/container"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/tonistiigi/fifo"
|
||||
"github.com/urfave/cli"
|
||||
|
@ -103,12 +104,12 @@ func getGRPCConnection(context *cli.Context) (*grpc.ClientConn, error) {
|
|||
return grpcConn, nil
|
||||
}
|
||||
|
||||
func getExecutionService(context *cli.Context) (execution.ExecutionServiceClient, error) {
|
||||
func getExecutionService(context *cli.Context) (execution.ContainerServiceClient, error) {
|
||||
conn, err := getGRPCConnection(context)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return execution.NewExecutionServiceClient(conn), nil
|
||||
return execution.NewContainerServiceClient(conn), nil
|
||||
}
|
||||
|
||||
func getTempDir(id string) (string, error) {
|
||||
|
@ -122,3 +123,19 @@ func getTempDir(id string) (string, error) {
|
|||
}
|
||||
return tmpDir, nil
|
||||
}
|
||||
|
||||
func waitContainer(events execution.ContainerService_EventsClient, respose *execution.CreateResponse) (uint32, error) {
|
||||
for {
|
||||
e, err := events.Recv()
|
||||
if err != nil {
|
||||
return 255, err
|
||||
}
|
||||
if e.Type != container.Event_EXIT {
|
||||
continue
|
||||
}
|
||||
if e.ID == respose.ID &&
|
||||
e.Pid == respose.Pid {
|
||||
return e.ExitStatus, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ var (
|
|||
// becomes the M declarations at the end of the declaration.
|
||||
packageMap = map[string]string{
|
||||
"google/protobuf/timestamp.proto": "github.com/gogo/protobuf/types",
|
||||
"google/protobuf/any.proto": "github.com/gogo/protobuf/types",
|
||||
"google/protobuf/descriptor.proto": "github.com/gogo/protobuf/protoc-gen-gogo/descriptor",
|
||||
"gogoproto/gogo.proto": "github.com/gogo/protobuf/gogoproto",
|
||||
}
|
||||
|
@ -148,8 +149,9 @@ func main() {
|
|||
// pass to sh -c so we don't need to re-split here.
|
||||
args := []string{"-c", arg}
|
||||
cmd := exec.Command("sh", args...)
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Fatalln(err)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
log.Fatalf("%s %s\n", out, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
94
collector.go
Normal file
94
collector.go
Normal file
|
@ -0,0 +1,94 @@
|
|||
package containerd
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
func newCollector(ctx context.Context, runtimes map[string]Runtime) (*collector, error) {
|
||||
c := &collector{
|
||||
context: ctx,
|
||||
ch: make(chan *Event, 2048),
|
||||
eventClients: make(map[*eventClient]struct{}),
|
||||
}
|
||||
for _, r := range runtimes {
|
||||
if err := c.collect(r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// run the publisher
|
||||
go c.publisher()
|
||||
// run a goroutine that waits for the context to be done
|
||||
// and closes the channel after all writes have finished
|
||||
go c.waitDone()
|
||||
return c, nil
|
||||
}
|
||||
|
||||
type eventClient struct {
|
||||
eCh chan error
|
||||
w EventWriter
|
||||
}
|
||||
|
||||
type collector struct {
|
||||
mu sync.Mutex
|
||||
wg sync.WaitGroup
|
||||
|
||||
context context.Context
|
||||
ch chan *Event
|
||||
eventClients map[*eventClient]struct{}
|
||||
}
|
||||
|
||||
// collect collects events from the provided runtime
|
||||
func (c *collector) collect(r Runtime) error {
|
||||
c.wg.Add(1)
|
||||
go func() {
|
||||
defer c.wg.Done()
|
||||
for e := range r.Events(c.context) {
|
||||
c.ch <- e
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Forward forwards all events from the collector to the EventWriters
|
||||
//
|
||||
// It forwards events until the channels are closed or the EventWriter
|
||||
// returns an error
|
||||
// This is a blocking call
|
||||
func (c *collector) forward(w EventWriter) (err error) {
|
||||
client := &eventClient{
|
||||
w: w,
|
||||
eCh: make(chan error, 1),
|
||||
}
|
||||
c.mu.Lock()
|
||||
c.eventClients[client] = struct{}{}
|
||||
c.mu.Unlock()
|
||||
if serr := <-client.eCh; serr != nil {
|
||||
err = serr
|
||||
}
|
||||
c.mu.Lock()
|
||||
delete(c.eventClients, client)
|
||||
c.mu.Unlock()
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *collector) publisher() {
|
||||
for e := range c.ch {
|
||||
c.mu.Lock()
|
||||
for client := range c.eventClients {
|
||||
if err := client.w.Write(e); err != nil {
|
||||
client.eCh <- err
|
||||
}
|
||||
}
|
||||
c.mu.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
// waitDone waits for the context to finish, waits for all the goroutines to finish
|
||||
// collecting grpc events from the shim, and closes the output channel
|
||||
func (c *collector) waitDone() {
|
||||
<-c.context.Done()
|
||||
c.wg.Wait()
|
||||
close(c.ch)
|
||||
}
|
31
container.go
Normal file
31
container.go
Normal file
|
@ -0,0 +1,31 @@
|
|||
package containerd
|
||||
|
||||
import "golang.org/x/net/context"
|
||||
|
||||
type Container interface {
|
||||
// ID of the container
|
||||
ID() string
|
||||
// Runtime returns the runtime name that the container was created with
|
||||
Runtime() string
|
||||
// Start the container's user defined process
|
||||
Start(context.Context) error
|
||||
// State returns the container's state
|
||||
State(context.Context) (State, error)
|
||||
}
|
||||
|
||||
type ContainerStatus int
|
||||
|
||||
const (
|
||||
CreatedStatus ContainerStatus = iota + 1
|
||||
RunningStatus
|
||||
StoppedStatus
|
||||
DeletedStatus
|
||||
PausedStatus
|
||||
)
|
||||
|
||||
type State interface {
|
||||
// Status is the current status of the container
|
||||
Status() ContainerStatus
|
||||
// Pid is the main process id for the container
|
||||
Pid() uint32
|
||||
}
|
10
errors.go
Normal file
10
errors.go
Normal file
|
@ -0,0 +1,10 @@
|
|||
package containerd
|
||||
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
ErrUnknownRuntime = errors.New("unknown runtime")
|
||||
ErrContainerExists = errors.New("container with id already exists")
|
||||
ErrContainerNotExist = errors.New("container does not exist")
|
||||
ErrRuntimeNotExist = errors.New("runtime does not exist")
|
||||
)
|
70
event.go
Normal file
70
event.go
Normal file
|
@ -0,0 +1,70 @@
|
|||
package containerd
|
||||
|
||||
import "time"
|
||||
|
||||
type EventType int
|
||||
|
||||
func (t EventType) String() string {
|
||||
switch t {
|
||||
case ExitEvent:
|
||||
return "exit"
|
||||
case PausedEvent:
|
||||
return "paused"
|
||||
case CreateEvent:
|
||||
return "create"
|
||||
case StartEvent:
|
||||
return "start"
|
||||
case OOMEvent:
|
||||
return "oom"
|
||||
case ExecAddEvent:
|
||||
return "execAdd"
|
||||
}
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
const (
|
||||
ExitEvent EventType = iota + 1
|
||||
PausedEvent
|
||||
CreateEvent
|
||||
StartEvent
|
||||
OOMEvent
|
||||
ExecAddEvent
|
||||
)
|
||||
|
||||
type Event struct {
|
||||
Timestamp time.Time
|
||||
Type EventType
|
||||
Runtime string
|
||||
ID string
|
||||
Pid uint32
|
||||
ExitStatus uint32
|
||||
}
|
||||
|
||||
type EventWriter interface {
|
||||
Write(*Event) error
|
||||
}
|
||||
|
||||
type EventFilter func(*Event) bool
|
||||
|
||||
// NewFilterEventWriter returns an EventWriter that runs the provided filters on the events.
|
||||
// If all the filters pass then the event is written to the wrapped EventWriter
|
||||
func NewFilterEventWriter(w EventWriter, filters ...EventFilter) EventWriter {
|
||||
return &filteredEventWriter{
|
||||
w: w,
|
||||
filters: filters,
|
||||
}
|
||||
}
|
||||
|
||||
type filteredEventWriter struct {
|
||||
w EventWriter
|
||||
filters []EventFilter
|
||||
}
|
||||
|
||||
func (f *filteredEventWriter) Write(e *Event) error {
|
||||
for _, filter := range f.filters {
|
||||
if !filter(e) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return f.w.Write(e)
|
||||
}
|
|
@ -1,179 +0,0 @@
|
|||
package execution
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"github.com/docker/containerd/log"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
InitProcessID = "init"
|
||||
processesDirName = "processes"
|
||||
bundleFileName = "bundle"
|
||||
)
|
||||
|
||||
func LoadContainer(ctx context.Context, stateDir, id string) (c *Container, err error) {
|
||||
c = &Container{
|
||||
id: id,
|
||||
stateDir: stateDir,
|
||||
processes: make(map[string]Process, 1),
|
||||
ctx: ctx,
|
||||
status: Unknown,
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadFile(filepath.Join(stateDir, bundleFileName))
|
||||
if err != nil {
|
||||
err = errors.Wrapf(err, "failed to read bundle path")
|
||||
return
|
||||
}
|
||||
c.bundle = string(data)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func NewContainer(ctx context.Context, stateDir, id, bundle string) (c *Container, err error) {
|
||||
c = &Container{
|
||||
id: id,
|
||||
stateDir: stateDir,
|
||||
bundle: bundle,
|
||||
processes: make(map[string]Process, 1),
|
||||
status: Created,
|
||||
ctx: ctx,
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
c.Cleanup()
|
||||
c = nil
|
||||
}
|
||||
}()
|
||||
|
||||
if err = os.Mkdir(stateDir, 0700); err != nil {
|
||||
err = errors.Wrap(err, "failed to create container state dir")
|
||||
return
|
||||
}
|
||||
|
||||
bundleFile := filepath.Join(stateDir, bundleFileName)
|
||||
if err = ioutil.WriteFile(bundleFile, []byte(bundle), 0600); err != nil {
|
||||
err = errors.Wrap(err, "failed to store bundle path")
|
||||
return
|
||||
}
|
||||
|
||||
processesDir := filepath.Join(stateDir, processesDirName)
|
||||
if err = os.Mkdir(processesDir, 0700); err != nil {
|
||||
err = errors.Wrap(err, "failed to create processes statedir")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
type Container struct {
|
||||
id string
|
||||
stateDir string
|
||||
bundle string
|
||||
processes map[string]Process
|
||||
status Status
|
||||
|
||||
ctx context.Context
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func (c *Container) ID() string {
|
||||
return c.id
|
||||
}
|
||||
|
||||
func (c *Container) Bundle() string {
|
||||
return c.bundle
|
||||
}
|
||||
|
||||
func (c *Container) Wait() (uint32, error) {
|
||||
initProcess := c.GetProcess(InitProcessID)
|
||||
return initProcess.Wait()
|
||||
}
|
||||
|
||||
func (c *Container) Status() Status {
|
||||
initProcess := c.GetProcess(InitProcessID)
|
||||
return initProcess.Status()
|
||||
}
|
||||
|
||||
func (c *Container) AddProcess(p Process) {
|
||||
c.mu.Lock()
|
||||
c.processes[p.ID()] = p
|
||||
c.mu.Unlock()
|
||||
}
|
||||
|
||||
func (c *Container) RemoveProcess(id string) error {
|
||||
if _, ok := c.processes[id]; !ok {
|
||||
return errors.Errorf("no such process %s", id)
|
||||
}
|
||||
|
||||
c.mu.Lock()
|
||||
delete(c.processes, id)
|
||||
c.mu.Unlock()
|
||||
|
||||
processStateDir := filepath.Join(c.stateDir, processesDirName, id)
|
||||
err := os.RemoveAll(processStateDir)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to remove process state dir")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Container) GetProcess(id string) Process {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
return c.processes[id]
|
||||
}
|
||||
|
||||
func (c *Container) Processes() []Process {
|
||||
var procs []Process
|
||||
|
||||
c.mu.Lock()
|
||||
for _, p := range c.processes {
|
||||
procs = append(procs, p)
|
||||
}
|
||||
c.mu.Unlock()
|
||||
|
||||
return procs
|
||||
}
|
||||
|
||||
// ProcessStateDir returns the path of the state dir for a given
|
||||
// process id. The process doesn't have to exist for this to succeed.
|
||||
func (c *Container) ProcessStateDir(id string) string {
|
||||
return filepath.Join(c.stateDir, processesDirName, id)
|
||||
}
|
||||
|
||||
// ProcessesStateDir returns a map matching process ids to their state
|
||||
// directory
|
||||
func (c *Container) ProcessesStateDir() (map[string]string, error) {
|
||||
root := filepath.Join(c.stateDir, processesDirName)
|
||||
dirs, err := ioutil.ReadDir(root)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to list processes state dirs")
|
||||
}
|
||||
|
||||
procs := make(map[string]string, 1)
|
||||
for _, d := range dirs {
|
||||
if d.IsDir() {
|
||||
procs[d.Name()] = filepath.Join(root, d.Name())
|
||||
}
|
||||
}
|
||||
|
||||
return procs, nil
|
||||
}
|
||||
|
||||
func (c *Container) Cleanup() {
|
||||
if err := os.RemoveAll(c.stateDir); err != nil {
|
||||
log.G(c.ctx).Warnf("failed to remove container state dir: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Container) Context() context.Context {
|
||||
return c.ctx
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package execution
|
||||
|
||||
import "fmt"
|
||||
|
||||
var (
|
||||
ErrProcessNotFound = fmt.Errorf("process not found")
|
||||
ErrProcessNotExited = fmt.Errorf("process has not exited")
|
||||
ErrContainerNotFound = fmt.Errorf("container not found")
|
||||
ErrContainerExists = fmt.Errorf("container already exists")
|
||||
)
|
|
@ -1,28 +0,0 @@
|
|||
package execution
|
||||
|
||||
import "time"
|
||||
|
||||
const (
|
||||
ExitEvent = "exit"
|
||||
OOMEvent = "oom"
|
||||
CreateEvent = "create"
|
||||
StartEvent = "start"
|
||||
ExecEvent = "exec-added9"
|
||||
)
|
||||
|
||||
type ContainerEvent struct {
|
||||
Timestamp time.Time
|
||||
ID string
|
||||
Type string
|
||||
Pid uint32
|
||||
ExitStatus uint32
|
||||
}
|
||||
|
||||
const (
|
||||
ContainersEventsSubjectSubscriber = "containerd.execution.container.>"
|
||||
)
|
||||
|
||||
const (
|
||||
containerEventsTopicFormat = "container.%s"
|
||||
containerProcessEventsTopicFormat = "container.%s.%s"
|
||||
)
|
|
@ -1,39 +0,0 @@
|
|||
package execution
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
type CreateOpts struct {
|
||||
Bundle string
|
||||
Console bool
|
||||
Stdin string
|
||||
Stdout string
|
||||
Stderr string
|
||||
}
|
||||
|
||||
type StartProcessOpts struct {
|
||||
ID string
|
||||
Spec specs.Process
|
||||
Console bool
|
||||
Stdin string
|
||||
Stdout string
|
||||
Stderr string
|
||||
}
|
||||
|
||||
type Executor interface {
|
||||
Create(ctx context.Context, id string, o CreateOpts) (*Container, error)
|
||||
Pause(context.Context, *Container) error
|
||||
Resume(context.Context, *Container) error
|
||||
List(context.Context) ([]*Container, error)
|
||||
Load(ctx context.Context, id string) (*Container, error)
|
||||
Delete(context.Context, *Container) error
|
||||
Start(context.Context, *Container) error
|
||||
|
||||
StartProcess(context.Context, *Container, StartProcessOpts) (Process, error)
|
||||
SignalProcess(ctx context.Context, c *Container, id string, sig os.Signal) error
|
||||
DeleteProcess(ctx context.Context, c *Container, id string) error
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
package execution
|
||||
|
||||
import "os"
|
||||
|
||||
type Process interface {
|
||||
ID() string
|
||||
Pid() int64
|
||||
//Spec() *specs.Process
|
||||
Wait() (uint32, error)
|
||||
Signal(os.Signal) error
|
||||
Status() Status
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
package execution
|
||||
|
||||
type Status string
|
||||
|
||||
const (
|
||||
Created Status = "created"
|
||||
Paused Status = "paused"
|
||||
Pausing Status = "pausing"
|
||||
Running Status = "running"
|
||||
Stopped Status = "stopped"
|
||||
Deleted Status = "deleted"
|
||||
Unknown Status = "unknown"
|
||||
|
||||
UnknownStatusCode = 255
|
||||
)
|
49
linux/container.go
Normal file
49
linux/container.go
Normal file
|
@ -0,0 +1,49 @@
|
|||
package linux
|
||||
|
||||
import (
|
||||
"github.com/docker/containerd"
|
||||
"github.com/docker/containerd/api/services/shim"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type State struct {
|
||||
pid uint32
|
||||
status containerd.ContainerStatus
|
||||
}
|
||||
|
||||
func (s State) Pid() uint32 {
|
||||
return s.pid
|
||||
}
|
||||
|
||||
func (s State) Status() containerd.ContainerStatus {
|
||||
return s.status
|
||||
}
|
||||
|
||||
type Container struct {
|
||||
id string
|
||||
|
||||
shim shim.ShimClient
|
||||
}
|
||||
|
||||
func (c *Container) ID() string {
|
||||
return c.id
|
||||
}
|
||||
|
||||
func (Container) Runtime() string {
|
||||
return runtimeName
|
||||
}
|
||||
|
||||
func (c *Container) Start(ctx context.Context) error {
|
||||
_, err := c.shim.Start(ctx, &shim.StartRequest{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Container) State(ctx context.Context) (containerd.State, error) {
|
||||
response, err := c.shim.State(ctx, &shim.StateRequest{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &State{
|
||||
pid: response.Pid,
|
||||
}, nil
|
||||
}
|
197
linux/runtime.go
Normal file
197
linux/runtime.go
Normal file
|
@ -0,0 +1,197 @@
|
|||
package linux
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/docker/containerd"
|
||||
"github.com/docker/containerd/api/services/shim"
|
||||
"github.com/docker/containerd/api/types/container"
|
||||
"github.com/docker/containerd/api/types/mount"
|
||||
"github.com/docker/swarmkit/log"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
const (
|
||||
runtimeName = "linux"
|
||||
configFilename = "config.json"
|
||||
)
|
||||
|
||||
func init() {
|
||||
containerd.RegisterRuntime(runtimeName, New)
|
||||
}
|
||||
|
||||
func New(root string) (containerd.Runtime, error) {
|
||||
if err := os.MkdirAll(root, 0700); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c, cancel := context.WithCancel(context.Background())
|
||||
return &Runtime{
|
||||
root: root,
|
||||
events: make(chan *containerd.Event, 2048),
|
||||
eventsContext: c,
|
||||
eventsCancel: cancel,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type Runtime struct {
|
||||
root string
|
||||
|
||||
events chan *containerd.Event
|
||||
eventsContext context.Context
|
||||
eventsCancel func()
|
||||
}
|
||||
|
||||
func (r *Runtime) Create(ctx context.Context, id string, opts containerd.CreateOpts) (containerd.Container, error) {
|
||||
path, err := r.newBundle(id, opts.Spec)
|
||||
if err != nil {
|
||||
os.RemoveAll(path)
|
||||
return nil, err
|
||||
}
|
||||
s, err := newShim(path)
|
||||
if err != nil {
|
||||
os.RemoveAll(path)
|
||||
return nil, err
|
||||
}
|
||||
if err := r.handleEvents(s); err != nil {
|
||||
os.RemoveAll(path)
|
||||
return nil, err
|
||||
}
|
||||
sopts := &shim.CreateRequest{
|
||||
ID: id,
|
||||
Bundle: path,
|
||||
Runtime: "runc",
|
||||
Stdin: opts.IO.Stdin,
|
||||
Stdout: opts.IO.Stdout,
|
||||
Stderr: opts.IO.Stderr,
|
||||
Terminal: opts.IO.Terminal,
|
||||
}
|
||||
for _, m := range opts.Rootfs {
|
||||
sopts.Rootfs = append(sopts.Rootfs, &mount.Mount{
|
||||
Type: m.Type,
|
||||
Source: m.Source,
|
||||
Options: m.Options,
|
||||
})
|
||||
}
|
||||
if _, err := s.Create(ctx, sopts); err != nil {
|
||||
os.RemoveAll(path)
|
||||
return nil, err
|
||||
}
|
||||
return &Container{
|
||||
id: id,
|
||||
shim: s,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *Runtime) Delete(ctx context.Context, c containerd.Container) error {
|
||||
lc, ok := c.(*Container)
|
||||
if !ok {
|
||||
return fmt.Errorf("container cannot be cast as *linux.Container")
|
||||
}
|
||||
if _, err := lc.shim.Delete(ctx, &shim.DeleteRequest{}); err != nil {
|
||||
return err
|
||||
}
|
||||
lc.shim.Exit(ctx, &shim.ExitRequest{})
|
||||
return r.deleteBundle(lc.id)
|
||||
}
|
||||
|
||||
func (r *Runtime) Containers() ([]containerd.Container, error) {
|
||||
dir, err := ioutil.ReadDir(r.root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var o []containerd.Container
|
||||
for _, fi := range dir {
|
||||
if !fi.IsDir() {
|
||||
continue
|
||||
}
|
||||
c, err := r.loadContainer(fi.Name())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
o = append(o, c)
|
||||
}
|
||||
return o, nil
|
||||
}
|
||||
|
||||
func (r *Runtime) Events(ctx context.Context) <-chan *containerd.Event {
|
||||
return r.events
|
||||
}
|
||||
|
||||
func (r *Runtime) handleEvents(s shim.ShimClient) error {
|
||||
events, err := s.Events(r.eventsContext, &shim.EventsRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go r.forward(events)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Runtime) forward(events shim.Shim_EventsClient) {
|
||||
for {
|
||||
e, err := events.Recv()
|
||||
if err != nil {
|
||||
log.G(r.eventsContext).WithError(err).Error("get event from shim")
|
||||
return
|
||||
}
|
||||
var et containerd.EventType
|
||||
switch e.Type {
|
||||
case container.Event_CREATE:
|
||||
et = containerd.CreateEvent
|
||||
case container.Event_EXEC_ADDED:
|
||||
et = containerd.ExecAddEvent
|
||||
case container.Event_EXIT:
|
||||
et = containerd.ExitEvent
|
||||
case container.Event_OOM:
|
||||
et = containerd.OOMEvent
|
||||
case container.Event_START:
|
||||
et = containerd.StartEvent
|
||||
}
|
||||
r.events <- &containerd.Event{
|
||||
Timestamp: time.Now(),
|
||||
Runtime: runtimeName,
|
||||
Type: et,
|
||||
Pid: e.Pid,
|
||||
ID: e.ID,
|
||||
ExitStatus: e.ExitStatus,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Runtime) newBundle(id string, spec []byte) (string, error) {
|
||||
path := filepath.Join(r.root, id)
|
||||
if err := os.Mkdir(path, 0700); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if err := os.Mkdir(filepath.Join(path, "rootfs"), 0700); err != nil {
|
||||
return "", err
|
||||
}
|
||||
f, err := os.Create(filepath.Join(path, configFilename))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
_, err = io.Copy(f, bytes.NewReader(spec))
|
||||
return path, err
|
||||
}
|
||||
|
||||
func (r *Runtime) deleteBundle(id string) error {
|
||||
return os.RemoveAll(filepath.Join(r.root, id))
|
||||
}
|
||||
|
||||
func (r *Runtime) loadContainer(path string) (*Container, error) {
|
||||
id := filepath.Base(path)
|
||||
s, err := loadShim(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Container{
|
||||
id: id,
|
||||
shim: s,
|
||||
}, nil
|
||||
}
|
76
linux/shim.go
Normal file
76
linux/shim.go
Normal file
|
@ -0,0 +1,76 @@
|
|||
package linux
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
|
||||
"github.com/docker/containerd/api/services/shim"
|
||||
"github.com/docker/containerd/utils"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func newShim(path string) (shim.ShimClient, error) {
|
||||
socket := filepath.Join(path, "shim.sock")
|
||||
l, err := utils.CreateUnixSocket(socket)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd := exec.Command("containerd-shim")
|
||||
cmd.Dir = path
|
||||
f, err := l.(*net.UnixListener).File()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd.ExtraFiles = append(cmd.ExtraFiles, f)
|
||||
// make sure the shim can be re-parented to system init
|
||||
// and is cloned in a new mount namespace because the overlay/filesystems
|
||||
// will be mounted by the shim
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||
Cloneflags: syscall.CLONE_NEWNS,
|
||||
Setpgid: true,
|
||||
}
|
||||
if err := cmd.Start(); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to start shim")
|
||||
}
|
||||
// close our side of the socket, do not close the listener as it will
|
||||
// remove the socket from disk
|
||||
f.Close()
|
||||
// since we are currently the parent go ahead and make sure we wait on the shim
|
||||
go cmd.Wait()
|
||||
return connectShim(socket)
|
||||
}
|
||||
|
||||
func loadShim(path string) (shim.ShimClient, error) {
|
||||
socket := filepath.Join(path, "shim.sock")
|
||||
return connectShim(socket)
|
||||
// TODO: failed to connect to the shim, check if it's alive
|
||||
// - if it is kill it
|
||||
// - in both case call runc killall and runc delete on the id
|
||||
}
|
||||
|
||||
func connectShim(socket string) (shim.ShimClient, error) {
|
||||
// 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(100 * time.Second)}
|
||||
dialOpts = append(dialOpts,
|
||||
grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) {
|
||||
return net.DialTimeout("unix", socket, timeout)
|
||||
}),
|
||||
grpc.WithBlock(),
|
||||
grpc.WithTimeout(2*time.Second),
|
||||
)
|
||||
conn, err := grpc.Dial(fmt.Sprintf("unix://%s", socket), dialOpts...)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to connect to shim via \"%s\"", fmt.Sprintf("unix://%s", socket))
|
||||
}
|
||||
return shim.NewShimClient(conn), nil
|
||||
}
|
10
mount.go
10
mount.go
|
@ -3,9 +3,6 @@ package containerd
|
|||
import (
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/containerd/log"
|
||||
)
|
||||
|
||||
// Mount is the lingua franca of containerd. A mount represents a
|
||||
|
@ -23,13 +20,6 @@ type Mount struct {
|
|||
|
||||
func (m *Mount) Mount(target string) error {
|
||||
flags, data := parseMountOptions(m.Options)
|
||||
|
||||
lfields := logrus.Fields{"target": target, "source": m.Source}
|
||||
if data != "" {
|
||||
lfields["data"] = data
|
||||
}
|
||||
log.L.WithFields(lfields).Debug("syscall.Mount")
|
||||
|
||||
return syscall.Mount(m.Source, target, m.Type, uintptr(flags), data)
|
||||
}
|
||||
|
||||
|
|
79
runtime.go
Normal file
79
runtime.go
Normal file
|
@ -0,0 +1,79 @@
|
|||
package containerd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// NewRuntimeFunc is the runtime's constructor
|
||||
type NewRuntimeFunc func(root string) (Runtime, error)
|
||||
|
||||
var runtimeRegistration = struct {
|
||||
mu sync.Mutex
|
||||
runtimes map[string]NewRuntimeFunc
|
||||
}{
|
||||
runtimes: make(map[string]NewRuntimeFunc),
|
||||
}
|
||||
|
||||
// RegisterRuntime is not external packages registers Runtimes for use with containerd
|
||||
func RegisterRuntime(name string, f NewRuntimeFunc) {
|
||||
runtimeRegistration.mu.Lock()
|
||||
defer runtimeRegistration.mu.Unlock()
|
||||
if _, ok := runtimeRegistration.runtimes[name]; ok {
|
||||
panic(fmt.Errorf("runtime already registered as %q", name))
|
||||
}
|
||||
runtimeRegistration.runtimes[name] = f
|
||||
}
|
||||
|
||||
// Runtimes returns a slice of all registered runtime names for containerd
|
||||
func Runtimes() (o []string) {
|
||||
runtimeRegistration.mu.Lock()
|
||||
defer runtimeRegistration.mu.Unlock()
|
||||
|
||||
for k := range runtimeRegistration.runtimes {
|
||||
o = append(o, k)
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// NewRuntime calls the runtime's constructor with the provided root
|
||||
func NewRuntime(name, root string) (Runtime, error) {
|
||||
runtimeRegistration.mu.Lock()
|
||||
defer runtimeRegistration.mu.Unlock()
|
||||
f, ok := runtimeRegistration.runtimes[name]
|
||||
if !ok {
|
||||
return nil, ErrRuntimeNotExist
|
||||
}
|
||||
return f(root)
|
||||
}
|
||||
|
||||
type IO struct {
|
||||
Stdin string
|
||||
Stdout string
|
||||
Stderr string
|
||||
Terminal bool
|
||||
}
|
||||
|
||||
type CreateOpts struct {
|
||||
// Spec is the OCI runtime spec
|
||||
Spec []byte
|
||||
// Rootfs mounts to perform to gain access to the container's filesystem
|
||||
Rootfs []Mount
|
||||
// IO for the container's main process
|
||||
IO IO
|
||||
}
|
||||
|
||||
// Runtime is responsible for the creation of containers for a certain platform,
|
||||
// arch, or custom usage.
|
||||
type Runtime interface {
|
||||
// Create creates a container with the provided id and options
|
||||
Create(ctx context.Context, id string, opts CreateOpts) (Container, error)
|
||||
// Containers returns all the current containers for the runtime
|
||||
Containers() ([]Container, error)
|
||||
// Delete returns the container in the runtime
|
||||
Delete(ctx context.Context, c Container) error
|
||||
// Events returns events for the runtime and all containers created by the runtime
|
||||
Events(context.Context) <-chan *Event
|
||||
}
|
136
services/execution/service.go
Normal file
136
services/execution/service.go
Normal file
|
@ -0,0 +1,136 @@
|
|||
package execution
|
||||
|
||||
import (
|
||||
"github.com/docker/containerd"
|
||||
api "github.com/docker/containerd/api/services/execution"
|
||||
"github.com/docker/containerd/api/types/container"
|
||||
google_protobuf "github.com/golang/protobuf/ptypes/empty"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
var (
|
||||
_ = (api.ContainerServiceServer)(&Service{})
|
||||
empty = &google_protobuf.Empty{}
|
||||
)
|
||||
|
||||
// New creates a new GRPC service for the ContainerService
|
||||
func New(s *containerd.Supervisor) *Service {
|
||||
return &Service{
|
||||
s: s,
|
||||
}
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
s *containerd.Supervisor
|
||||
}
|
||||
|
||||
func (s *Service) Create(ctx context.Context, r *api.CreateRequest) (*api.CreateResponse, error) {
|
||||
opts := containerd.CreateOpts{
|
||||
Spec: r.Spec.Value,
|
||||
IO: containerd.IO{
|
||||
Stdin: r.Stdin,
|
||||
Stdout: r.Stdout,
|
||||
Stderr: r.Stderr,
|
||||
Terminal: r.Terminal,
|
||||
},
|
||||
}
|
||||
for _, m := range r.Rootfs {
|
||||
opts.Rootfs = append(opts.Rootfs, containerd.Mount{
|
||||
Type: m.Type,
|
||||
Source: m.Source,
|
||||
Options: m.Options,
|
||||
})
|
||||
}
|
||||
c, err := s.s.Create(ctx, r.ID, r.Runtime, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
state, err := c.State(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &api.CreateResponse{
|
||||
ID: r.ID,
|
||||
Pid: state.Pid(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Service) Start(ctx context.Context, r *api.StartRequest) (*google_protobuf.Empty, error) {
|
||||
c, err := s.s.Get(r.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := c.Start(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return empty, nil
|
||||
}
|
||||
|
||||
func (s *Service) Delete(ctx context.Context, r *api.DeleteRequest) (*google_protobuf.Empty, error) {
|
||||
if err := s.s.Delete(ctx, r.ID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return empty, nil
|
||||
}
|
||||
|
||||
func (s *Service) List(ctx context.Context, r *api.ListRequest) (*api.ListResponse, error) {
|
||||
resp := &api.ListResponse{}
|
||||
for _, c := range s.s.Containers() {
|
||||
state, err := c.State(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var status container.Status
|
||||
switch state.Status() {
|
||||
case containerd.CreatedStatus:
|
||||
status = container.Status_CREATED
|
||||
case containerd.RunningStatus:
|
||||
status = container.Status_RUNNING
|
||||
case containerd.StoppedStatus:
|
||||
status = container.Status_STOPPED
|
||||
case containerd.PausedStatus:
|
||||
status = container.Status_PAUSED
|
||||
}
|
||||
resp.Containers = append(resp.Containers, &container.Container{
|
||||
ID: c.ID(),
|
||||
Pid: state.Pid(),
|
||||
Status: status,
|
||||
})
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (s *Service) Events(r *api.EventsRequest, server api.ContainerService_EventsServer) error {
|
||||
w := &grpcEventWriter{
|
||||
server: server,
|
||||
}
|
||||
return s.s.ForwardEvents(w)
|
||||
}
|
||||
|
||||
type grpcEventWriter struct {
|
||||
server api.ContainerService_EventsServer
|
||||
}
|
||||
|
||||
func (g *grpcEventWriter) Write(e *containerd.Event) error {
|
||||
var t container.Event_EventType
|
||||
switch e.Type {
|
||||
case containerd.ExitEvent:
|
||||
t = container.Event_EXIT
|
||||
case containerd.ExecAddEvent:
|
||||
t = container.Event_EXEC_ADDED
|
||||
case containerd.PausedEvent:
|
||||
t = container.Event_PAUSED
|
||||
case containerd.CreateEvent:
|
||||
t = container.Event_CREATE
|
||||
case containerd.StartEvent:
|
||||
t = container.Event_START
|
||||
case containerd.OOMEvent:
|
||||
t = container.Event_OOM
|
||||
}
|
||||
return g.server.Send(&container.Event{
|
||||
Type: t,
|
||||
ID: e.ID,
|
||||
Pid: e.Pid,
|
||||
ExitStatus: e.ExitStatus,
|
||||
})
|
||||
}
|
11
shim/init.go
11
shim/init.go
|
@ -9,6 +9,7 @@ import (
|
|||
|
||||
"github.com/crosbymichael/console"
|
||||
runc "github.com/crosbymichael/go-runc"
|
||||
"github.com/docker/containerd"
|
||||
shimapi "github.com/docker/containerd/api/services/shim"
|
||||
)
|
||||
|
||||
|
@ -29,6 +30,16 @@ func newInitProcess(context context.Context, r *shimapi.CreateRequest) (*initPro
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, rm := range r.Rootfs {
|
||||
m := &containerd.Mount{
|
||||
Type: rm.Type,
|
||||
Source: rm.Source,
|
||||
Options: rm.Options,
|
||||
}
|
||||
if err := m.Mount(filepath.Join(cwd, "rootfs")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
runtime := &runc.Runc{
|
||||
Command: r.Runtime,
|
||||
Log: filepath.Join(cwd, "log.json"),
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
package shim
|
||||
|
||||
import (
|
||||
"os"
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
"github.com/crosbymichael/console"
|
||||
shimapi "github.com/docker/containerd/api/services/shim"
|
||||
processapi "github.com/docker/containerd/api/types/process"
|
||||
stateapi "github.com/docker/containerd/api/types/state"
|
||||
"github.com/docker/containerd/api/types/container"
|
||||
"github.com/docker/containerd/utils"
|
||||
google_protobuf "github.com/golang/protobuf/ptypes/empty"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
var emptyResponse = &google_protobuf.Empty{}
|
||||
var empty = &google_protobuf.Empty{}
|
||||
|
||||
// New returns a new shim service that can be used via GRPC
|
||||
func New() *Service {
|
||||
return &Service{
|
||||
processes: make(map[int]process),
|
||||
events: make(chan *shimapi.Event, 4096),
|
||||
events: make(chan *container.Event, 4096),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ type Service struct {
|
|||
bundle string
|
||||
mu sync.Mutex
|
||||
processes map[int]process
|
||||
events chan *shimapi.Event
|
||||
events chan *container.Event
|
||||
execID int
|
||||
}
|
||||
|
||||
|
@ -46,8 +46,8 @@ func (s *Service) Create(ctx context.Context, r *shimapi.CreateRequest) (*shimap
|
|||
pid := process.Pid()
|
||||
s.processes[pid] = process
|
||||
s.mu.Unlock()
|
||||
s.events <- &shimapi.Event{
|
||||
Type: shimapi.EventType_CREATE,
|
||||
s.events <- &container.Event{
|
||||
Type: container.Event_CREATE,
|
||||
ID: r.ID,
|
||||
Pid: uint32(pid),
|
||||
}
|
||||
|
@ -60,12 +60,12 @@ func (s *Service) Start(ctx context.Context, r *shimapi.StartRequest) (*google_p
|
|||
if err := s.initProcess.Start(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.events <- &shimapi.Event{
|
||||
Type: shimapi.EventType_START,
|
||||
s.events <- &container.Event{
|
||||
Type: container.Event_START,
|
||||
ID: s.id,
|
||||
Pid: uint32(s.initProcess.Pid()),
|
||||
}
|
||||
return emptyResponse, nil
|
||||
return empty, nil
|
||||
}
|
||||
|
||||
func (s *Service) Delete(ctx context.Context, r *shimapi.DeleteRequest) (*shimapi.DeleteResponse, error) {
|
||||
|
@ -73,7 +73,7 @@ func (s *Service) Delete(ctx context.Context, r *shimapi.DeleteRequest) (*shimap
|
|||
p, ok := s.processes[int(r.Pid)]
|
||||
s.mu.Unlock()
|
||||
if !ok {
|
||||
return nil, errors.Errorf("process does not exist %d", r.Pid)
|
||||
p = s.initProcess
|
||||
}
|
||||
if err := p.Delete(ctx); err != nil {
|
||||
return nil, err
|
||||
|
@ -96,8 +96,8 @@ func (s *Service) Exec(ctx context.Context, r *shimapi.ExecRequest) (*shimapi.Ex
|
|||
}
|
||||
pid := process.Pid()
|
||||
s.processes[pid] = process
|
||||
s.events <- &shimapi.Event{
|
||||
Type: shimapi.EventType_EXEC_ADDED,
|
||||
s.events <- &container.Event{
|
||||
Type: container.Event_EXEC_ADDED,
|
||||
ID: s.id,
|
||||
Pid: uint32(pid),
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ func (s *Service) Pty(ctx context.Context, r *shimapi.PtyRequest) (*google_proto
|
|||
if err := p.Resize(ws); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return emptyResponse, nil
|
||||
return empty, nil
|
||||
}
|
||||
|
||||
func (s *Service) Events(r *shimapi.EventsRequest, stream shimapi.Shim_EventsServer) error {
|
||||
|
@ -139,22 +139,22 @@ func (s *Service) State(ctx context.Context, r *shimapi.StateRequest) (*shimapi.
|
|||
o := &shimapi.StateResponse{
|
||||
ID: s.id,
|
||||
Bundle: s.bundle,
|
||||
InitPid: uint32(s.initProcess.Pid()),
|
||||
Processes: []*processapi.Process{},
|
||||
Pid: uint32(s.initProcess.Pid()),
|
||||
Processes: []*container.Process{},
|
||||
}
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
for _, p := range s.processes {
|
||||
state := stateapi.State_RUNNING
|
||||
status := container.Status_RUNNING
|
||||
if err := syscall.Kill(p.Pid(), 0); err != nil {
|
||||
if err != syscall.ESRCH {
|
||||
return nil, err
|
||||
}
|
||||
state = stateapi.State_STOPPED
|
||||
status = container.Status_STOPPED
|
||||
}
|
||||
o.Processes = append(o.Processes, &processapi.Process{
|
||||
Pid: uint32(p.Pid()),
|
||||
State: state,
|
||||
o.Processes = append(o.Processes, &container.Process{
|
||||
Pid: uint32(p.Pid()),
|
||||
Status: status,
|
||||
})
|
||||
}
|
||||
return o, nil
|
||||
|
@ -164,22 +164,30 @@ func (s *Service) Pause(ctx context.Context, r *shimapi.PauseRequest) (*google_p
|
|||
if err := s.initProcess.Pause(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return emptyResponse, nil
|
||||
return empty, nil
|
||||
}
|
||||
|
||||
func (s *Service) Resume(ctx context.Context, r *shimapi.ResumeRequest) (*google_protobuf.Empty, error) {
|
||||
if err := s.initProcess.Resume(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return emptyResponse, nil
|
||||
return empty, nil
|
||||
}
|
||||
|
||||
func (s *Service) Exit(ctx context.Context, r *shimapi.ExitRequest) (*google_protobuf.Empty, error) {
|
||||
// signal ourself to exit
|
||||
if err := syscall.Kill(os.Getpid(), syscall.SIGTERM); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return empty, nil
|
||||
}
|
||||
|
||||
func (s *Service) ProcessExit(e utils.Exit) error {
|
||||
s.mu.Lock()
|
||||
if p, ok := s.processes[e.Pid]; ok {
|
||||
p.Exited(e.Status)
|
||||
s.events <- &shimapi.Event{
|
||||
Type: shimapi.EventType_EXIT,
|
||||
s.events <- &container.Event{
|
||||
Type: container.Event_EXIT,
|
||||
ID: s.id,
|
||||
Pid: uint32(p.Pid()),
|
||||
ExitStatus: uint32(e.Status),
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
package specification
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
|
||||
"github.com/docker/containerd"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
var rwm = "rwm"
|
||||
|
||||
func Default(config containerd.Config, mounts []containerd.Mount) *specs.Spec {
|
||||
s := &specs.Spec{
|
||||
Version: specs.Version,
|
||||
Platform: specs.Platform{
|
||||
OS: runtime.GOOS,
|
||||
Arch: runtime.GOARCH,
|
||||
},
|
||||
Root: specs.Root{
|
||||
Path: "rootfs",
|
||||
Readonly: false,
|
||||
},
|
||||
Process: specs.Process{
|
||||
Args: config.Process.Args,
|
||||
Env: config.Process.Env,
|
||||
Terminal: config.Process.TTY,
|
||||
Cwd: config.Process.Cwd,
|
||||
NoNewPrivileges: true,
|
||||
},
|
||||
Hostname: config.Hostname,
|
||||
Linux: &specs.Linux{
|
||||
Resources: &specs.LinuxResources{
|
||||
Devices: []specs.LinuxDeviceCgroup{
|
||||
{
|
||||
Allow: false,
|
||||
Access: &rwm,
|
||||
},
|
||||
},
|
||||
},
|
||||
Namespaces: []specs.LinuxNamespace{
|
||||
{
|
||||
Type: "pid",
|
||||
},
|
||||
{
|
||||
Type: "ipc",
|
||||
},
|
||||
{
|
||||
Type: "uts",
|
||||
},
|
||||
{
|
||||
Type: "mount",
|
||||
},
|
||||
{
|
||||
Type: "network",
|
||||
},
|
||||
},
|
||||
},
|
||||
Annotations: config.Labels,
|
||||
}
|
||||
// apply snapshot mounts
|
||||
for _, m := range mounts {
|
||||
s.Mounts = append(s.Mounts, specs.Mount{
|
||||
Source: m.Source,
|
||||
Destination: "/",
|
||||
Type: m.Type,
|
||||
Options: m.Options,
|
||||
})
|
||||
}
|
||||
return s
|
||||
}
|
100
supervisor.go
Normal file
100
supervisor.go
Normal file
|
@ -0,0 +1,100 @@
|
|||
package containerd
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
func NewSupervisor(ctx context.Context, runtimes map[string]Runtime) (*Supervisor, error) {
|
||||
c, err := newCollector(ctx, runtimes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s := &Supervisor{
|
||||
containers: make(map[string]Container),
|
||||
runtimes: runtimes,
|
||||
collector: c,
|
||||
}
|
||||
for _, r := range runtimes {
|
||||
containers, err := r.Containers()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, c := range containers {
|
||||
s.containers[c.ID()] = c
|
||||
}
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// Supervisor supervises containers and events from multiple runtimes
|
||||
type Supervisor struct {
|
||||
mu sync.Mutex
|
||||
|
||||
containers map[string]Container
|
||||
runtimes map[string]Runtime
|
||||
collector *collector
|
||||
}
|
||||
|
||||
// ForwardEvents is a blocking method that will forward all events from the supervisor
|
||||
// to the EventWriter provided by the caller
|
||||
func (s *Supervisor) ForwardEvents(w EventWriter) error {
|
||||
return s.collector.forward(w)
|
||||
}
|
||||
|
||||
// Create creates a new container with the provided runtime
|
||||
func (s *Supervisor) Create(ctx context.Context, id, runtime string, opts CreateOpts) (Container, error) {
|
||||
r, ok := s.runtimes[runtime]
|
||||
if !ok {
|
||||
return nil, ErrUnknownRuntime
|
||||
}
|
||||
// check to make sure the container's id is unique across the entire system
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
if _, ok := s.containers[id]; ok {
|
||||
return nil, ErrContainerExists
|
||||
}
|
||||
c, err := r.Create(ctx, id, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.containers[c.ID()] = c
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// Delete deletes the container
|
||||
func (s *Supervisor) Delete(ctx context.Context, id string) error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
c, ok := s.containers[id]
|
||||
if !ok {
|
||||
return ErrContainerNotExist
|
||||
}
|
||||
err := s.runtimes[c.Runtime()].Delete(ctx, c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
delete(s.containers, id)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Containers returns all the containers for the supervisor
|
||||
func (s *Supervisor) Containers() (o []Container) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
for _, c := range s.containers {
|
||||
o = append(o, c)
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (s *Supervisor) Get(id string) (Container, error) {
|
||||
s.mu.Lock()
|
||||
c, ok := s.containers[id]
|
||||
s.mu.Unlock()
|
||||
if !ok {
|
||||
return nil, ErrContainerNotExist
|
||||
}
|
||||
return c, nil
|
||||
}
|
|
@ -1,354 +0,0 @@
|
|||
package supervisor
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
executionapi "github.com/docker/containerd/api/services/execution"
|
||||
"github.com/docker/containerd/api/services/shim"
|
||||
"github.com/docker/containerd/api/types/container"
|
||||
"github.com/docker/containerd/api/types/process"
|
||||
"github.com/docker/containerd/events"
|
||||
"github.com/docker/containerd/execution"
|
||||
"github.com/docker/containerd/log"
|
||||
google_protobuf "github.com/golang/protobuf/ptypes/empty"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
var (
|
||||
_ = (executionapi.ExecutionServiceServer)(&Service{})
|
||||
empty = &google_protobuf.Empty{}
|
||||
)
|
||||
|
||||
// New creates a new GRPC services for execution
|
||||
func New(ctx context.Context, root string) (*Service, error) {
|
||||
ctx = log.WithModule(ctx, "supervisor")
|
||||
log.G(ctx).WithField("root", root).Debugf("New()")
|
||||
if err := os.MkdirAll(root, 0700); err != nil {
|
||||
return nil, errors.Wrapf(err, "unable to create root directory %q", root)
|
||||
}
|
||||
clients, err := loadClients(ctx, root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s := &Service{
|
||||
root: root,
|
||||
shims: clients,
|
||||
ctx: ctx,
|
||||
}
|
||||
for _, c := range clients {
|
||||
if err := s.monitor(events.GetPoster(ctx), c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
mu sync.Mutex
|
||||
|
||||
ctx context.Context
|
||||
root string
|
||||
shims map[string]*shimClient
|
||||
}
|
||||
|
||||
func (s *Service) propagateRuntimeLog(client *shimClient, entries int) {
|
||||
logs, err := client.readRuntimeLogEntries(entries)
|
||||
if err != nil {
|
||||
log.G(s.ctx).WithError(err).WithField("container", client.id).
|
||||
Warnf("failed to read shim log")
|
||||
return
|
||||
}
|
||||
log.G(s.ctx).WithField("container", client.id).
|
||||
Warnf("shim log (last %d entry): %v", entries, logs)
|
||||
}
|
||||
|
||||
func (s *Service) CreateContainer(ctx context.Context, r *executionapi.CreateContainerRequest) (*executionapi.CreateContainerResponse, error) {
|
||||
client, err := s.newShim(r.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
s.propagateRuntimeLog(client, 1)
|
||||
s.removeShim(r.ID)
|
||||
}
|
||||
}()
|
||||
|
||||
if err := s.monitor(events.GetPoster(ctx), client); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
createResponse, err := client.Create(ctx, &shim.CreateRequest{
|
||||
ID: r.ID,
|
||||
Bundle: r.BundlePath,
|
||||
Terminal: r.Console,
|
||||
Stdin: r.Stdin,
|
||||
Stdout: r.Stdout,
|
||||
Stderr: r.Stderr,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "shim create request failed")
|
||||
}
|
||||
client.initPid = createResponse.Pid
|
||||
return &executionapi.CreateContainerResponse{
|
||||
Container: &container.Container{
|
||||
ID: r.ID,
|
||||
},
|
||||
InitProcess: &process.Process{
|
||||
Pid: createResponse.Pid,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Service) StartContainer(ctx context.Context, r *executionapi.StartContainerRequest) (*google_protobuf.Empty, error) {
|
||||
client, err := s.getShim(r.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := client.Start(ctx, &shim.StartRequest{}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return empty, nil
|
||||
}
|
||||
|
||||
func (s *Service) DeleteContainer(ctx context.Context, r *executionapi.DeleteContainerRequest) (*google_protobuf.Empty, error) {
|
||||
client, err := s.getShim(r.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = client.Delete(ctx, &shim.DeleteRequest{
|
||||
Pid: client.initPid,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.removeShim(r.ID)
|
||||
return empty, nil
|
||||
}
|
||||
|
||||
func (s *Service) ListContainers(ctx context.Context, r *executionapi.ListContainersRequest) (*executionapi.ListContainersResponse, error) {
|
||||
resp := &executionapi.ListContainersResponse{}
|
||||
for _, client := range s.shims {
|
||||
status, err := client.State(ctx, &shim.StateRequest{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp.Containers = append(resp.Containers, &container.Container{
|
||||
ID: status.ID,
|
||||
Bundle: status.Bundle,
|
||||
})
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
func (s *Service) GetContainer(ctx context.Context, r *executionapi.GetContainerRequest) (*executionapi.GetContainerResponse, error) {
|
||||
client, err := s.getShim(r.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
state, err := client.State(ctx, &shim.StateRequest{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &executionapi.GetContainerResponse{
|
||||
Container: &container.Container{
|
||||
ID: state.ID,
|
||||
Bundle: state.Bundle,
|
||||
// TODO: add processes
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Service) UpdateContainer(ctx context.Context, r *executionapi.UpdateContainerRequest) (*google_protobuf.Empty, error) {
|
||||
panic("not implemented")
|
||||
return empty, nil
|
||||
}
|
||||
|
||||
func (s *Service) PauseContainer(ctx context.Context, r *executionapi.PauseContainerRequest) (*google_protobuf.Empty, error) {
|
||||
client, err := s.getShim(r.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return client.Pause(ctx, &shim.PauseRequest{})
|
||||
}
|
||||
|
||||
func (s *Service) ResumeContainer(ctx context.Context, r *executionapi.ResumeContainerRequest) (*google_protobuf.Empty, error) {
|
||||
client, err := s.getShim(r.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return client.Resume(ctx, &shim.ResumeRequest{})
|
||||
}
|
||||
|
||||
func (s *Service) StartProcess(ctx context.Context, r *executionapi.StartProcessRequest) (*executionapi.StartProcessResponse, error) {
|
||||
client, err := s.getShim(r.ContainerID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
er := &shim.ExecRequest{
|
||||
Terminal: r.Console,
|
||||
Stdin: r.Stdin,
|
||||
Stdout: r.Stdout,
|
||||
Stderr: r.Stderr,
|
||||
Args: r.Process.Args,
|
||||
Env: r.Process.Env,
|
||||
Cwd: r.Process.Cwd,
|
||||
}
|
||||
|
||||
if r.Process.User != nil {
|
||||
er.User.Uid = r.Process.User.Uid
|
||||
er.User.Gid = r.Process.User.Gid
|
||||
er.User.AdditionalGids = r.Process.User.AdditionalGids
|
||||
}
|
||||
|
||||
resp, err := client.Exec(ctx, er)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to exec into container %q", r.ContainerID)
|
||||
}
|
||||
r.Process.Pid = resp.Pid
|
||||
return &executionapi.StartProcessResponse{
|
||||
Process: r.Process,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// containerd managed execs + system pids forked in container
|
||||
func (s *Service) GetProcess(ctx context.Context, r *executionapi.GetProcessRequest) (*executionapi.GetProcessResponse, error) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (s *Service) SignalProcess(ctx context.Context, r *executionapi.SignalProcessRequest) (*google_protobuf.Empty, error) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (s *Service) DeleteProcess(ctx context.Context, r *executionapi.DeleteProcessRequest) (*google_protobuf.Empty, error) {
|
||||
client, err := s.getShim(r.ContainerID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = client.Delete(ctx, &shim.DeleteRequest{
|
||||
Pid: r.Pid,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if r.Pid == client.initPid {
|
||||
s.removeShim(r.ContainerID)
|
||||
}
|
||||
return empty, nil
|
||||
}
|
||||
|
||||
func (s *Service) ListProcesses(ctx context.Context, r *executionapi.ListProcessesRequest) (*executionapi.ListProcessesResponse, error) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
// monitor monitors the shim's event rpc and forwards container and process
|
||||
// events to callers
|
||||
func (s *Service) monitor(poster events.Poster, client *shimClient) error {
|
||||
// we use the service context here because we don't want to be
|
||||
// tied to the Create rpc call
|
||||
stream, err := client.Events(s.ctx, &shim.EventsRequest{})
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to get events stream for client at %q", client.root)
|
||||
}
|
||||
|
||||
go func() {
|
||||
for {
|
||||
e, err := stream.Recv()
|
||||
if err != nil {
|
||||
if err.Error() == "EOF" || strings.Contains(err.Error(), "transport is closing") {
|
||||
break
|
||||
}
|
||||
log.G(s.ctx).WithError(err).WithField("container", client.id).
|
||||
Warnf("event stream for client at %q got terminated", client.root)
|
||||
break
|
||||
}
|
||||
|
||||
var topic string
|
||||
if e.Type == shim.EventType_CREATE {
|
||||
topic = "containers"
|
||||
} else {
|
||||
topic = fmt.Sprintf("containers.%s", e.ID)
|
||||
}
|
||||
|
||||
ctx := events.WithTopic(s.ctx, topic)
|
||||
poster.Post(ctx, execution.ContainerEvent{
|
||||
Timestamp: time.Now(),
|
||||
ID: e.ID,
|
||||
Type: toExecutionEventType(e.Type),
|
||||
Pid: e.Pid,
|
||||
ExitStatus: e.ExitStatus,
|
||||
})
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) newShim(id string) (*shimClient, error) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if _, ok := s.shims[id]; ok {
|
||||
return nil, errors.Errorf("container %q already exists", id)
|
||||
}
|
||||
client, err := newShimClient(filepath.Join(s.root, id), id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.shims[id] = client
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func (s *Service) getShim(id string) (*shimClient, error) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
client, ok := s.shims[id]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("container does not exist %q", id)
|
||||
}
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func (s *Service) removeShim(id string) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
client, ok := s.shims[id]
|
||||
if ok {
|
||||
client.stop()
|
||||
delete(s.shims, id)
|
||||
}
|
||||
}
|
||||
|
||||
func loadClients(ctx context.Context, root string) (map[string]*shimClient, error) {
|
||||
files, err := ioutil.ReadDir(root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := make(map[string]*shimClient)
|
||||
for _, f := range files {
|
||||
if !f.IsDir() {
|
||||
continue
|
||||
}
|
||||
//
|
||||
id := f.Name()
|
||||
client, err := loadShimClient(filepath.Join(root, id), id)
|
||||
if err != nil {
|
||||
log.G(ctx).WithError(err).WithField("id", id).Warn("failed to load container")
|
||||
// TODO: send an exit event with 255 as exit status
|
||||
continue
|
||||
}
|
||||
out[f.Name()] = client
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func toExecutionEventType(et shim.EventType) string {
|
||||
return strings.Replace(strings.ToLower(et.String()), "_", "-", -1)
|
||||
}
|
|
@ -1,160 +0,0 @@
|
|||
package supervisor
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/docker/containerd/api/services/shim"
|
||||
"github.com/pkg/errors"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
)
|
||||
|
||||
func newShimClient(root, id string) (*shimClient, error) {
|
||||
if err := os.Mkdir(root, 0700); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to create shim working dir")
|
||||
}
|
||||
|
||||
cmd := exec.Command("containerd-shim")
|
||||
cmd.Dir = root
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||
Setpgid: true,
|
||||
}
|
||||
if err := cmd.Start(); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to start shim")
|
||||
}
|
||||
|
||||
socket := filepath.Join(root, "shim.sock")
|
||||
sc, err := connectToShim(socket)
|
||||
if err != nil {
|
||||
syscall.Kill(cmd.Process.Pid, syscall.SIGKILL)
|
||||
cmd.Wait()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s := &shimClient{
|
||||
ShimClient: sc,
|
||||
shimCmd: cmd,
|
||||
syncCh: make(chan struct{}),
|
||||
root: root,
|
||||
id: id,
|
||||
}
|
||||
go func() {
|
||||
cmd.Wait()
|
||||
close(s.syncCh)
|
||||
}()
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func loadShimClient(root, id string) (*shimClient, error) {
|
||||
socket := filepath.Join(root, "shim.sock")
|
||||
client, err := connectToShim(socket)
|
||||
if err != nil {
|
||||
// TODO: failed to connect to the shim, check if it's alive
|
||||
// - if it is kill it
|
||||
// - in both case call runc killall and runc delete on the id
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := client.State(context.Background(), &shim.StateRequest{})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to fetch state for container %s", id)
|
||||
}
|
||||
|
||||
return &shimClient{
|
||||
ShimClient: client,
|
||||
root: root,
|
||||
id: id,
|
||||
initPid: resp.InitPid,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type shimClient struct {
|
||||
shim.ShimClient
|
||||
shimCmd *exec.Cmd
|
||||
syncCh chan struct{}
|
||||
root string
|
||||
id string
|
||||
initPid uint32
|
||||
}
|
||||
|
||||
func (s *shimClient) stop() {
|
||||
if s.shimCmd != nil {
|
||||
select {
|
||||
case <-s.syncCh:
|
||||
default:
|
||||
syscall.Kill(s.shimCmd.Process.Pid, syscall.SIGTERM)
|
||||
select {
|
||||
case <-s.syncCh:
|
||||
case <-time.After(10 * time.Second):
|
||||
syscall.Kill(s.shimCmd.Process.Pid, syscall.SIGKILL)
|
||||
}
|
||||
}
|
||||
}
|
||||
os.RemoveAll(s.root)
|
||||
}
|
||||
|
||||
func (s *shimClient) readRuntimeLogEntries(lastEntries int) ([]map[string]interface{}, error) {
|
||||
f, err := os.Open(filepath.Join(s.root, "log.json"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
return parseRuntimeLog(f, lastEntries)
|
||||
}
|
||||
|
||||
// parseRuntimeLog parses log.json.
|
||||
// If lastEntries is greater than 0, only some last entries are returned.
|
||||
func parseRuntimeLog(r io.Reader, lastEntries int) ([]map[string]interface{}, error) {
|
||||
b, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lines := strings.Split(string(b), "\n")
|
||||
if lastEntries > 0 {
|
||||
lines = lines[len(lines)-lastEntries-1 : len(lines)]
|
||||
}
|
||||
var entries []map[string]interface{}
|
||||
for _, line := range lines {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
var entry map[string]interface{}
|
||||
if err := json.Unmarshal([]byte(line), &entry); err != nil {
|
||||
return nil, errors.Wrapf(err, "cannot unmarshal JSON string %q", line)
|
||||
}
|
||||
entries = append(entries, entry)
|
||||
}
|
||||
return entries, nil
|
||||
}
|
||||
|
||||
func connectToShim(socket string) (shim.ShimClient, error) {
|
||||
// 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(100 * time.Second)}
|
||||
dialOpts = append(dialOpts,
|
||||
grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) {
|
||||
return net.DialTimeout("unix", socket, timeout)
|
||||
}),
|
||||
grpc.WithBlock(),
|
||||
grpc.WithTimeout(2*time.Second),
|
||||
)
|
||||
conn, err := grpc.Dial(fmt.Sprintf("unix://%s", socket), dialOpts...)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to connect to shim via \"%s\"", fmt.Sprintf("unix://%s", socket))
|
||||
}
|
||||
return shim.NewShimClient(conn), nil
|
||||
}
|
Loading…
Reference in a new issue