Merge pull request #894 from dmcgowan/container-metadata-service
[carry #859] api/services: define the container metadata service
This commit is contained in:
commit
c00d731cc2
2206
api/services/containers/containers.pb.go
Normal file
2206
api/services/containers/containers.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
116
api/services/containers/containers.proto
Normal file
116
api/services/containers/containers.proto
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.v1;
|
||||||
|
|
||||||
|
import "gogoproto/gogo.proto";
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
import "google/protobuf/empty.proto";
|
||||||
|
import "google/protobuf/field_mask.proto";
|
||||||
|
import "github.com/containerd/containerd/api/types/descriptor/descriptor.proto";
|
||||||
|
|
||||||
|
// Containers provides metadata storage for containers used in the execution
|
||||||
|
// service.
|
||||||
|
//
|
||||||
|
// The objects here provide an state-independent view of containers for use in
|
||||||
|
// management and resource pinning. From that perspective, contaienrs do not
|
||||||
|
// have a "state" but rather this is the set of resources that will be
|
||||||
|
// considered in use by the container.
|
||||||
|
//
|
||||||
|
// From the perspective of the execution service, these objects represent the
|
||||||
|
// base parameters for creating a container process.
|
||||||
|
//
|
||||||
|
// In general, when looking to add fields for this type, first ask yourself
|
||||||
|
// whether or not the function of the field has to do with runtime execution or
|
||||||
|
// is invariant of the runtime state of the container. If it has to do with
|
||||||
|
// runtime, or changes as the "container" is started and stops, it probably
|
||||||
|
// doesn't belong on this object.
|
||||||
|
service Containers {
|
||||||
|
rpc Get(GetContainerRequest) returns (GetContainerResponse);
|
||||||
|
rpc List(ListContainersRequest) returns (ListContainersResponse);
|
||||||
|
rpc Create(CreateContainerRequest) returns (CreateContainerResponse);
|
||||||
|
rpc Update(UpdateContainerRequest) returns (UpdateContainerResponse);
|
||||||
|
rpc Delete(DeleteContainerRequest) returns (google.protobuf.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
message Container {
|
||||||
|
// ID is the user-specified identifier.
|
||||||
|
//
|
||||||
|
// This field may not be updated.
|
||||||
|
string id = 1;
|
||||||
|
|
||||||
|
// Labels provides an area to include arbitrary data on containers.
|
||||||
|
//
|
||||||
|
// Note that to add a new value to this field, read the existing set and
|
||||||
|
// include the entire result in the update call.
|
||||||
|
map<string, string> labels = 2;
|
||||||
|
|
||||||
|
// Image contains the reference of the image used to build the
|
||||||
|
// specification and snapshots for running this container.
|
||||||
|
//
|
||||||
|
// If this field is updated, the spec and rootfs needed to updated, as well.
|
||||||
|
string image = 3;
|
||||||
|
|
||||||
|
// Runtime specifies which runtime to use for executing this container.
|
||||||
|
string runtime = 4;
|
||||||
|
|
||||||
|
// Spec to be used when creating the container. This is runtime specific.
|
||||||
|
google.protobuf.Any spec = 6;
|
||||||
|
|
||||||
|
// RootFS specifies the snapshot key to use for the container's root
|
||||||
|
// filesystem. When starting a task from this container, a caller should
|
||||||
|
// look up the mounts from the snapshot service and include those on the
|
||||||
|
// task create request.
|
||||||
|
//
|
||||||
|
// Snapshots referenced in this field will not be garbage collected.
|
||||||
|
//
|
||||||
|
// This field may be updated.
|
||||||
|
string rootfs = 7 [(gogoproto.customname) = "RootFS"];
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetContainerRequest {
|
||||||
|
string id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetContainerResponse {
|
||||||
|
Container container = 1 [(gogoproto.nullable) = false];
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListContainersRequest {
|
||||||
|
string filter = 1; // TODO(stevvooe): Define a filtering syntax to make these queries.
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListContainersResponse {
|
||||||
|
repeated Container containers = 1 [(gogoproto.nullable) = false];
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateContainerRequest {
|
||||||
|
Container container = 1 [(gogoproto.nullable) = false];
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateContainerResponse {
|
||||||
|
Container container = 1 [(gogoproto.nullable) = false];
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateContainerRequest updates the metadata on one or more container.
|
||||||
|
//
|
||||||
|
// The operation should follow semantics described in
|
||||||
|
// https://developers.google.com/protocol-buffers/docs/reference/csharp/class/google/protobuf/well-known-types/field-mask,
|
||||||
|
// unless otherwise qualified.
|
||||||
|
message UpdateContainerRequest {
|
||||||
|
// Container provides the target values, as declared by the mask, for the update.
|
||||||
|
//
|
||||||
|
// The ID field must be set.
|
||||||
|
Container container = 1 [(gogoproto.nullable) = false];
|
||||||
|
|
||||||
|
// UpdateMask specifies which fields to perform the update on. If empty,
|
||||||
|
// the operation applies to all fields.
|
||||||
|
google.protobuf.FieldMask update_mask = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateContainerResponse {
|
||||||
|
Container container = 1 [(gogoproto.nullable) = false];
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteContainerRequest {
|
||||||
|
string id = 1;
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -1,20 +1,20 @@
|
|||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
|
|
||||||
package containerd.v1.services;
|
package containerd.v1.services.execution;
|
||||||
|
|
||||||
import "google/protobuf/empty.proto";
|
import "google/protobuf/empty.proto";
|
||||||
import "google/protobuf/any.proto";
|
import "google/protobuf/any.proto";
|
||||||
import "gogoproto/gogo.proto";
|
import "gogoproto/gogo.proto";
|
||||||
import "github.com/containerd/containerd/api/types/mount/mount.proto";
|
import "github.com/containerd/containerd/api/types/mount/mount.proto";
|
||||||
import "github.com/containerd/containerd/api/types/container/container.proto";
|
|
||||||
import "github.com/containerd/containerd/api/types/descriptor/descriptor.proto";
|
import "github.com/containerd/containerd/api/types/descriptor/descriptor.proto";
|
||||||
|
import "github.com/containerd/containerd/api/types/task/task.proto";
|
||||||
import "google/protobuf/timestamp.proto";
|
import "google/protobuf/timestamp.proto";
|
||||||
|
|
||||||
service ContainerService {
|
service Tasks {
|
||||||
rpc Create(CreateRequest) returns (CreateResponse);
|
rpc Create(CreateRequest) returns (CreateResponse);
|
||||||
rpc Start(StartRequest) returns (google.protobuf.Empty);
|
rpc Start(StartRequest) returns (google.protobuf.Empty);
|
||||||
rpc Delete(DeleteRequest) returns (DeleteResponse);
|
rpc Delete(DeleteRequest) returns (DeleteResponse);
|
||||||
rpc Info(InfoRequest) returns (containerd.v1.types.Container);
|
rpc Info(InfoRequest) returns (InfoResponse);
|
||||||
rpc List(ListRequest) returns (ListResponse);
|
rpc List(ListRequest) returns (ListResponse);
|
||||||
rpc Kill(KillRequest) returns (google.protobuf.Empty);
|
rpc Kill(KillRequest) returns (google.protobuf.Empty);
|
||||||
rpc Events(EventsRequest) returns (stream containerd.v1.types.Event);
|
rpc Events(EventsRequest) returns (stream containerd.v1.types.Event);
|
||||||
@ -28,49 +28,76 @@ service ContainerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message CreateRequest {
|
message CreateRequest {
|
||||||
string id = 1;
|
// ContainerID specifies the container to use for creating this task.
|
||||||
google.protobuf.Any spec = 2;
|
//
|
||||||
|
// The spec from the provided container id will be used to create the
|
||||||
|
// task associated with this container. Only one task can be run at a time
|
||||||
|
// per container.
|
||||||
|
//
|
||||||
|
// This should be created using the Containers service.
|
||||||
|
string container_id = 2;
|
||||||
|
|
||||||
|
// RootFS provides the pre-chroot mounts to perform in the shim before
|
||||||
|
// executing the container task.
|
||||||
|
//
|
||||||
|
// These are for mounts that cannot be performed in the user namespace.
|
||||||
|
// Typically, these mounts should be resolved from snapshots specified on
|
||||||
|
// the container object.
|
||||||
repeated containerd.v1.types.Mount rootfs = 3;
|
repeated containerd.v1.types.Mount rootfs = 3;
|
||||||
string runtime = 4;
|
|
||||||
string stdin = 5;
|
string stdin = 5;
|
||||||
string stdout = 6;
|
string stdout = 6;
|
||||||
string stderr = 7;
|
string stderr = 7;
|
||||||
bool terminal = 8;
|
bool terminal = 8;
|
||||||
|
|
||||||
types.Descriptor checkpoint = 9;
|
types.Descriptor checkpoint = 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
message CreateResponse {
|
message CreateResponse {
|
||||||
string id = 1;
|
// TODO(stevvooe): We no longer have an id for a task since they are bound
|
||||||
uint32 pid = 2;
|
// to a single container. Although, we should represent each new task with
|
||||||
|
// an ID so one can differentiate between each instance of a container
|
||||||
|
// running.
|
||||||
|
//
|
||||||
|
// Hence, we are leaving this here and reserving the field number in case
|
||||||
|
// we need to move in this direction.
|
||||||
|
// string id = 1;
|
||||||
|
|
||||||
|
string container_id = 2;
|
||||||
|
uint32 pid = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message StartRequest {
|
message StartRequest {
|
||||||
string id = 1;
|
string container_id = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message DeleteRequest {
|
message DeleteRequest {
|
||||||
string id = 1;
|
string container_id = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message DeleteResponse {
|
message DeleteResponse {
|
||||||
string id = 1;
|
string container_id = 1;
|
||||||
uint32 exit_status = 2;
|
uint32 exit_status = 2;
|
||||||
google.protobuf.Timestamp exited_at = 3 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
|
google.protobuf.Timestamp exited_at = 3 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
|
||||||
}
|
}
|
||||||
|
|
||||||
message InfoRequest {
|
message InfoRequest {
|
||||||
string id = 1;
|
string container_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message InfoResponse {
|
||||||
|
types.Task task = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ListRequest {
|
message ListRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
message ListResponse {
|
message ListResponse {
|
||||||
repeated containerd.v1.types.Container containers = 1;
|
repeated containerd.v1.types.Task tasks = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message KillRequest {
|
message KillRequest {
|
||||||
string id = 1;
|
string container_id = 1;
|
||||||
uint32 signal = 2;
|
uint32 signal = 2;
|
||||||
oneof pid_or_all {
|
oneof pid_or_all {
|
||||||
bool all = 3;
|
bool all = 3;
|
||||||
@ -82,11 +109,16 @@ message EventsRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message ExecRequest {
|
message ExecRequest {
|
||||||
string id = 1;
|
// ContainerID specifies the container in which to exec the process.
|
||||||
|
string container_id = 1;
|
||||||
bool terminal = 2;
|
bool terminal = 2;
|
||||||
string stdin = 3;
|
string stdin = 3;
|
||||||
string stdout = 4;
|
string stdout = 4;
|
||||||
string stderr = 5;
|
string stderr = 5;
|
||||||
|
|
||||||
|
// Spec for starting a process in the target container.
|
||||||
|
//
|
||||||
|
// For runc, this is a process spec, for example.
|
||||||
google.protobuf.Any spec = 6;
|
google.protobuf.Any spec = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,27 +127,27 @@ message ExecResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message PtyRequest {
|
message PtyRequest {
|
||||||
string id = 1;
|
string container_id = 1;
|
||||||
uint32 pid = 2;
|
uint32 pid = 2;
|
||||||
uint32 width = 3;
|
uint32 width = 3;
|
||||||
uint32 height = 4;
|
uint32 height = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message CloseStdinRequest {
|
message CloseStdinRequest {
|
||||||
string id = 1;
|
string container_id = 1;
|
||||||
uint32 pid = 2;
|
uint32 pid = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message PauseRequest {
|
message PauseRequest {
|
||||||
string id = 1;
|
string container_id = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ResumeRequest {
|
message ResumeRequest {
|
||||||
string id = 1;
|
string container_id = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ProcessesRequest {
|
message ProcessesRequest {
|
||||||
string id = 1;
|
string container_id = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ProcessesResponse{
|
message ProcessesResponse{
|
||||||
@ -123,7 +155,7 @@ message ProcessesResponse{
|
|||||||
}
|
}
|
||||||
|
|
||||||
message CheckpointRequest {
|
message CheckpointRequest {
|
||||||
string id = 1;
|
string container_id = 1;
|
||||||
bool allow_tcp = 2;
|
bool allow_tcp = 2;
|
||||||
bool allow_unix_sockets = 3;
|
bool allow_unix_sockets = 3;
|
||||||
bool allow_terminal = 4;
|
bool allow_terminal = 4;
|
||||||
|
@ -50,7 +50,8 @@ const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
|
|||||||
|
|
||||||
type Image struct {
|
type Image struct {
|
||||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||||
Target containerd_v1_types1.Descriptor `protobuf:"bytes,2,opt,name=target" json:"target"`
|
Labels string `protobuf:"bytes,2,opt,name=labels,proto3" json:"labels,omitempty"`
|
||||||
|
Target containerd_v1_types1.Descriptor `protobuf:"bytes,3,opt,name=target" json:"target"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Image) Reset() { *m = Image{} }
|
func (m *Image) Reset() { *m = Image{} }
|
||||||
@ -127,11 +128,11 @@ const _ = grpc.SupportPackageIsVersion4
|
|||||||
type ImagesClient interface {
|
type ImagesClient interface {
|
||||||
// Get returns an image by name.
|
// Get returns an image by name.
|
||||||
Get(ctx context.Context, in *GetRequest, opts ...grpc.CallOption) (*GetResponse, error)
|
Get(ctx context.Context, in *GetRequest, opts ...grpc.CallOption) (*GetResponse, error)
|
||||||
|
// List returns a list of all images known to containerd.
|
||||||
|
List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error)
|
||||||
// Put assigns the name to a given target image based on the provided
|
// Put assigns the name to a given target image based on the provided
|
||||||
// image.
|
// image.
|
||||||
Put(ctx context.Context, in *PutRequest, opts ...grpc.CallOption) (*google_protobuf1.Empty, error)
|
Put(ctx context.Context, in *PutRequest, opts ...grpc.CallOption) (*google_protobuf1.Empty, error)
|
||||||
// List returns a list of all images known to containerd.
|
|
||||||
List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error)
|
|
||||||
// Delete deletes the image by name.
|
// Delete deletes the image by name.
|
||||||
Delete(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*google_protobuf1.Empty, error)
|
Delete(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*google_protobuf1.Empty, error)
|
||||||
}
|
}
|
||||||
@ -153,18 +154,18 @@ func (c *imagesClient) Get(ctx context.Context, in *GetRequest, opts ...grpc.Cal
|
|||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *imagesClient) Put(ctx context.Context, in *PutRequest, opts ...grpc.CallOption) (*google_protobuf1.Empty, error) {
|
func (c *imagesClient) List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) {
|
||||||
out := new(google_protobuf1.Empty)
|
out := new(ListResponse)
|
||||||
err := grpc.Invoke(ctx, "/containerd.v1.Images/Put", in, out, c.cc, opts...)
|
err := grpc.Invoke(ctx, "/containerd.v1.Images/List", in, out, c.cc, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *imagesClient) List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) {
|
func (c *imagesClient) Put(ctx context.Context, in *PutRequest, opts ...grpc.CallOption) (*google_protobuf1.Empty, error) {
|
||||||
out := new(ListResponse)
|
out := new(google_protobuf1.Empty)
|
||||||
err := grpc.Invoke(ctx, "/containerd.v1.Images/List", in, out, c.cc, opts...)
|
err := grpc.Invoke(ctx, "/containerd.v1.Images/Put", in, out, c.cc, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -185,11 +186,11 @@ func (c *imagesClient) Delete(ctx context.Context, in *DeleteRequest, opts ...gr
|
|||||||
type ImagesServer interface {
|
type ImagesServer interface {
|
||||||
// Get returns an image by name.
|
// Get returns an image by name.
|
||||||
Get(context.Context, *GetRequest) (*GetResponse, error)
|
Get(context.Context, *GetRequest) (*GetResponse, error)
|
||||||
|
// List returns a list of all images known to containerd.
|
||||||
|
List(context.Context, *ListRequest) (*ListResponse, error)
|
||||||
// Put assigns the name to a given target image based on the provided
|
// Put assigns the name to a given target image based on the provided
|
||||||
// image.
|
// image.
|
||||||
Put(context.Context, *PutRequest) (*google_protobuf1.Empty, error)
|
Put(context.Context, *PutRequest) (*google_protobuf1.Empty, error)
|
||||||
// List returns a list of all images known to containerd.
|
|
||||||
List(context.Context, *ListRequest) (*ListResponse, error)
|
|
||||||
// Delete deletes the image by name.
|
// Delete deletes the image by name.
|
||||||
Delete(context.Context, *DeleteRequest) (*google_protobuf1.Empty, error)
|
Delete(context.Context, *DeleteRequest) (*google_protobuf1.Empty, error)
|
||||||
}
|
}
|
||||||
@ -216,24 +217,6 @@ func _Images_Get_Handler(srv interface{}, ctx context.Context, dec func(interfac
|
|||||||
return interceptor(ctx, in, info, handler)
|
return interceptor(ctx, in, info, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
func _Images_Put_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(PutRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(ImagesServer).Put(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: "/containerd.v1.Images/Put",
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(ImagesServer).Put(ctx, req.(*PutRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Images_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
func _Images_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
in := new(ListRequest)
|
in := new(ListRequest)
|
||||||
if err := dec(in); err != nil {
|
if err := dec(in); err != nil {
|
||||||
@ -252,6 +235,24 @@ func _Images_List_Handler(srv interface{}, ctx context.Context, dec func(interfa
|
|||||||
return interceptor(ctx, in, info, handler)
|
return interceptor(ctx, in, info, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func _Images_Put_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(PutRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(ImagesServer).Put(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: "/containerd.v1.Images/Put",
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(ImagesServer).Put(ctx, req.(*PutRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
func _Images_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
func _Images_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
in := new(DeleteRequest)
|
in := new(DeleteRequest)
|
||||||
if err := dec(in); err != nil {
|
if err := dec(in); err != nil {
|
||||||
@ -278,14 +279,14 @@ var _Images_serviceDesc = grpc.ServiceDesc{
|
|||||||
MethodName: "Get",
|
MethodName: "Get",
|
||||||
Handler: _Images_Get_Handler,
|
Handler: _Images_Get_Handler,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
MethodName: "Put",
|
|
||||||
Handler: _Images_Put_Handler,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
MethodName: "List",
|
MethodName: "List",
|
||||||
Handler: _Images_List_Handler,
|
Handler: _Images_List_Handler,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
MethodName: "Put",
|
||||||
|
Handler: _Images_Put_Handler,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
MethodName: "Delete",
|
MethodName: "Delete",
|
||||||
Handler: _Images_Delete_Handler,
|
Handler: _Images_Delete_Handler,
|
||||||
@ -316,8 +317,14 @@ func (m *Image) MarshalTo(dAtA []byte) (int, error) {
|
|||||||
i = encodeVarintImages(dAtA, i, uint64(len(m.Name)))
|
i = encodeVarintImages(dAtA, i, uint64(len(m.Name)))
|
||||||
i += copy(dAtA[i:], m.Name)
|
i += copy(dAtA[i:], m.Name)
|
||||||
}
|
}
|
||||||
|
if len(m.Labels) > 0 {
|
||||||
dAtA[i] = 0x12
|
dAtA[i] = 0x12
|
||||||
i++
|
i++
|
||||||
|
i = encodeVarintImages(dAtA, i, uint64(len(m.Labels)))
|
||||||
|
i += copy(dAtA[i:], m.Labels)
|
||||||
|
}
|
||||||
|
dAtA[i] = 0x1a
|
||||||
|
i++
|
||||||
i = encodeVarintImages(dAtA, i, uint64(m.Target.Size()))
|
i = encodeVarintImages(dAtA, i, uint64(m.Target.Size()))
|
||||||
n1, err := m.Target.MarshalTo(dAtA[i:])
|
n1, err := m.Target.MarshalTo(dAtA[i:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -511,6 +518,10 @@ func (m *Image) Size() (n int) {
|
|||||||
if l > 0 {
|
if l > 0 {
|
||||||
n += 1 + l + sovImages(uint64(l))
|
n += 1 + l + sovImages(uint64(l))
|
||||||
}
|
}
|
||||||
|
l = len(m.Labels)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + sovImages(uint64(l))
|
||||||
|
}
|
||||||
l = m.Target.Size()
|
l = m.Target.Size()
|
||||||
n += 1 + l + sovImages(uint64(l))
|
n += 1 + l + sovImages(uint64(l))
|
||||||
return n
|
return n
|
||||||
@ -591,6 +602,7 @@ func (this *Image) String() string {
|
|||||||
}
|
}
|
||||||
s := strings.Join([]string{`&Image{`,
|
s := strings.Join([]string{`&Image{`,
|
||||||
`Name:` + fmt.Sprintf("%v", this.Name) + `,`,
|
`Name:` + fmt.Sprintf("%v", this.Name) + `,`,
|
||||||
|
`Labels:` + fmt.Sprintf("%v", this.Labels) + `,`,
|
||||||
`Target:` + strings.Replace(strings.Replace(this.Target.String(), "Descriptor", "containerd_v1_types1.Descriptor", 1), `&`, ``, 1) + `,`,
|
`Target:` + strings.Replace(strings.Replace(this.Target.String(), "Descriptor", "containerd_v1_types1.Descriptor", 1), `&`, ``, 1) + `,`,
|
||||||
`}`,
|
`}`,
|
||||||
}, "")
|
}, "")
|
||||||
@ -722,6 +734,35 @@ func (m *Image) Unmarshal(dAtA []byte) error {
|
|||||||
m.Name = string(dAtA[iNdEx:postIndex])
|
m.Name = string(dAtA[iNdEx:postIndex])
|
||||||
iNdEx = postIndex
|
iNdEx = postIndex
|
||||||
case 2:
|
case 2:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType)
|
||||||
|
}
|
||||||
|
var stringLen uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowImages
|
||||||
|
}
|
||||||
|
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 ErrInvalidLengthImages
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + intStringLen
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.Labels = string(dAtA[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
|
case 3:
|
||||||
if wireType != 2 {
|
if wireType != 2 {
|
||||||
return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType)
|
return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType)
|
||||||
}
|
}
|
||||||
@ -1334,32 +1375,32 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var fileDescriptorImages = []byte{
|
var fileDescriptorImages = []byte{
|
||||||
// 419 bytes of a gzipped FileDescriptorProto
|
// 430 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x52, 0x4d, 0x6f, 0xd3, 0x40,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x52, 0x41, 0x6f, 0x94, 0x40,
|
||||||
0x10, 0xcd, 0x36, 0xa9, 0x25, 0xc6, 0xe4, 0xb2, 0xaa, 0x90, 0x71, 0x91, 0x6b, 0x99, 0x4b, 0xc5,
|
0x14, 0xde, 0xe9, 0x6e, 0x49, 0x7c, 0xb8, 0x97, 0x49, 0xd3, 0x20, 0x35, 0x94, 0xe0, 0xa5, 0xf1,
|
||||||
0x61, 0x0d, 0xe6, 0x02, 0x52, 0x29, 0x22, 0x2a, 0x54, 0x48, 0x1c, 0x2a, 0x1f, 0xb9, 0x39, 0xee,
|
0x30, 0x28, 0x5e, 0x34, 0xa9, 0x35, 0x6e, 0xaa, 0x8d, 0x89, 0x87, 0x86, 0x7f, 0x00, 0xf4, 0x89,
|
||||||
0x60, 0x2c, 0xd5, 0x5e, 0xe3, 0x5d, 0x57, 0xca, 0x0d, 0xfe, 0x5d, 0x8e, 0x1c, 0x39, 0x21, 0xe2,
|
0x24, 0xc0, 0x20, 0x33, 0x34, 0xe9, 0x4d, 0xff, 0xdd, 0x1e, 0x3d, 0x7a, 0x32, 0x96, 0x5f, 0x62,
|
||||||
0x5f, 0x82, 0xbc, 0xbb, 0xf9, 0x32, 0x01, 0xd2, 0x4b, 0x32, 0xab, 0x79, 0xef, 0xcd, 0x7b, 0xe3,
|
0x98, 0x99, 0xee, 0x6e, 0x71, 0xd5, 0xf6, 0x02, 0xef, 0xcd, 0xfb, 0xbe, 0xef, 0xbd, 0xef, 0xe5,
|
||||||
0x81, 0x37, 0x59, 0x2e, 0x3f, 0x37, 0x53, 0x96, 0xf2, 0x22, 0x4c, 0x79, 0x29, 0x93, 0xbc, 0xc4,
|
0xc1, 0xdb, 0xbc, 0x90, 0x9f, 0xbb, 0x94, 0x65, 0xbc, 0x0a, 0x33, 0x5e, 0xcb, 0xa4, 0xa8, 0xb1,
|
||||||
0xfa, 0x7a, 0xb3, 0x4c, 0xaa, 0x3c, 0x14, 0x58, 0xdf, 0xe6, 0x29, 0x8a, 0x30, 0x2f, 0x92, 0x6c,
|
0xbd, 0xd8, 0x0c, 0x93, 0xa6, 0x08, 0x05, 0xb6, 0x97, 0x45, 0x86, 0x22, 0x2c, 0xaa, 0x24, 0x5f,
|
||||||
0xf5, 0xc7, 0xaa, 0x9a, 0x4b, 0x4e, 0xc7, 0x6b, 0x30, 0xbb, 0x7d, 0xe6, 0x1e, 0x65, 0x3c, 0xe3,
|
0xfd, 0x58, 0xd3, 0x72, 0xc9, 0xe9, 0x7c, 0x0d, 0x66, 0x97, 0xcf, 0xdd, 0xbd, 0x9c, 0xe7, 0x5c,
|
||||||
0xaa, 0x13, 0x76, 0x95, 0x06, 0xb9, 0xc7, 0x19, 0xe7, 0xd9, 0x0d, 0x86, 0xea, 0x35, 0x6d, 0x3e,
|
0x55, 0xc2, 0x21, 0xd2, 0x20, 0xf7, 0x20, 0xe7, 0x3c, 0x2f, 0x31, 0x54, 0x59, 0xda, 0x7d, 0x0a,
|
||||||
0x85, 0x58, 0x54, 0x72, 0x66, 0x9a, 0x67, 0x7b, 0x99, 0x90, 0xb3, 0x0a, 0x45, 0x58, 0xf0, 0xa6,
|
0xb1, 0x6a, 0xe4, 0x95, 0x29, 0x1e, 0xdf, 0x69, 0x08, 0x79, 0xd5, 0xa0, 0x08, 0x2b, 0xde, 0xd5,
|
||||||
0x94, 0xfa, 0xd7, 0xb0, 0xdf, 0xdd, 0x81, 0x7d, 0x8d, 0x22, 0xad, 0xf3, 0x4a, 0xf2, 0x7a, 0xa3,
|
0x52, 0x7f, 0x0d, 0xfb, 0xfd, 0x3d, 0xd8, 0x17, 0x28, 0xb2, 0xb6, 0x68, 0x24, 0x6f, 0x37, 0x42,
|
||||||
0xd4, 0x3a, 0xc1, 0x47, 0x38, 0x7c, 0xdf, 0xe5, 0xa2, 0x14, 0x46, 0x65, 0x52, 0xa0, 0x43, 0x7c,
|
0xad, 0x13, 0xb4, 0xb0, 0xfb, 0x61, 0xf0, 0x45, 0x29, 0xcc, 0xea, 0xa4, 0x42, 0x87, 0xf8, 0xe4,
|
||||||
0x72, 0x7a, 0x2f, 0x56, 0x35, 0x7d, 0x05, 0x96, 0x4c, 0xea, 0x0c, 0xa5, 0x73, 0xe0, 0x93, 0x53,
|
0xe8, 0x41, 0xac, 0x62, 0xba, 0x0f, 0x56, 0x99, 0xa4, 0x58, 0x0a, 0x67, 0x47, 0xbd, 0x9a, 0x8c,
|
||||||
0x3b, 0x3a, 0x61, 0x5b, 0xa9, 0x99, 0x92, 0x67, 0x17, 0x2b, 0xcd, 0xc9, 0x68, 0xfe, 0xf3, 0x64,
|
0xbe, 0x06, 0x4b, 0x26, 0x6d, 0x8e, 0xd2, 0x99, 0xfa, 0xe4, 0xc8, 0x8e, 0x0e, 0xd9, 0xad, 0x6d,
|
||||||
0x10, 0x1b, 0x52, 0xe0, 0x03, 0x5c, 0xa2, 0x8c, 0xf1, 0x4b, 0x83, 0x42, 0xee, 0x1a, 0x10, 0xbc,
|
0x30, 0xd5, 0x96, 0x9d, 0xae, 0x7a, 0x2d, 0x66, 0xcb, 0x9f, 0x87, 0x93, 0xd8, 0x90, 0x02, 0x1f,
|
||||||
0x04, 0x5b, 0x21, 0x44, 0xc5, 0x4b, 0x81, 0xf4, 0x09, 0x1c, 0xaa, 0x25, 0x2b, 0x8c, 0x1d, 0x1d,
|
0xe0, 0x0c, 0x65, 0x8c, 0x5f, 0x3a, 0x14, 0x72, 0x5b, 0xe3, 0xe0, 0x15, 0xd8, 0x0a, 0x21, 0x1a,
|
||||||
0xf5, 0xc6, 0x29, 0xa3, 0xb1, 0x86, 0x04, 0xe7, 0x00, 0x57, 0xcd, 0x4a, 0xfc, 0xe9, 0x1e, 0x4c,
|
0x5e, 0x0b, 0xa4, 0x4f, 0x61, 0x57, 0x2d, 0x5f, 0x61, 0xec, 0x68, 0x6f, 0xd4, 0x4e, 0x19, 0x88,
|
||||||
0xe3, 0xce, 0xf0, 0xc7, 0x60, 0x7f, 0xc8, 0xc5, 0x52, 0x20, 0x98, 0xc0, 0x7d, 0xfd, 0x34, 0x56,
|
0x35, 0x24, 0x38, 0x01, 0x38, 0xef, 0x56, 0xe2, 0xcf, 0xee, 0xc0, 0x34, 0xd3, 0x19, 0xfe, 0x1c,
|
||||||
0x22, 0xb0, 0xf4, 0xf7, 0x76, 0x88, 0x3f, 0xfc, 0x8f, 0xa2, 0x41, 0x06, 0x8f, 0x61, 0x7c, 0x81,
|
0xec, 0x8f, 0x85, 0xb8, 0x11, 0x08, 0x16, 0xf0, 0x50, 0xa7, 0x66, 0x94, 0x08, 0x2c, 0x7d, 0x07,
|
||||||
0x37, 0x28, 0xf1, 0x1f, 0x91, 0xa3, 0x6f, 0x07, 0x60, 0x29, 0xb2, 0xa0, 0x67, 0x30, 0xbc, 0x44,
|
0x0e, 0xf1, 0xa7, 0xff, 0x51, 0x34, 0xc8, 0xe0, 0x09, 0xcc, 0x4f, 0xb1, 0x44, 0x89, 0xff, 0xb0,
|
||||||
0x49, 0x1f, 0xf6, 0xa4, 0xd7, 0x3b, 0x73, 0xdd, 0x5d, 0x2d, 0xe3, 0xf0, 0x05, 0x0c, 0xaf, 0x9a,
|
0x1c, 0x7d, 0xdb, 0x01, 0x4b, 0x91, 0x05, 0x3d, 0x86, 0xe9, 0x19, 0x4a, 0xfa, 0x68, 0x24, 0xbd,
|
||||||
0x3f, 0xd9, 0xeb, 0xa5, 0xb8, 0x0f, 0x98, 0xbe, 0x3f, 0xb6, 0xbc, 0x3f, 0xf6, 0xb6, 0xbb, 0x3f,
|
0xde, 0x99, 0xeb, 0x6e, 0x2b, 0x99, 0x09, 0xdf, 0xc0, 0x6c, 0x98, 0x98, 0x8e, 0x31, 0x1b, 0xae,
|
||||||
0xfa, 0x1a, 0x46, 0x5d, 0x56, 0xda, 0x57, 0xdf, 0xd8, 0x87, 0x7b, 0xbc, 0xb3, 0x67, 0x46, 0x9f,
|
0xdc, 0x83, 0xad, 0x35, 0x23, 0xf0, 0x12, 0xa6, 0xe7, 0xdd, 0x9f, 0xed, 0xd7, 0x5b, 0x75, 0xf7,
|
||||||
0x83, 0xa5, 0x83, 0xd2, 0x47, 0x3d, 0xd8, 0x56, 0xfe, 0xbf, 0x19, 0x98, 0x38, 0xf3, 0x85, 0x37,
|
0x99, 0x3e, 0x6c, 0x76, 0x73, 0xd8, 0xec, 0xdd, 0x70, 0xd8, 0xf4, 0x04, 0x2c, 0x6d, 0x94, 0x3e,
|
||||||
0xf8, 0xb1, 0xf0, 0x06, 0x5f, 0x5b, 0x8f, 0xcc, 0x5b, 0x8f, 0x7c, 0x6f, 0x3d, 0xf2, 0xab, 0xf5,
|
0x1e, 0x91, 0x6f, 0xf9, 0xff, 0x1b, 0x7f, 0xe1, 0x2c, 0xaf, 0xbd, 0xc9, 0x8f, 0x6b, 0x6f, 0xf2,
|
||||||
0xc8, 0xd4, 0x52, 0xc8, 0xe7, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x45, 0x0e, 0x92, 0xb1, 0xa2,
|
0xb5, 0xf7, 0xc8, 0xb2, 0xf7, 0xc8, 0xf7, 0xde, 0x23, 0xbf, 0x7a, 0x8f, 0xa4, 0x96, 0x42, 0xbe,
|
||||||
0x03, 0x00, 0x00,
|
0xf8, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x7b, 0xe2, 0xcf, 0xa0, 0xba, 0x03, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
@ -22,20 +22,21 @@ service Images {
|
|||||||
// Get returns an image by name.
|
// Get returns an image by name.
|
||||||
rpc Get(GetRequest) returns (GetResponse);
|
rpc Get(GetRequest) returns (GetResponse);
|
||||||
|
|
||||||
|
// List returns a list of all images known to containerd.
|
||||||
|
rpc List(ListRequest) returns (ListResponse);
|
||||||
|
|
||||||
// Put assigns the name to a given target image based on the provided
|
// Put assigns the name to a given target image based on the provided
|
||||||
// image.
|
// image.
|
||||||
rpc Put(PutRequest) returns (google.protobuf.Empty);
|
rpc Put(PutRequest) returns (google.protobuf.Empty);
|
||||||
|
|
||||||
// List returns a list of all images known to containerd.
|
|
||||||
rpc List(ListRequest) returns (ListResponse);
|
|
||||||
|
|
||||||
// Delete deletes the image by name.
|
// Delete deletes the image by name.
|
||||||
rpc Delete(DeleteRequest) returns (google.protobuf.Empty);
|
rpc Delete(DeleteRequest) returns (google.protobuf.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
message Image {
|
message Image {
|
||||||
string name = 1;
|
string name = 1;
|
||||||
types.Descriptor target = 2 [(gogoproto.nullable) = false];
|
string labels = 2;
|
||||||
|
types.Descriptor target = 3 [(gogoproto.nullable) = false];
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetRequest {
|
message GetRequest {
|
||||||
|
@ -39,7 +39,7 @@ import google_protobuf "github.com/gogo/protobuf/types"
|
|||||||
import google_protobuf1 "github.com/golang/protobuf/ptypes/empty"
|
import google_protobuf1 "github.com/golang/protobuf/ptypes/empty"
|
||||||
import _ "github.com/gogo/protobuf/gogoproto"
|
import _ "github.com/gogo/protobuf/gogoproto"
|
||||||
import containerd_v1_types "github.com/containerd/containerd/api/types/mount"
|
import containerd_v1_types "github.com/containerd/containerd/api/types/mount"
|
||||||
import containerd_v1_types1 "github.com/containerd/containerd/api/types/container"
|
import containerd_v1_types1 "github.com/containerd/containerd/api/types/task"
|
||||||
import _ "github.com/gogo/protobuf/types"
|
import _ "github.com/gogo/protobuf/types"
|
||||||
|
|
||||||
import time "time"
|
import time "time"
|
||||||
@ -4251,76 +4251,76 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var fileDescriptorShim = []byte{
|
var fileDescriptorShim = []byte{
|
||||||
// 1125 bytes of a gzipped FileDescriptorProto
|
// 1126 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0xcb, 0x72, 0xe3, 0x44,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0x4f, 0x6f, 0xe3, 0x44,
|
||||||
0x17, 0x1e, 0xd9, 0x8e, 0xc7, 0x3e, 0x1e, 0xe7, 0xd2, 0x95, 0x4a, 0x69, 0x9c, 0xff, 0x77, 0x82,
|
0x14, 0x5f, 0x27, 0x69, 0x36, 0x79, 0xd9, 0x74, 0xdb, 0x51, 0x55, 0x79, 0x53, 0x48, 0x8b, 0xa5,
|
||||||
0xaa, 0xa6, 0x70, 0x32, 0x20, 0x43, 0x66, 0x47, 0xc1, 0x22, 0x37, 0x8a, 0x81, 0x00, 0xae, 0x4e,
|
0x15, 0x69, 0x17, 0x1c, 0xe8, 0xde, 0x56, 0x70, 0xe8, 0x3f, 0xc4, 0x42, 0x81, 0x68, 0x5a, 0x4e,
|
||||||
0x58, 0x51, 0x85, 0x4b, 0x91, 0x3b, 0x76, 0x13, 0x49, 0x2d, 0xd4, 0xad, 0x4c, 0xb2, 0xe3, 0x11,
|
0x48, 0x44, 0xae, 0x33, 0x4d, 0x86, 0xda, 0x1e, 0xe3, 0x19, 0x77, 0xdb, 0x1b, 0x1f, 0x81, 0x2b,
|
||||||
0xd8, 0xf2, 0x24, 0xec, 0x59, 0x65, 0xc9, 0x0e, 0x56, 0x03, 0x93, 0xb7, 0x60, 0x47, 0xf5, 0x45,
|
0x9f, 0x84, 0x3b, 0xa7, 0x1e, 0xb9, 0xc1, 0x69, 0x61, 0xfb, 0x2d, 0xb8, 0xa1, 0xf9, 0x63, 0x27,
|
||||||
0xb2, 0x9d, 0x44, 0x76, 0xb2, 0x71, 0x9d, 0x73, 0xfa, 0xeb, 0xa3, 0x73, 0xfd, 0xda, 0xf0, 0xd9,
|
0x69, 0xeb, 0xa4, 0xbd, 0x58, 0xf3, 0xde, 0xfc, 0xe6, 0xcd, 0xfb, 0xfb, 0x1b, 0xc3, 0xe7, 0x43,
|
||||||
0x90, 0x8a, 0x51, 0x7a, 0xea, 0xfa, 0x2c, 0xec, 0xfa, 0x2c, 0x12, 0x1e, 0x8d, 0x48, 0x32, 0x98,
|
0x2a, 0x46, 0xe9, 0x89, 0xeb, 0xb3, 0xb0, 0xeb, 0xb3, 0x48, 0x78, 0x34, 0x22, 0xc9, 0x60, 0x72,
|
||||||
0x14, 0xbd, 0x98, 0x76, 0x39, 0x49, 0x2e, 0xa8, 0x4f, 0x78, 0x97, 0x8f, 0x68, 0xa8, 0x7e, 0xdc,
|
0xe9, 0xc5, 0xb4, 0xcb, 0x49, 0x72, 0x4e, 0x7d, 0xc2, 0xbb, 0x7c, 0x44, 0x43, 0xf5, 0x71, 0xe3,
|
||||||
0x38, 0x61, 0x82, 0xa1, 0xf5, 0x31, 0xd0, 0xbd, 0xf8, 0xd8, 0xcd, 0x70, 0xae, 0x84, 0xb4, 0x9e,
|
0x84, 0x09, 0x86, 0xd6, 0xc6, 0x40, 0xf7, 0xfc, 0x53, 0x37, 0xc3, 0xb9, 0x12, 0xd2, 0x7a, 0x36,
|
||||||
0x0f, 0x19, 0x1b, 0x06, 0xa4, 0xab, 0xa0, 0xa7, 0xe9, 0x59, 0xd7, 0x8b, 0xae, 0xf4, 0xbd, 0xd6,
|
0x64, 0x6c, 0x18, 0x90, 0xae, 0x82, 0x9e, 0xa4, 0xa7, 0x5d, 0x2f, 0xba, 0xd4, 0xe7, 0x5a, 0x6b,
|
||||||
0xfa, 0xed, 0x23, 0x12, 0xc6, 0x22, 0x3b, 0x5c, 0x1d, 0xb2, 0x21, 0x53, 0x62, 0x57, 0x4a, 0xc6,
|
0x37, 0xb7, 0x48, 0x18, 0x8b, 0x6c, 0x73, 0x65, 0xc8, 0x86, 0x4c, 0x2d, 0xbb, 0x72, 0x65, 0xb4,
|
||||||
0xfa, 0xe9, 0x83, 0x22, 0x15, 0x57, 0x31, 0xe1, 0xdd, 0x90, 0xa5, 0x91, 0xd0, 0xbf, 0xe6, 0xf6,
|
0x9f, 0xdd, 0xcb, 0x53, 0x71, 0x19, 0x13, 0xde, 0x0d, 0x59, 0x1a, 0x09, 0xfd, 0x35, 0xa7, 0x5f,
|
||||||
0xc1, 0x23, 0x6e, 0xe7, 0xc6, 0xb1, 0x64, 0xbc, 0x6c, 0xdc, 0x0e, 0x5b, 0xd0, 0x90, 0x70, 0xe1,
|
0x3d, 0xe0, 0xb4, 0xf0, 0xf8, 0x99, 0xfa, 0x98, 0xb3, 0xeb, 0x37, 0x9d, 0x15, 0x34, 0x24, 0x5c,
|
||||||
0x85, 0xb1, 0x06, 0x38, 0x7f, 0x96, 0xa0, 0xb9, 0x9f, 0x10, 0x4f, 0x10, 0x4c, 0x7e, 0x4a, 0x09,
|
0x78, 0x61, 0xac, 0x01, 0xce, 0x5f, 0x25, 0x68, 0xee, 0x25, 0xc4, 0x13, 0x04, 0x93, 0x9f, 0x53,
|
||||||
0x17, 0x68, 0x0d, 0x4a, 0x74, 0x60, 0x5b, 0x9b, 0x56, 0xa7, 0xbe, 0x57, 0xbd, 0x79, 0xbb, 0x51,
|
0xc2, 0x05, 0x5a, 0x85, 0x12, 0x1d, 0xd8, 0xd6, 0x86, 0xd5, 0xa9, 0xef, 0x56, 0xaf, 0xdf, 0xae,
|
||||||
0x7a, 0x7d, 0x80, 0x4b, 0x74, 0x80, 0xd6, 0xa0, 0x7a, 0x9a, 0x46, 0x83, 0x80, 0xd8, 0x25, 0x79,
|
0x97, 0x5e, 0xef, 0xe3, 0x12, 0x1d, 0xa0, 0x55, 0xa8, 0x9e, 0xa4, 0xd1, 0x20, 0x20, 0x76, 0x49,
|
||||||
0x86, 0x8d, 0x86, 0x6c, 0x78, 0x9a, 0xa4, 0x91, 0xf4, 0x6b, 0x97, 0xd5, 0x41, 0xa6, 0xa2, 0xe7,
|
0xee, 0x61, 0x23, 0x21, 0x1b, 0x1e, 0x27, 0x69, 0x24, 0xed, 0xda, 0x65, 0xb5, 0x91, 0x89, 0xe8,
|
||||||
0x50, 0x8b, 0x58, 0x3f, 0xa6, 0x17, 0x4c, 0xd8, 0x95, 0x4d, 0xab, 0x53, 0xc3, 0x4f, 0x23, 0xd6,
|
0x19, 0xd4, 0x22, 0xd6, 0x8f, 0xe9, 0x39, 0x13, 0x76, 0x65, 0xc3, 0xea, 0xd4, 0xf0, 0xe3, 0x88,
|
||||||
0x93, 0x2a, 0x6a, 0x41, 0x4d, 0x90, 0x24, 0xa4, 0x91, 0x17, 0xd8, 0x0b, 0xea, 0x28, 0xd7, 0xd1,
|
0xf5, 0xa4, 0x88, 0x5a, 0x50, 0x13, 0x24, 0x09, 0x69, 0xe4, 0x05, 0xf6, 0x82, 0xda, 0xca, 0x65,
|
||||||
0x2a, 0x2c, 0x70, 0x31, 0xa0, 0x91, 0x5d, 0x55, 0xee, 0xb4, 0x22, 0x3f, 0xcf, 0xc5, 0x80, 0xa5,
|
0xb4, 0x02, 0x0b, 0x5c, 0x0c, 0x68, 0x64, 0x57, 0x95, 0x39, 0x2d, 0xc8, 0xeb, 0xb9, 0x18, 0xb0,
|
||||||
0xc2, 0x7e, 0xaa, 0x3f, 0xaf, 0x35, 0x63, 0x27, 0x49, 0x62, 0xd7, 0x72, 0x3b, 0x49, 0x12, 0xb4,
|
0x54, 0xd8, 0x8f, 0xf5, 0xf5, 0x5a, 0x32, 0x7a, 0x92, 0x24, 0x76, 0x2d, 0xd7, 0x93, 0x24, 0x41,
|
||||||
0x03, 0xd5, 0x84, 0x31, 0x71, 0xc6, 0xed, 0xfa, 0x66, 0xb9, 0xd3, 0xd8, 0x69, 0xb9, 0xd3, 0x9d,
|
0xdb, 0x50, 0x4d, 0x18, 0x13, 0xa7, 0xdc, 0xae, 0x6f, 0x94, 0x3b, 0x8d, 0xed, 0x96, 0x3b, 0x5d,
|
||||||
0x57, 0x95, 0x73, 0xbf, 0x96, 0x15, 0xc7, 0x06, 0x89, 0xda, 0x00, 0xfe, 0x88, 0xf8, 0xe7, 0x31,
|
0x6f, 0x95, 0x2f, 0xf7, 0x1b, 0x99, 0x67, 0x6c, 0x90, 0xa8, 0x0d, 0xe0, 0x8f, 0x88, 0x7f, 0x16,
|
||||||
0xa3, 0x91, 0xb0, 0x41, 0xf9, 0x9b, 0xb0, 0xa0, 0x97, 0xb0, 0x12, 0x7b, 0x09, 0x89, 0x44, 0x7f,
|
0x33, 0x1a, 0x09, 0x1b, 0x94, 0xbd, 0x09, 0x0d, 0x7a, 0x01, 0xcb, 0xb1, 0x97, 0x90, 0x48, 0xf4,
|
||||||
0x02, 0xd6, 0x50, 0xb0, 0x65, 0x7d, 0xb0, 0x9f, 0xdb, 0x1d, 0x07, 0x16, 0xb3, 0xc2, 0xf2, 0x98,
|
0x27, 0x60, 0x0d, 0x05, 0x5b, 0xd2, 0x1b, 0x7b, 0xb9, 0xde, 0x71, 0x60, 0x31, 0x4b, 0x2c, 0x8f,
|
||||||
0x45, 0x9c, 0xa0, 0x65, 0x28, 0xc7, 0xa6, 0xb4, 0x4d, 0x2c, 0x45, 0x67, 0x11, 0x9e, 0x1d, 0x0b,
|
0x59, 0xc4, 0x09, 0x5a, 0x82, 0x72, 0x6c, 0x52, 0xdb, 0xc4, 0x72, 0xe9, 0x2c, 0xc2, 0x93, 0x23,
|
||||||
0x2f, 0x11, 0xa6, 0xf6, 0xce, 0x7b, 0xd0, 0x3c, 0x20, 0x01, 0x19, 0x37, 0xe3, 0xee, 0x15, 0x01,
|
0xe1, 0x25, 0xc2, 0xe4, 0xde, 0xf9, 0x00, 0x9a, 0xfb, 0x24, 0x20, 0xe3, 0x62, 0xdc, 0x3e, 0x22,
|
||||||
0x8b, 0x19, 0xc4, 0xb8, 0xdd, 0x80, 0x06, 0xb9, 0xa4, 0xa2, 0xcf, 0x85, 0x27, 0x52, 0x6e, 0xb0,
|
0x60, 0x31, 0x83, 0x18, 0xb3, 0xeb, 0xd0, 0x20, 0x17, 0x54, 0xf4, 0xb9, 0xf0, 0x44, 0xca, 0x0d,
|
||||||
0x20, 0x4d, 0xc7, 0xca, 0x82, 0x76, 0xa1, 0x2e, 0x35, 0x32, 0xe8, 0x7b, 0x42, 0x35, 0x4f, 0x56,
|
0x16, 0xa4, 0xea, 0x48, 0x69, 0xd0, 0x0e, 0xd4, 0xa5, 0x44, 0x06, 0x7d, 0x4f, 0xa8, 0xe2, 0xc9,
|
||||||
0x43, 0x0f, 0x86, 0x9b, 0x0d, 0x86, 0x7b, 0x92, 0x0d, 0xc6, 0x5e, 0xed, 0xfa, 0xed, 0xc6, 0x93,
|
0x6c, 0xe8, 0xc6, 0x70, 0xb3, 0xc6, 0x70, 0x8f, 0xb3, 0xc6, 0xd8, 0xad, 0x5d, 0xbd, 0x5d, 0x7f,
|
||||||
0x5f, 0xfe, 0xde, 0xb0, 0x70, 0x4d, 0x5f, 0xdb, 0x15, 0xce, 0xaf, 0x16, 0x34, 0x0e, 0x2f, 0x89,
|
0xf4, 0xeb, 0x3f, 0xeb, 0x16, 0xae, 0xe9, 0x63, 0x3b, 0xc2, 0xf9, 0xcd, 0x82, 0xc6, 0xc1, 0x05,
|
||||||
0x9f, 0xc5, 0x35, 0xd9, 0x3f, 0xab, 0xa8, 0x7f, 0xa5, 0xfb, 0xfb, 0x57, 0x2e, 0xe8, 0x5f, 0x65,
|
0xf1, 0x33, 0xbf, 0x26, 0xeb, 0x67, 0x15, 0xd5, 0xaf, 0x74, 0x77, 0xfd, 0xca, 0x05, 0xf5, 0xab,
|
||||||
0xaa, 0x7f, 0x1d, 0xa8, 0xf0, 0x98, 0xf8, 0x6a, 0x3a, 0x1a, 0x3b, 0xab, 0x77, 0xe2, 0xdd, 0x8d,
|
0x4c, 0xd5, 0xaf, 0x03, 0x15, 0x1e, 0x13, 0x5f, 0x75, 0x47, 0x63, 0x7b, 0xe5, 0x96, 0xbf, 0x3b,
|
||||||
0xae, 0xb0, 0x42, 0x38, 0x07, 0x50, 0xc5, 0x01, 0x0d, 0xa9, 0x40, 0x08, 0x2a, 0xb2, 0xad, 0x7a,
|
0xd1, 0x25, 0x56, 0x08, 0x67, 0x1f, 0xaa, 0x38, 0xa0, 0x21, 0x15, 0x08, 0x41, 0x45, 0x96, 0x55,
|
||||||
0x78, 0xb1, 0x92, 0xa5, 0x6d, 0xe4, 0x25, 0x03, 0x15, 0x4c, 0x05, 0x2b, 0x59, 0xda, 0x38, 0x3b,
|
0x37, 0x2f, 0x56, 0x6b, 0xa9, 0x1b, 0x79, 0xc9, 0x40, 0x39, 0x53, 0xc1, 0x6a, 0x2d, 0x75, 0x9c,
|
||||||
0xd3, 0x91, 0x54, 0xb0, 0x92, 0x9d, 0x4d, 0x78, 0xa6, 0x13, 0x2c, 0x6c, 0xd6, 0x11, 0x40, 0x4f,
|
0x9d, 0x6a, 0x4f, 0x2a, 0x58, 0xad, 0x9d, 0x0d, 0x78, 0xa2, 0x03, 0x2c, 0x2c, 0xd6, 0x21, 0x40,
|
||||||
0x5c, 0x15, 0x76, 0x46, 0xe6, 0xfd, 0x86, 0x0e, 0xc4, 0x48, 0x7d, 0xaa, 0x89, 0xb5, 0x22, 0xf3,
|
0x4f, 0x5c, 0x16, 0x56, 0x46, 0xc6, 0xfd, 0x86, 0x0e, 0xc4, 0x48, 0x5d, 0xd5, 0xc4, 0x5a, 0x90,
|
||||||
0x1b, 0x11, 0x3a, 0x1c, 0xe9, 0xaf, 0x35, 0xb1, 0xd1, 0x9c, 0x25, 0x68, 0x1e, 0x5e, 0x90, 0x48,
|
0xf1, 0x8d, 0x08, 0x1d, 0x8e, 0xf4, 0x6d, 0x4d, 0x6c, 0x24, 0xe7, 0x29, 0x34, 0x0f, 0xce, 0x49,
|
||||||
0xf0, 0xac, 0xf7, 0x7a, 0x16, 0xf2, 0xd6, 0x3b, 0xbf, 0x5b, 0xd0, 0x34, 0x06, 0x13, 0xd2, 0x63,
|
0x24, 0x78, 0x56, 0x7b, 0xdd, 0x0b, 0x79, 0xe9, 0x9d, 0x3f, 0x2c, 0x68, 0x1a, 0x85, 0x71, 0xe9,
|
||||||
0x37, 0xd3, 0x84, 0x58, 0x1e, 0x87, 0xf8, 0x4a, 0x16, 0x5b, 0x4d, 0x89, 0x2c, 0xf6, 0xe2, 0xce,
|
0xa1, 0x93, 0x69, 0x5c, 0x2c, 0x8f, 0x5d, 0x7c, 0x29, 0x93, 0xad, 0xba, 0x44, 0x26, 0x7b, 0x71,
|
||||||
0xfa, 0xbd, 0x4b, 0xa1, 0xc7, 0x06, 0x1b, 0x28, 0xfa, 0x04, 0xea, 0x71, 0xc2, 0x7c, 0xc2, 0x39,
|
0x7b, 0xed, 0xce, 0xa1, 0xd0, 0x6d, 0x83, 0x0d, 0x14, 0xbd, 0x82, 0x7a, 0x9c, 0x30, 0x9f, 0x70,
|
||||||
0xe1, 0xf6, 0x82, 0x5a, 0xa6, 0xff, 0xdd, 0x7b, 0xaf, 0xa7, 0x51, 0x78, 0x0c, 0x97, 0x49, 0xf5,
|
0x4e, 0xb8, 0xbd, 0xa0, 0x86, 0xe9, 0xbd, 0x3b, 0xcf, 0xf5, 0x34, 0x0a, 0x8f, 0xe1, 0x32, 0xa8,
|
||||||
0xbc, 0x94, 0xe7, 0x49, 0x2d, 0x41, 0x13, 0x13, 0x9e, 0x86, 0xb9, 0xa1, 0x29, 0xe7, 0x8a, 0xe6,
|
0x9e, 0x97, 0xf2, 0x3c, 0xa8, 0xa7, 0xd0, 0xc4, 0x84, 0xa7, 0x61, 0xae, 0x68, 0xca, 0xbe, 0xa2,
|
||||||
0x0b, 0xf0, 0x1a, 0x1a, 0x5f, 0xd1, 0x20, 0x18, 0x73, 0x51, 0x95, 0xd3, 0x61, 0x36, 0x64, 0x4d,
|
0xf9, 0x00, 0xbc, 0x86, 0xc6, 0xd7, 0x34, 0x08, 0xc6, 0x5c, 0x54, 0xe5, 0x74, 0x98, 0x35, 0x59,
|
||||||
0x6c, 0x34, 0x99, 0x99, 0x17, 0x04, 0x2a, 0xdd, 0x1a, 0x96, 0xe2, 0xdd, 0x5c, 0x9d, 0x17, 0xb0,
|
0x13, 0x1b, 0x49, 0x46, 0xe6, 0x05, 0x81, 0x0a, 0xb7, 0x86, 0xe5, 0xf2, 0x76, 0xac, 0xce, 0x73,
|
||||||
0xb2, 0x1f, 0x30, 0x4e, 0x8e, 0xe5, 0xf8, 0x15, 0xef, 0xd3, 0x36, 0x2c, 0xf7, 0xb2, 0x70, 0xe7,
|
0x58, 0xde, 0x0b, 0x18, 0x27, 0x47, 0xb2, 0xfd, 0x8a, 0xe7, 0x69, 0x0b, 0x96, 0x7a, 0x99, 0xbb,
|
||||||
0x50, 0xa0, 0xf3, 0x2d, 0xac, 0x4c, 0x60, 0x4d, 0x57, 0xa6, 0xca, 0x63, 0x3d, 0xae, 0x3c, 0xff,
|
0x73, 0x28, 0xd0, 0xf9, 0x0e, 0x96, 0x27, 0xb0, 0xa6, 0x2a, 0x53, 0xe9, 0xb1, 0x1e, 0x96, 0x9e,
|
||||||
0x5a, 0xb0, 0x32, 0xa6, 0x8c, 0xec, 0xf3, 0x08, 0x2a, 0x72, 0xf1, 0xcc, 0x62, 0x29, 0x19, 0xad,
|
0xff, 0x2c, 0x58, 0x1e, 0x53, 0x46, 0x76, 0x3d, 0x82, 0x8a, 0x1c, 0x3c, 0x33, 0x58, 0x6a, 0x8d,
|
||||||
0x43, 0xdd, 0x0b, 0x02, 0xf6, 0xa6, 0x2f, 0xfc, 0xd8, 0xe4, 0x5d, 0x53, 0x86, 0x13, 0x3f, 0x46,
|
0xd6, 0xa0, 0xee, 0x05, 0x01, 0x7b, 0xd3, 0x17, 0x7e, 0x6c, 0xe2, 0xae, 0x29, 0xc5, 0xb1, 0x1f,
|
||||||
0x1f, 0x00, 0xd2, 0x87, 0x69, 0x44, 0x2f, 0xfb, 0x9c, 0xf9, 0xe7, 0x44, 0x70, 0x55, 0x8b, 0x1a,
|
0xa3, 0x8f, 0x00, 0xe9, 0xcd, 0x34, 0xa2, 0x17, 0x7d, 0xce, 0xfc, 0x33, 0x22, 0xb8, 0xca, 0x45,
|
||||||
0x5e, 0x56, 0x27, 0xdf, 0x45, 0xf4, 0xf2, 0x58, 0xdb, 0xd1, 0x0b, 0x58, 0x34, 0xae, 0xb2, 0x0d,
|
0x0d, 0x2f, 0xa9, 0x9d, 0xef, 0x23, 0x7a, 0x71, 0xa4, 0xf5, 0xe8, 0x39, 0x2c, 0x1a, 0x53, 0xd9,
|
||||||
0xd6, 0xe4, 0xdc, 0xd4, 0xfe, 0xb2, 0x35, 0xfe, 0x3f, 0xc0, 0x19, 0x0d, 0x48, 0x3f, 0x60, 0xfe,
|
0x04, 0x6b, 0x72, 0x6e, 0x6a, 0x7b, 0xd9, 0x18, 0xbf, 0x0f, 0x70, 0x4a, 0x03, 0xd2, 0x0f, 0x98,
|
||||||
0x39, 0x37, 0x24, 0x5d, 0x97, 0x96, 0x23, 0x69, 0x40, 0x5b, 0xb0, 0xac, 0x9e, 0xc0, 0x7e, 0xe4,
|
0x7f, 0xc6, 0x0d, 0x49, 0xd7, 0xa5, 0xe6, 0x50, 0x2a, 0xd0, 0x26, 0x2c, 0xa9, 0x87, 0xaf, 0x1f,
|
||||||
0x85, 0x84, 0xc7, 0x9e, 0x4f, 0xb8, 0x5d, 0xdd, 0x2c, 0x77, 0xea, 0x78, 0x49, 0xd9, 0xbf, 0xc9,
|
0x79, 0x21, 0xe1, 0xb1, 0xe7, 0x13, 0x6e, 0x57, 0x37, 0xca, 0x9d, 0x3a, 0x7e, 0xaa, 0xf4, 0xdf,
|
||||||
0xcd, 0x72, 0x31, 0x68, 0xe8, 0x0d, 0x89, 0x61, 0x6e, 0xad, 0xec, 0xfc, 0x56, 0x87, 0xca, 0xf1,
|
0xe6, 0x6a, 0x39, 0x18, 0x34, 0xf4, 0x86, 0xc4, 0x30, 0xb7, 0x16, 0xb6, 0x7f, 0xaf, 0x43, 0xe5,
|
||||||
0x88, 0x86, 0xc8, 0x83, 0xaa, 0x26, 0x4a, 0xb4, 0xed, 0xce, 0x78, 0x9d, 0xdd, 0xa9, 0x67, 0xaa,
|
0x68, 0x44, 0x43, 0xe4, 0x41, 0x55, 0x13, 0x25, 0xda, 0x72, 0x67, 0xbc, 0xc9, 0xee, 0xd4, 0x33,
|
||||||
0xf5, 0xf2, 0x41, 0x58, 0xd3, 0xa3, 0x2f, 0x61, 0x41, 0xf1, 0x2c, 0xda, 0x9a, 0x79, 0x6b, 0x92,
|
0xd5, 0x7a, 0x71, 0x2f, 0xac, 0xa9, 0xd1, 0x57, 0xb0, 0xa0, 0x78, 0x16, 0x6d, 0xce, 0x3c, 0x35,
|
||||||
0x8b, 0x5b, 0x6b, 0x77, 0x28, 0xe7, 0x50, 0xe6, 0x25, 0xc3, 0xd5, 0x04, 0x3c, 0x27, 0xdc, 0x29,
|
0xc9, 0xc5, 0xad, 0xd5, 0x5b, 0x94, 0x73, 0x20, 0xe3, 0x92, 0xee, 0x6a, 0x02, 0x9e, 0xe3, 0xee,
|
||||||
0x22, 0x9f, 0x13, 0xee, 0x2d, 0x46, 0xff, 0x41, 0x85, 0x2b, 0xc8, 0xfc, 0x70, 0xc7, 0x1f, 0xd8,
|
0x14, 0x91, 0xcf, 0x71, 0xf7, 0x06, 0xa3, 0xff, 0xa8, 0xdc, 0x15, 0x64, 0xbe, 0xbb, 0xe3, 0x0b,
|
||||||
0x7e, 0x08, 0xd4, 0xf8, 0xff, 0x11, 0xea, 0xf9, 0x1c, 0xa3, 0x0f, 0x67, 0x5e, 0xbc, 0xbd, 0x1b,
|
0xb6, 0xee, 0x03, 0x35, 0xf6, 0x7f, 0x82, 0x7a, 0xde, 0xc7, 0xe8, 0xe3, 0x99, 0x07, 0x6f, 0xce,
|
||||||
0x2d, 0xf7, 0xa1, 0xf0, 0x71, 0xe9, 0x15, 0x03, 0xcc, 0xc9, 0x65, 0x92, 0x25, 0x0a, 0x4b, 0x7f,
|
0x46, 0xcb, 0xbd, 0x2f, 0x7c, 0x9c, 0x7a, 0xc5, 0x00, 0x73, 0x62, 0x99, 0x64, 0x89, 0xc2, 0xd4,
|
||||||
0x04, 0x55, 0xcd, 0x1e, 0x73, 0x4a, 0x3f, 0x45, 0x31, 0x85, 0xde, 0x4e, 0x00, 0xc6, 0xbb, 0x87,
|
0x1f, 0x42, 0x55, 0xb3, 0xc7, 0x9c, 0xd4, 0x4f, 0x51, 0x4c, 0xa1, 0xb5, 0x63, 0x80, 0xf1, 0xec,
|
||||||
0x66, 0xe7, 0x75, 0x67, 0x49, 0x0b, 0xbd, 0x7e, 0x01, 0x15, 0x49, 0x68, 0xa8, 0x33, 0xd3, 0xdf,
|
0xa1, 0xd9, 0x71, 0xdd, 0x1a, 0xd2, 0x42, 0xab, 0x5f, 0x42, 0x45, 0x12, 0x1a, 0xea, 0xcc, 0xb4,
|
||||||
0x04, 0xe7, 0x15, 0x7a, 0xc2, 0x50, 0xd5, 0x2f, 0xc4, 0x9c, 0x6c, 0xa7, 0x9e, 0x91, 0xd6, 0xfd,
|
0x37, 0xc1, 0x79, 0x85, 0x96, 0x30, 0x54, 0xf5, 0x0b, 0x31, 0x27, 0xda, 0xa9, 0x67, 0xa4, 0x75,
|
||||||
0xff, 0x73, 0x14, 0xe6, 0x23, 0x4b, 0x46, 0x27, 0xf9, 0x75, 0x4e, 0x74, 0x13, 0x14, 0x5c, 0x18,
|
0xf7, 0x7f, 0x8e, 0xc2, 0x7c, 0x62, 0x49, 0xef, 0x24, 0xbf, 0xce, 0xf1, 0x6e, 0x82, 0x82, 0x0b,
|
||||||
0xdd, 0xf7, 0x32, 0x4f, 0xe2, 0xcf, 0xcd, 0x33, 0xff, 0xcf, 0xd0, 0xda, 0x7a, 0x00, 0xd2, 0x0c,
|
0xbd, 0xfb, 0x41, 0xc6, 0x49, 0xfc, 0xb9, 0x71, 0xe6, 0xff, 0x0c, 0xad, 0xcd, 0x7b, 0x20, 0x4d,
|
||||||
0xcd, 0xe7, 0x50, 0xee, 0x89, 0x2b, 0xf4, 0xfe, 0xec, 0x91, 0xc9, 0x1f, 0xe3, 0x99, 0x2d, 0xce,
|
0xd3, 0x7c, 0x01, 0xe5, 0x9e, 0xb8, 0x44, 0x1f, 0xce, 0x6e, 0x99, 0xfc, 0x31, 0x9e, 0x59, 0xe2,
|
||||||
0xdf, 0x80, 0x79, 0x2d, 0xbe, 0xfd, 0x58, 0x14, 0x79, 0xdd, 0xb3, 0xaf, 0xdf, 0xb5, 0x9f, 0xfc,
|
0xfc, 0x0d, 0x98, 0x57, 0xe2, 0x9b, 0x8f, 0x45, 0x91, 0xd5, 0x5d, 0xfb, 0xea, 0x5d, 0xfb, 0xd1,
|
||||||
0xf5, 0xae, 0xfd, 0xe4, 0xe7, 0x9b, 0xb6, 0x75, 0x7d, 0xd3, 0xb6, 0xfe, 0xb8, 0x69, 0x5b, 0xff,
|
0xdf, 0xef, 0xda, 0x8f, 0x7e, 0xb9, 0x6e, 0x5b, 0x57, 0xd7, 0x6d, 0xeb, 0xcf, 0xeb, 0xb6, 0xf5,
|
||||||
0xdc, 0xb4, 0xad, 0xd3, 0xaa, 0x42, 0xbe, 0xfa, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x5d, 0x44, 0x45,
|
0xef, 0x75, 0xdb, 0x3a, 0xa9, 0x2a, 0xe4, 0xcb, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0xef, 0xf8,
|
||||||
0xe4, 0xa5, 0x0c, 0x00, 0x00,
|
0x34, 0x69, 0x9b, 0x0c, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import "google/protobuf/any.proto";
|
|||||||
import "google/protobuf/empty.proto";
|
import "google/protobuf/empty.proto";
|
||||||
import "gogoproto/gogo.proto";
|
import "gogoproto/gogo.proto";
|
||||||
import "github.com/containerd/containerd/api/types/mount/mount.proto";
|
import "github.com/containerd/containerd/api/types/mount/mount.proto";
|
||||||
import "github.com/containerd/containerd/api/types/container/container.proto";
|
import "github.com/containerd/containerd/api/types/task/task.proto";
|
||||||
import "google/protobuf/timestamp.proto";
|
import "google/protobuf/timestamp.proto";
|
||||||
|
|
||||||
// Shim service is launched for each container and is responsible for owning the IO
|
// Shim service is launched for each container and is responsible for owning the IO
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -17,11 +17,12 @@ enum Status {
|
|||||||
PAUSED = 4 [(gogoproto.enumvalue_customname) = "StatusPaused"];
|
PAUSED = 4 [(gogoproto.enumvalue_customname) = "StatusPaused"];
|
||||||
}
|
}
|
||||||
|
|
||||||
message Container {
|
message Task {
|
||||||
string id = 1;
|
string id = 1; // TODO(stevvooe): For now, this is just the container id.
|
||||||
uint32 pid = 2;
|
string container_id = 2;
|
||||||
Status status = 3;
|
uint32 pid = 3;
|
||||||
google.protobuf.Any spec = 4;
|
Status status = 4;
|
||||||
|
google.protobuf.Any spec = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Process {
|
message Process {
|
@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
// register containerd builtins here
|
// register containerd builtins here
|
||||||
import (
|
import (
|
||||||
|
_ "github.com/containerd/containerd/services/containers"
|
||||||
_ "github.com/containerd/containerd/services/content"
|
_ "github.com/containerd/containerd/services/content"
|
||||||
_ "github.com/containerd/containerd/services/diff"
|
_ "github.com/containerd/containerd/services/diff"
|
||||||
_ "github.com/containerd/containerd/services/execution"
|
_ "github.com/containerd/containerd/services/execution"
|
||||||
|
@ -17,6 +17,7 @@ import (
|
|||||||
"google.golang.org/grpc/health/grpc_health_v1"
|
"google.golang.org/grpc/health/grpc_health_v1"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
|
containersapi "github.com/containerd/containerd/api/services/containers"
|
||||||
contentapi "github.com/containerd/containerd/api/services/content"
|
contentapi "github.com/containerd/containerd/api/services/content"
|
||||||
diffapi "github.com/containerd/containerd/api/services/diff"
|
diffapi "github.com/containerd/containerd/api/services/diff"
|
||||||
api "github.com/containerd/containerd/api/services/execution"
|
api "github.com/containerd/containerd/api/services/execution"
|
||||||
@ -265,7 +266,7 @@ func resolveMetaDB(ctx *cli.Context) (*bolt.DB, error) {
|
|||||||
return db, nil
|
return db, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadRuntimes(monitor plugin.ContainerMonitor) (map[string]plugin.Runtime, error) {
|
func loadRuntimes(monitor plugin.TaskMonitor) (map[string]plugin.Runtime, error) {
|
||||||
o := make(map[string]plugin.Runtime)
|
o := make(map[string]plugin.Runtime)
|
||||||
for name, rr := range plugin.Registrations() {
|
for name, rr := range plugin.Registrations() {
|
||||||
if rr.Type != plugin.RuntimePlugin {
|
if rr.Type != plugin.RuntimePlugin {
|
||||||
@ -293,10 +294,10 @@ func loadRuntimes(monitor plugin.ContainerMonitor) (map[string]plugin.Runtime, e
|
|||||||
return o, nil
|
return o, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadMonitor() (plugin.ContainerMonitor, error) {
|
func loadMonitor() (plugin.TaskMonitor, error) {
|
||||||
var monitors []plugin.ContainerMonitor
|
var monitors []plugin.TaskMonitor
|
||||||
for name, m := range plugin.Registrations() {
|
for name, m := range plugin.Registrations() {
|
||||||
if m.Type != plugin.ContainerMonitorPlugin {
|
if m.Type != plugin.TaskMonitorPlugin {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
log.G(global).Infof("loading monitor plugin %q...", name)
|
log.G(global).Infof("loading monitor plugin %q...", name)
|
||||||
@ -309,12 +310,12 @@ func loadMonitor() (plugin.ContainerMonitor, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
monitors = append(monitors, mm.(plugin.ContainerMonitor))
|
monitors = append(monitors, mm.(plugin.TaskMonitor))
|
||||||
}
|
}
|
||||||
if len(monitors) == 0 {
|
if len(monitors) == 0 {
|
||||||
return plugin.NewNoopMonitor(), nil
|
return plugin.NewNoopMonitor(), nil
|
||||||
}
|
}
|
||||||
return plugin.NewMultiContainerMonitor(monitors...), nil
|
return plugin.NewMultiTaskMonitor(monitors...), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadSnapshotter(store content.Store) (snapshot.Snapshotter, error) {
|
func loadSnapshotter(store content.Store) (snapshot.Snapshotter, error) {
|
||||||
@ -414,8 +415,10 @@ func interceptor(ctx gocontext.Context,
|
|||||||
) (interface{}, error) {
|
) (interface{}, error) {
|
||||||
ctx = log.WithModule(ctx, "containerd")
|
ctx = log.WithModule(ctx, "containerd")
|
||||||
switch info.Server.(type) {
|
switch info.Server.(type) {
|
||||||
case api.ContainerServiceServer:
|
case api.TasksServer:
|
||||||
ctx = log.WithModule(ctx, "execution")
|
ctx = log.WithModule(ctx, "execution")
|
||||||
|
case containersapi.ContainersServer:
|
||||||
|
ctx = log.WithModule(ctx, "containers")
|
||||||
case contentapi.ContentServer:
|
case contentapi.ContentServer:
|
||||||
ctx = log.WithModule(ctx, "content")
|
ctx = log.WithModule(ctx, "content")
|
||||||
case imagesapi.ImagesServer:
|
case imagesapi.ImagesServer:
|
||||||
|
@ -46,7 +46,8 @@ var checkpointCommand = cli.Command{
|
|||||||
if id == "" {
|
if id == "" {
|
||||||
return errors.New("container id must be provided")
|
return errors.New("container id must be provided")
|
||||||
}
|
}
|
||||||
containers, err := getExecutionService(context)
|
|
||||||
|
tasks, err := getTasksService(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -59,13 +60,13 @@ var checkpointCommand = cli.Command{
|
|||||||
return errors.Wrap(err, "failed resolving image store")
|
return errors.Wrap(err, "failed resolving image store")
|
||||||
}
|
}
|
||||||
var spec specs.Spec
|
var spec specs.Spec
|
||||||
info, err := containers.Info(ctx, &execution.InfoRequest{
|
info, err := tasks.Info(ctx, &execution.InfoRequest{
|
||||||
ID: id,
|
ContainerID: id,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal(info.Spec.Value, &spec); err != nil {
|
if err := json.Unmarshal(info.Task.Spec.Value, &spec); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
stopped := context.Bool("exit")
|
stopped := context.Bool("exit")
|
||||||
@ -73,21 +74,21 @@ var checkpointCommand = cli.Command{
|
|||||||
// we pause the container and give us time to checkpoint the filesystem before
|
// we pause the container and give us time to checkpoint the filesystem before
|
||||||
// it resumes execution
|
// it resumes execution
|
||||||
if !stopped {
|
if !stopped {
|
||||||
if _, err := containers.Pause(ctx, &execution.PauseRequest{
|
if _, err := tasks.Pause(ctx, &execution.PauseRequest{
|
||||||
ID: id,
|
ContainerID: id,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if _, err := containers.Resume(ctx, &execution.ResumeRequest{
|
if _, err := tasks.Resume(ctx, &execution.ResumeRequest{
|
||||||
ID: id,
|
ContainerID: id,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
logrus.WithError(err).Error("ctr: unable to resume container")
|
logrus.WithError(err).Error("ctr: unable to resume container")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
checkpoint, err := containers.Checkpoint(ctx, &execution.CheckpointRequest{
|
checkpoint, err := tasks.Checkpoint(ctx, &execution.CheckpointRequest{
|
||||||
ID: id,
|
ContainerID: id,
|
||||||
Exit: context.Bool("exit"),
|
Exit: context.Bool("exit"),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -3,6 +3,10 @@ package main
|
|||||||
import (
|
import (
|
||||||
gocontext "context"
|
gocontext "context"
|
||||||
|
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
|
||||||
|
containersapi "github.com/containerd/containerd/api/services/containers"
|
||||||
"github.com/containerd/containerd/api/services/execution"
|
"github.com/containerd/containerd/api/services/execution"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
@ -13,10 +17,15 @@ var deleteCommand = cli.Command{
|
|||||||
Usage: "delete an existing container",
|
Usage: "delete an existing container",
|
||||||
ArgsUsage: "CONTAINER",
|
ArgsUsage: "CONTAINER",
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
containers, err := getExecutionService(context)
|
containers, err := getContainersService(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
tasks, err := getTasksService(context)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
snapshotter, err := getSnapshotter(context)
|
snapshotter, err := getSnapshotter(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -26,13 +35,24 @@ var deleteCommand = cli.Command{
|
|||||||
return errors.New("container id must be provided")
|
return errors.New("container id must be provided")
|
||||||
}
|
}
|
||||||
ctx := gocontext.TODO()
|
ctx := gocontext.TODO()
|
||||||
_, err = containers.Delete(ctx, &execution.DeleteRequest{
|
_, err = containers.Delete(ctx, &containersapi.DeleteContainerRequest{
|
||||||
ID: id,
|
ID: id,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to delete container")
|
return errors.Wrap(err, "failed to delete container")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, err = tasks.Delete(ctx, &execution.DeleteRequest{
|
||||||
|
ContainerID: id,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
// Ignore error if task has already been removed, task is
|
||||||
|
// removed by default after run
|
||||||
|
if grpc.Code(errors.Cause(err)) != codes.NotFound {
|
||||||
|
return errors.Wrap(err, "failed to task container")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := snapshotter.Remove(ctx, id); err != nil {
|
if err := snapshotter.Remove(ctx, id); err != nil {
|
||||||
return errors.Wrapf(err, "failed to remove snapshot %q", id)
|
return errors.Wrapf(err, "failed to remove snapshot %q", id)
|
||||||
}
|
}
|
||||||
|
@ -14,11 +14,11 @@ var eventsCommand = cli.Command{
|
|||||||
Name: "events",
|
Name: "events",
|
||||||
Usage: "display containerd events",
|
Usage: "display containerd events",
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
containers, err := getExecutionService(context)
|
tasks, err := getTasksService(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
events, err := containers.Events(gocontext.Background(), &execution.EventsRequest{})
|
events, err := tasks.Events(gocontext.Background(), &execution.EventsRequest{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -37,11 +37,11 @@ var execCommand = cli.Command{
|
|||||||
return errors.New("container id must be provided")
|
return errors.New("container id must be provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
containers, err := getExecutionService(context)
|
tasks, err := getTasksService(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
events, err := containers.Events(ctx, &execution.EventsRequest{})
|
events, err := tasks.Events(ctx, &execution.EventsRequest{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -66,12 +66,12 @@ var execCommand = cli.Command{
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
response, err := containers.Exec(ctx, request)
|
response, err := tasks.Exec(ctx, request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if request.Terminal {
|
if request.Terminal {
|
||||||
if err := handleConsoleResize(ctx, containers, id, response.Pid, con); err != nil {
|
if err := handleConsoleResize(ctx, tasks, id, response.Pid, con); err != nil {
|
||||||
logrus.WithError(err).Error("console resize")
|
logrus.WithError(err).Error("console resize")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ func newExecRequest(context *cli.Context, tmpDir, id string) (*execution.ExecReq
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &execution.ExecRequest{
|
return &execution.ExecRequest{
|
||||||
ID: id,
|
ContainerID: id,
|
||||||
Spec: &protobuf.Any{
|
Spec: &protobuf.Any{
|
||||||
TypeUrl: specs.Version,
|
TypeUrl: specs.Version,
|
||||||
Value: data,
|
Value: data,
|
||||||
|
@ -23,7 +23,7 @@ func newExecRequest(context *cli.Context, tmpDir, id string) (*execution.ExecReq
|
|||||||
}
|
}
|
||||||
now := time.Now().UnixNano()
|
now := time.Now().UnixNano()
|
||||||
request := &execution.ExecRequest{
|
request := &execution.ExecRequest{
|
||||||
ID: id,
|
ContainerID: id,
|
||||||
Spec: &protobuf.Any{
|
Spec: &protobuf.Any{
|
||||||
TypeUrl: specs.Version,
|
TypeUrl: specs.Version,
|
||||||
Value: data,
|
Value: data,
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
gocontext "context"
|
gocontext "context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
containersapi "github.com/containerd/containerd/api/services/containers"
|
||||||
"github.com/containerd/containerd/api/services/execution"
|
"github.com/containerd/containerd/api/services/execution"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
@ -26,11 +27,30 @@ var infoCommand = cli.Command{
|
|||||||
return errors.New("container id must be provided")
|
return errors.New("container id must be provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
containers, err := getExecutionService(context)
|
containers, err := getContainersService(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
response, err := containers.Info(gocontext.Background(), &execution.InfoRequest{ID: id})
|
tasks, err := getTasksService(context)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
containerResponse, err := containers.Get(gocontext.TODO(), &containersapi.GetContainerRequest{ID: id})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(stevvooe): Just dumping the container and the task, for now. We
|
||||||
|
// should split this into two separate commands.
|
||||||
|
cjson, err := json.MarshalIndent(containerResponse, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(string(cjson))
|
||||||
|
|
||||||
|
response, err := tasks.Info(gocontext.Background(), &execution.InfoRequest{ContainerID: id})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ var killCommand = cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
killRequest := &execution.KillRequest{
|
killRequest := &execution.KillRequest{
|
||||||
ID: id,
|
ContainerID: id,
|
||||||
Signal: uint32(signal),
|
Signal: uint32(signal),
|
||||||
PidOrAll: &execution.KillRequest_Pid{
|
PidOrAll: &execution.KillRequest_Pid{
|
||||||
Pid: uint32(pid),
|
Pid: uint32(pid),
|
||||||
@ -62,11 +62,11 @@ var killCommand = cli.Command{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
containers, err := getExecutionService(context)
|
tasks, err := getTasksService(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = containers.Kill(gocontext.Background(), killRequest)
|
_, err = tasks.Kill(gocontext.Background(), killRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,16 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
|
||||||
|
containersapi "github.com/containerd/containerd/api/services/containers"
|
||||||
"github.com/containerd/containerd/api/services/execution"
|
"github.com/containerd/containerd/api/services/execution"
|
||||||
|
tasktypes "github.com/containerd/containerd/api/types/task"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var containersCommand = cli.Command{
|
||||||
|
Name: "containers",
|
||||||
|
}
|
||||||
|
|
||||||
var listCommand = cli.Command{
|
var listCommand = cli.Command{
|
||||||
Name: "list",
|
Name: "list",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
@ -22,11 +28,18 @@ var listCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
quiet := context.Bool("quiet")
|
quiet := context.Bool("quiet")
|
||||||
containers, err := getExecutionService(context)
|
|
||||||
|
tasks, err := getTasksService(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
response, err := containers.List(gocontext.Background(), &execution.ListRequest{})
|
|
||||||
|
containers, err := getContainersService(context)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := containers.List(gocontext.Background(), &containersapi.ListContainersRequest{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -36,13 +49,40 @@ var listCommand = cli.Command{
|
|||||||
fmt.Println(c.ID)
|
fmt.Println(c.ID)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
tasksResponse, err := tasks.List(gocontext.TODO(), &execution.ListRequest{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Join with tasks to get status.
|
||||||
|
tasksByContainerID := map[string]*tasktypes.Task{}
|
||||||
|
for _, task := range tasksResponse.Tasks {
|
||||||
|
task.Descriptor()
|
||||||
|
tasksByContainerID[task.ContainerID] = task
|
||||||
|
}
|
||||||
|
|
||||||
w := tabwriter.NewWriter(os.Stdout, 10, 1, 3, ' ', 0)
|
w := tabwriter.NewWriter(os.Stdout, 10, 1, 3, ' ', 0)
|
||||||
fmt.Fprintln(w, "ID\tPID\tSTATUS")
|
fmt.Fprintln(w, "ID\tIMAGE\tPID\tSTATUS")
|
||||||
for _, c := range response.Containers {
|
for _, c := range response.Containers {
|
||||||
if _, err := fmt.Fprintf(w, "%s\t%d\t%s\n",
|
var (
|
||||||
|
status string
|
||||||
|
pid uint32
|
||||||
|
)
|
||||||
|
task, ok := tasksByContainerID[c.ID]
|
||||||
|
if ok {
|
||||||
|
status = task.Status.String()
|
||||||
|
pid = task.Pid
|
||||||
|
} else {
|
||||||
|
status = "STOPPED" // TODO(stevvooe): Is this assumption correct?
|
||||||
|
pid = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := fmt.Fprintf(w, "%s\t%s\t%d\t%s\n",
|
||||||
c.ID,
|
c.ID,
|
||||||
c.Pid,
|
c.Image,
|
||||||
c.Status.String(),
|
pid,
|
||||||
|
status,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ var pauseCommand = cli.Command{
|
|||||||
Usage: "pause an existing container",
|
Usage: "pause an existing container",
|
||||||
ArgsUsage: "CONTAINER",
|
ArgsUsage: "CONTAINER",
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
containers, err := getExecutionService(context)
|
tasks, err := getTasksService(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -21,8 +21,8 @@ var pauseCommand = cli.Command{
|
|||||||
if id == "" {
|
if id == "" {
|
||||||
return errors.New("container id must be provided")
|
return errors.New("container id must be provided")
|
||||||
}
|
}
|
||||||
_, err = containers.Pause(gocontext.Background(), &execution.PauseRequest{
|
_, err = tasks.Pause(gocontext.Background(), &execution.PauseRequest{
|
||||||
ID: id,
|
ContainerID: id,
|
||||||
})
|
})
|
||||||
return err
|
return err
|
||||||
},
|
},
|
||||||
|
@ -27,15 +27,15 @@ var psCommand = cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
pr := &execution.ProcessesRequest{
|
pr := &execution.ProcessesRequest{
|
||||||
ID: id,
|
ContainerID: id,
|
||||||
}
|
}
|
||||||
|
|
||||||
containers, err := getExecutionService(context)
|
tasks, err := getTasksService(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := containers.Processes(gocontext.Background(), pr)
|
resp, err := tasks.Processes(gocontext.Background(), pr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ var resumeCommand = cli.Command{
|
|||||||
Usage: "resume a paused container",
|
Usage: "resume a paused container",
|
||||||
ArgsUsage: "CONTAINER",
|
ArgsUsage: "CONTAINER",
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
containers, err := getExecutionService(context)
|
tasks, err := getTasksService(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -21,8 +21,8 @@ var resumeCommand = cli.Command{
|
|||||||
if id == "" {
|
if id == "" {
|
||||||
return errors.New("container id must be provided")
|
return errors.New("container id must be provided")
|
||||||
}
|
}
|
||||||
_, err = containers.Resume(gocontext.Background(), &execution.ResumeRequest{
|
_, err = tasks.Resume(gocontext.Background(), &execution.ResumeRequest{
|
||||||
ID: id,
|
ContainerID: id,
|
||||||
})
|
})
|
||||||
return err
|
return err
|
||||||
},
|
},
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/containerd/console"
|
"github.com/containerd/console"
|
||||||
|
containersapi "github.com/containerd/containerd/api/services/containers"
|
||||||
"github.com/containerd/containerd/api/services/execution"
|
"github.com/containerd/containerd/api/services/execution"
|
||||||
"github.com/containerd/containerd/images"
|
"github.com/containerd/containerd/images"
|
||||||
"github.com/containerd/containerd/mount"
|
"github.com/containerd/containerd/mount"
|
||||||
@ -80,7 +81,11 @@ var runCommand = cli.Command{
|
|||||||
if id == "" {
|
if id == "" {
|
||||||
return errors.New("container id must be provided")
|
return errors.New("container id must be provided")
|
||||||
}
|
}
|
||||||
containers, err := getExecutionService(context)
|
containers, err := getContainersService(context)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
tasks, err := getTasksService(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -89,7 +94,7 @@ var runCommand = cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer os.RemoveAll(tmpDir)
|
defer os.RemoveAll(tmpDir)
|
||||||
events, err := containers.Events(ctx, &execution.EventsRequest{})
|
events, err := tasks.Events(ctx, &execution.EventsRequest{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -227,11 +232,22 @@ var runCommand = cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(spec) == 0 {
|
if len(spec) == 0 {
|
||||||
if spec, err = newSpec(context, &imageConfig.Config, ref); err != nil {
|
if spec, err = newContainerSpec(context, &imageConfig.Config, ref); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
create, err := newCreateRequest(context, id, tmpDir, checkpoint, mounts, spec)
|
|
||||||
|
createContainer, err := newCreateContainerRequest(context, id, id, spec)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = containers.Create(ctx, createContainer)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
create, err := newCreateTaskRequest(context, id, tmpDir, checkpoint, mounts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -247,22 +263,22 @@ var runCommand = cli.Command{
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
response, err := containers.Create(ctx, create)
|
response, err := tasks.Create(ctx, create)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
pid := response.Pid
|
pid := response.Pid
|
||||||
if create.Terminal {
|
if create.Terminal {
|
||||||
if err := handleConsoleResize(ctx, containers, id, pid, con); err != nil {
|
if err := handleConsoleResize(ctx, tasks, id, pid, con); err != nil {
|
||||||
logrus.WithError(err).Error("console resize")
|
logrus.WithError(err).Error("console resize")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sigc := forwardAllSignals(containers, id)
|
sigc := forwardAllSignals(tasks, id)
|
||||||
defer stopCatch(sigc)
|
defer stopCatch(sigc)
|
||||||
}
|
}
|
||||||
if checkpoint == nil {
|
if checkpoint == nil {
|
||||||
if _, err := containers.Start(ctx, &execution.StartRequest{
|
if _, err := tasks.Start(ctx, &execution.StartRequest{
|
||||||
ID: id,
|
ContainerID: id,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -274,11 +290,16 @@ var runCommand = cli.Command{
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := containers.Delete(ctx, &execution.DeleteRequest{
|
if _, err := tasks.Delete(ctx, &execution.DeleteRequest{
|
||||||
ID: response.ID,
|
ContainerID: response.ContainerID,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if context.Bool("rm") {
|
||||||
|
if _, err := containers.Delete(ctx, &containersapi.DeleteContainerRequest{ID: id}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
if status != 0 {
|
if status != 0 {
|
||||||
return cli.NewExitError("", int(status))
|
return cli.NewExitError("", int(status))
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import (
|
|||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/containerd/console"
|
"github.com/containerd/console"
|
||||||
|
containersapi "github.com/containerd/containerd/api/services/containers"
|
||||||
"github.com/containerd/containerd/api/services/execution"
|
"github.com/containerd/containerd/api/services/execution"
|
||||||
"github.com/containerd/containerd/api/types/descriptor"
|
"github.com/containerd/containerd/api/types/descriptor"
|
||||||
"github.com/containerd/containerd/api/types/mount"
|
"github.com/containerd/containerd/api/types/mount"
|
||||||
@ -265,7 +266,7 @@ func getConfig(context *cli.Context, imageConfig *ocispec.ImageConfig, rootfs st
|
|||||||
return customSpec(config, rootfs)
|
return customSpec(config, rootfs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSpec(context *cli.Context, config *ocispec.ImageConfig, imageRef string) ([]byte, error) {
|
func newContainerSpec(context *cli.Context, config *ocispec.ImageConfig, imageRef string) ([]byte, error) {
|
||||||
s, err := getConfig(context, config, context.String("rootfs"))
|
s, err := getConfig(context, config, context.String("rootfs"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -277,26 +278,31 @@ func newSpec(context *cli.Context, config *ocispec.ImageConfig, imageRef string)
|
|||||||
return json.Marshal(s)
|
return json.Marshal(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newCreateRequest(context *cli.Context, id, tmpDir string, checkpoint *ocispec.Descriptor, mounts []mountt.Mount, spec []byte) (*execution.CreateRequest, error) {
|
func newCreateContainerRequest(context *cli.Context, id, snapshot string, spec []byte) (*containersapi.CreateContainerRequest, error) {
|
||||||
create := &execution.CreateRequest{
|
create := &containersapi.CreateContainerRequest{
|
||||||
|
Container: containersapi.Container{
|
||||||
ID: id,
|
ID: id,
|
||||||
Spec: &protobuf.Any{
|
Spec: &protobuf.Any{
|
||||||
TypeUrl: specs.Version,
|
TypeUrl: specs.Version,
|
||||||
Value: spec,
|
Value: spec,
|
||||||
},
|
},
|
||||||
Runtime: context.String("runtime"),
|
Runtime: context.String("runtime"),
|
||||||
|
RootFS: snapshot,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return create, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newCreateTaskRequest(context *cli.Context, id, tmpDir string, checkpoint *ocispec.Descriptor, mounts []mountt.Mount) (*execution.CreateRequest, error) {
|
||||||
|
create := &execution.CreateRequest{
|
||||||
|
ContainerID: id,
|
||||||
Terminal: context.Bool("tty"),
|
Terminal: context.Bool("tty"),
|
||||||
Stdin: filepath.Join(tmpDir, "stdin"),
|
Stdin: filepath.Join(tmpDir, "stdin"),
|
||||||
Stdout: filepath.Join(tmpDir, "stdout"),
|
Stdout: filepath.Join(tmpDir, "stdout"),
|
||||||
Stderr: filepath.Join(tmpDir, "stderr"),
|
Stderr: filepath.Join(tmpDir, "stderr"),
|
||||||
}
|
}
|
||||||
if checkpoint != nil {
|
|
||||||
create.Checkpoint = &descriptor.Descriptor{
|
|
||||||
MediaType: checkpoint.MediaType,
|
|
||||||
Size_: checkpoint.Size,
|
|
||||||
Digest: checkpoint.Digest,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, m := range mounts {
|
for _, m := range mounts {
|
||||||
create.Rootfs = append(create.Rootfs, &mount.Mount{
|
create.Rootfs = append(create.Rootfs, &mount.Mount{
|
||||||
Type: m.Type,
|
Type: m.Type,
|
||||||
@ -304,17 +310,26 @@ func newCreateRequest(context *cli.Context, id, tmpDir string, checkpoint *ocisp
|
|||||||
Options: m.Options,
|
Options: m.Options,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if checkpoint != nil {
|
||||||
|
create.Checkpoint = &descriptor.Descriptor{
|
||||||
|
MediaType: checkpoint.MediaType,
|
||||||
|
Size_: checkpoint.Size,
|
||||||
|
Digest: checkpoint.Digest,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return create, nil
|
return create, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleConsoleResize(ctx context.Context, service execution.ContainerServiceClient, id string, pid uint32, con console.Console) error {
|
func handleConsoleResize(ctx context.Context, service execution.TasksClient, id string, pid uint32, con console.Console) error {
|
||||||
// do an initial resize of the console
|
// do an initial resize of the console
|
||||||
size, err := con.Size()
|
size, err := con.Size()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := service.Pty(ctx, &execution.PtyRequest{
|
if _, err := service.Pty(ctx, &execution.PtyRequest{
|
||||||
ID: id,
|
ContainerID: id,
|
||||||
Pid: pid,
|
Pid: pid,
|
||||||
Width: uint32(size.Width),
|
Width: uint32(size.Width),
|
||||||
Height: uint32(size.Height),
|
Height: uint32(size.Height),
|
||||||
@ -331,7 +346,7 @@ func handleConsoleResize(ctx context.Context, service execution.ContainerService
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if _, err := service.Pty(ctx, &execution.PtyRequest{
|
if _, err := service.Pty(ctx, &execution.PtyRequest{
|
||||||
ID: id,
|
ContainerID: id,
|
||||||
Pid: pid,
|
Pid: pid,
|
||||||
Width: uint32(size.Width),
|
Width: uint32(size.Width),
|
||||||
Height: uint32(size.Height),
|
Height: uint32(size.Height),
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/containerd/console"
|
"github.com/containerd/console"
|
||||||
|
containersapi "github.com/containerd/containerd/api/services/containers"
|
||||||
"github.com/containerd/containerd/api/services/execution"
|
"github.com/containerd/containerd/api/services/execution"
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
"github.com/containerd/containerd/mount"
|
"github.com/containerd/containerd/mount"
|
||||||
@ -117,7 +118,7 @@ func getConfig(context *cli.Context, imageConfig *ocispec.ImageConfig, rootfs st
|
|||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSpec(context *cli.Context, config *ocispec.ImageConfig, imageRef string) ([]byte, error) {
|
func newContainerSpec(context *cli.Context, config *ocispec.ImageConfig, imageRef string) ([]byte, error) {
|
||||||
spec, err := getConfig(context, config, context.String("rootfs"))
|
spec, err := getConfig(context, config, context.String("rootfs"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -136,14 +137,25 @@ func newSpec(context *cli.Context, config *ocispec.ImageConfig, imageRef string)
|
|||||||
return json.Marshal(rtSpec)
|
return json.Marshal(rtSpec)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newCreateRequest(context *cli.Context, id, tmpDir string, checkpoint *ocispec.Descriptor, mounts []mount.Mount, spec []byte) (*execution.CreateRequest, error) {
|
func newCreateContainerRequest(context *cli.Context, id, snapshot string, spec []byte) (*containersapi.CreateContainerRequest, error) {
|
||||||
create := &execution.CreateRequest{
|
create := &containersapi.CreateContainerRequest{
|
||||||
|
Container: containersapi.Container{
|
||||||
ID: id,
|
ID: id,
|
||||||
Spec: &protobuf.Any{
|
Spec: &protobuf.Any{
|
||||||
TypeUrl: specs.Version,
|
TypeUrl: specs.Version,
|
||||||
Value: spec,
|
Value: spec,
|
||||||
},
|
},
|
||||||
Runtime: context.String("runtime"),
|
Runtime: context.String("runtime"),
|
||||||
|
RootFS: snapshot,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return create, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newCreateTaskRequest(context *cli.Context, id, tmpDir string, checkpoint *ocispec.Descriptor, mounts []mount.Mount) (*execution.CreateRequest, error) {
|
||||||
|
create := &execution.CreateRequest{
|
||||||
|
ContainerID: id,
|
||||||
Terminal: context.Bool("tty"),
|
Terminal: context.Bool("tty"),
|
||||||
Stdin: fmt.Sprintf(`%s\ctr-%s-stdin`, pipeRoot, id),
|
Stdin: fmt.Sprintf(`%s\ctr-%s-stdin`, pipeRoot, id),
|
||||||
Stdout: fmt.Sprintf(`%s\ctr-%s-stdout`, pipeRoot, id),
|
Stdout: fmt.Sprintf(`%s\ctr-%s-stdout`, pipeRoot, id),
|
||||||
@ -154,7 +166,7 @@ func newCreateRequest(context *cli.Context, id, tmpDir string, checkpoint *ocisp
|
|||||||
return create, nil
|
return create, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleConsoleResize(ctx context.Context, service execution.ContainerServiceClient, id string, pid uint32, con console.Console) error {
|
func handleConsoleResize(ctx context.Context, service execution.TasksClient, id string, pid uint32, con console.Console) error {
|
||||||
// do an initial resize of the console
|
// do an initial resize of the console
|
||||||
size, err := con.Size()
|
size, err := con.Size()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -173,7 +185,7 @@ func handleConsoleResize(ctx context.Context, service execution.ContainerService
|
|||||||
|
|
||||||
if size.Width != prevSize.Width || size.Height != prevSize.Height {
|
if size.Width != prevSize.Width || size.Height != prevSize.Height {
|
||||||
if _, err := service.Pty(ctx, &execution.PtyRequest{
|
if _, err := service.Pty(ctx, &execution.PtyRequest{
|
||||||
ID: id,
|
ContainerID: id,
|
||||||
Pid: pid,
|
Pid: pid,
|
||||||
Width: uint32(size.Width),
|
Width: uint32(size.Width),
|
||||||
Height: uint32(size.Height),
|
Height: uint32(size.Height),
|
||||||
|
@ -13,13 +13,14 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
|
containersapi "github.com/containerd/containerd/api/services/containers"
|
||||||
contentapi "github.com/containerd/containerd/api/services/content"
|
contentapi "github.com/containerd/containerd/api/services/content"
|
||||||
diffapi "github.com/containerd/containerd/api/services/diff"
|
diffapi "github.com/containerd/containerd/api/services/diff"
|
||||||
"github.com/containerd/containerd/api/services/execution"
|
"github.com/containerd/containerd/api/services/execution"
|
||||||
imagesapi "github.com/containerd/containerd/api/services/images"
|
imagesapi "github.com/containerd/containerd/api/services/images"
|
||||||
snapshotapi "github.com/containerd/containerd/api/services/snapshot"
|
snapshotapi "github.com/containerd/containerd/api/services/snapshot"
|
||||||
versionservice "github.com/containerd/containerd/api/services/version"
|
versionservice "github.com/containerd/containerd/api/services/version"
|
||||||
"github.com/containerd/containerd/api/types/container"
|
"github.com/containerd/containerd/api/types/task"
|
||||||
"github.com/containerd/containerd/content"
|
"github.com/containerd/containerd/content"
|
||||||
"github.com/containerd/containerd/images"
|
"github.com/containerd/containerd/images"
|
||||||
contentservice "github.com/containerd/containerd/services/content"
|
contentservice "github.com/containerd/containerd/services/content"
|
||||||
@ -34,12 +35,20 @@ import (
|
|||||||
|
|
||||||
var grpcConn *grpc.ClientConn
|
var grpcConn *grpc.ClientConn
|
||||||
|
|
||||||
func getExecutionService(context *cli.Context) (execution.ContainerServiceClient, error) {
|
func getContainersService(context *cli.Context) (containersapi.ContainersClient, error) {
|
||||||
conn, err := getGRPCConnection(context)
|
conn, err := getGRPCConnection(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return execution.NewContainerServiceClient(conn), nil
|
return containersapi.NewContainersClient(conn), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTasksService(context *cli.Context) (execution.TasksClient, error) {
|
||||||
|
conn, err := getGRPCConnection(context)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return execution.NewTasksClient(conn), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getContentStore(context *cli.Context) (content.Store, error) {
|
func getContentStore(context *cli.Context) (content.Store, error) {
|
||||||
@ -94,13 +103,13 @@ func getTempDir(id string) (string, error) {
|
|||||||
return tmpDir, nil
|
return tmpDir, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func waitContainer(events execution.ContainerService_EventsClient, id string, pid uint32) (uint32, error) {
|
func waitContainer(events execution.Tasks_EventsClient, id string, pid uint32) (uint32, error) {
|
||||||
for {
|
for {
|
||||||
e, err := events.Recv()
|
e, err := events.Recv()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 255, err
|
return 255, err
|
||||||
}
|
}
|
||||||
if e.Type != container.Event_EXIT {
|
if e.Type != task.Event_EXIT {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if e.ID == id && e.Pid == pid {
|
if e.ID == id && e.Pid == pid {
|
||||||
@ -109,7 +118,7 @@ func waitContainer(events execution.ContainerService_EventsClient, id string, pi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func forwardAllSignals(containers execution.ContainerServiceClient, id string) chan os.Signal {
|
func forwardAllSignals(containers execution.TasksClient, id string) chan os.Signal {
|
||||||
sigc := make(chan os.Signal, 128)
|
sigc := make(chan os.Signal, 128)
|
||||||
signal.Notify(sigc)
|
signal.Notify(sigc)
|
||||||
|
|
||||||
@ -117,7 +126,7 @@ func forwardAllSignals(containers execution.ContainerServiceClient, id string) c
|
|||||||
for s := range sigc {
|
for s := range sigc {
|
||||||
logrus.Debug("Forwarding signal ", s)
|
logrus.Debug("Forwarding signal ", s)
|
||||||
killRequest := &execution.KillRequest{
|
killRequest := &execution.KillRequest{
|
||||||
ID: id,
|
ContainerID: id,
|
||||||
Signal: uint32(s.(syscall.Signal)),
|
Signal: uint32(s.(syscall.Signal)),
|
||||||
PidOrAll: &execution.KillRequest_All{
|
PidOrAll: &execution.KillRequest_All{
|
||||||
All: false,
|
All: false,
|
||||||
|
@ -43,6 +43,7 @@ var (
|
|||||||
packageMap = map[string]string{
|
packageMap = map[string]string{
|
||||||
"google/protobuf/timestamp.proto": "github.com/gogo/protobuf/types",
|
"google/protobuf/timestamp.proto": "github.com/gogo/protobuf/types",
|
||||||
"google/protobuf/any.proto": "github.com/gogo/protobuf/types",
|
"google/protobuf/any.proto": "github.com/gogo/protobuf/types",
|
||||||
|
"google/protobuf/field_mask.proto": "github.com/gogo/protobuf/types",
|
||||||
"google/protobuf/descriptor.proto": "github.com/gogo/protobuf/protoc-gen-gogo/descriptor",
|
"google/protobuf/descriptor.proto": "github.com/gogo/protobuf/protoc-gen-gogo/descriptor",
|
||||||
"gogoproto/gogo.proto": "github.com/gogo/protobuf/gogoproto",
|
"gogoproto/gogo.proto": "github.com/gogo/protobuf/gogoproto",
|
||||||
}
|
}
|
||||||
|
24
containers/containers.go
Normal file
24
containers/containers.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package containers
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
// Container represents the set of data pinned by a container. Unless otherwise
|
||||||
|
// noted, the resources here are considered in use by the container.
|
||||||
|
//
|
||||||
|
// The resources specified in this object are used to create tasks from the container.
|
||||||
|
type Container struct {
|
||||||
|
ID string
|
||||||
|
Labels map[string]string
|
||||||
|
Image string
|
||||||
|
Runtime string
|
||||||
|
Spec []byte
|
||||||
|
RootFS string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Store interface {
|
||||||
|
Get(ctx context.Context, id string) (Container, error)
|
||||||
|
List(ctx context.Context, filter string) ([]Container, error)
|
||||||
|
Create(ctx context.Context, container Container) (Container, error)
|
||||||
|
Update(ctx context.Context, container Container) (Container, error)
|
||||||
|
Delete(ctx context.Context, id string) error
|
||||||
|
}
|
146
containers/storage.go
Normal file
146
containers/storage.go
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
package containers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/boltdb/bolt"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrExists = errors.New("images: exists")
|
||||||
|
ErrNotFound = errors.New("images: not found")
|
||||||
|
)
|
||||||
|
|
||||||
|
// IsNotFound returns true if the error is due to a missing image.
|
||||||
|
func IsNotFound(err error) bool {
|
||||||
|
return errors.Cause(err) == ErrNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsExists(err error) bool {
|
||||||
|
return errors.Cause(err) == ErrExists
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
bucketKeyStorageVersion = []byte("v1")
|
||||||
|
bucketKeyContainers = []byte("containers")
|
||||||
|
)
|
||||||
|
|
||||||
|
type storage struct {
|
||||||
|
tx *bolt.Tx
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStore(tx *bolt.Tx) Store {
|
||||||
|
return &storage{
|
||||||
|
tx: tx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storage) Get(ctx context.Context, id string) (Container, error) {
|
||||||
|
bkt := s.bucket()
|
||||||
|
if bkt == nil {
|
||||||
|
return Container{}, errors.Wrap(ErrNotFound, "bucket does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
cb := bkt.Get([]byte(id))
|
||||||
|
if len(cb) == 0 {
|
||||||
|
return Container{}, errors.Wrap(ErrNotFound, "no content for id")
|
||||||
|
}
|
||||||
|
|
||||||
|
var container Container
|
||||||
|
if err := json.Unmarshal(cb, &container); err != nil {
|
||||||
|
return Container{}, errors.Wrap(err, "failed to unmarshal container")
|
||||||
|
}
|
||||||
|
|
||||||
|
return container, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storage) List(ctx context.Context, filter string) ([]Container, error) {
|
||||||
|
containers := []Container{}
|
||||||
|
bkt := s.bucket()
|
||||||
|
if bkt == nil {
|
||||||
|
return containers, nil
|
||||||
|
}
|
||||||
|
err := bkt.ForEach(func(k, v []byte) error {
|
||||||
|
container := Container{ID: string(k)}
|
||||||
|
if err := json.Unmarshal(v, &container); err != nil {
|
||||||
|
return errors.Wrap(err, "failed to unmarshal container")
|
||||||
|
}
|
||||||
|
containers = append(containers, container)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return containers, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storage) Create(ctx context.Context, container Container) (Container, error) {
|
||||||
|
bkt, err := s.createBucket()
|
||||||
|
if err != nil {
|
||||||
|
return Container{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
b := bkt.Get([]byte(container.ID))
|
||||||
|
if len(b) > 0 {
|
||||||
|
return Container{}, errors.Wrap(ErrExists, "content for id already exists")
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err = json.Marshal(container)
|
||||||
|
if err != nil {
|
||||||
|
return Container{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return container, bkt.Put([]byte(container.ID), b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storage) Update(ctx context.Context, container Container) (Container, error) {
|
||||||
|
bkt, err := s.createBucket()
|
||||||
|
if err != nil {
|
||||||
|
return Container{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
b := bkt.Get([]byte(container.ID))
|
||||||
|
if len(b) == 0 {
|
||||||
|
return Container{}, errors.Wrap(ErrNotFound, "no content for id")
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err = json.Marshal(container)
|
||||||
|
if err != nil {
|
||||||
|
return Container{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return container, bkt.Put([]byte(container.ID), b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storage) Delete(ctx context.Context, id string) error {
|
||||||
|
bkt, err := s.createBucket()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
b := bkt.Get([]byte(id))
|
||||||
|
if len(b) == 0 {
|
||||||
|
return errors.Wrap(ErrNotFound, "no content for id")
|
||||||
|
}
|
||||||
|
|
||||||
|
return bkt.Delete([]byte(id))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storage) bucket() *bolt.Bucket {
|
||||||
|
bkt := s.tx.Bucket(bucketKeyStorageVersion)
|
||||||
|
if bkt == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return bkt.Bucket(bucketKeyContainers)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storage) createBucket() (*bolt.Bucket, error) {
|
||||||
|
bkt, err := s.tx.CreateBucketIfNotExists(bucketKeyStorageVersion)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return bkt.CreateBucketIfNotExists(bucketKeyContainers)
|
||||||
|
}
|
@ -55,7 +55,7 @@ func InitDB(db *bolt.DB) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewImageStore(tx *bolt.Tx) Store {
|
func NewStore(tx *bolt.Tx) Store {
|
||||||
return &storage{tx: tx}
|
return &storage{tx: tx}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,8 +14,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containerd/containerd/api/services/shim"
|
"github.com/containerd/containerd/api/services/shim"
|
||||||
"github.com/containerd/containerd/api/types/container"
|
|
||||||
"github.com/containerd/containerd/api/types/mount"
|
"github.com/containerd/containerd/api/types/mount"
|
||||||
|
"github.com/containerd/containerd/api/types/task"
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
"github.com/containerd/containerd/plugin"
|
"github.com/containerd/containerd/plugin"
|
||||||
runc "github.com/containerd/go-runc"
|
runc "github.com/containerd/go-runc"
|
||||||
@ -83,10 +83,10 @@ type Runtime struct {
|
|||||||
events chan *plugin.Event
|
events chan *plugin.Event
|
||||||
eventsContext context.Context
|
eventsContext context.Context
|
||||||
eventsCancel func()
|
eventsCancel func()
|
||||||
monitor plugin.ContainerMonitor
|
monitor plugin.TaskMonitor
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Runtime) Create(ctx context.Context, id string, opts plugin.CreateOpts) (plugin.Container, error) {
|
func (r *Runtime) Create(ctx context.Context, id string, opts plugin.CreateOpts) (plugin.Task, error) {
|
||||||
path, err := r.newBundle(id, opts.Spec)
|
path, err := r.newBundle(id, opts.Spec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -127,16 +127,16 @@ func (r *Runtime) Create(ctx context.Context, id string, opts plugin.CreateOpts)
|
|||||||
os.RemoveAll(path)
|
os.RemoveAll(path)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
c := newContainer(id, opts.Spec, s)
|
c := newTask(id, opts.Spec, s)
|
||||||
// after the container is created, add it to the monitor
|
// after the task is created, add it to the monitor
|
||||||
if err = r.monitor.Monitor(c); err != nil {
|
if err = r.monitor.Monitor(c); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Runtime) Delete(ctx context.Context, c plugin.Container) (*plugin.Exit, error) {
|
func (r *Runtime) Delete(ctx context.Context, c plugin.Task) (*plugin.Exit, error) {
|
||||||
lc, ok := c.(*Container)
|
lc, ok := c.(*Task)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("container cannot be cast as *linux.Container")
|
return nil, fmt.Errorf("container cannot be cast as *linux.Container")
|
||||||
}
|
}
|
||||||
@ -153,15 +153,15 @@ func (r *Runtime) Delete(ctx context.Context, c plugin.Container) (*plugin.Exit,
|
|||||||
return &plugin.Exit{
|
return &plugin.Exit{
|
||||||
Status: rsp.ExitStatus,
|
Status: rsp.ExitStatus,
|
||||||
Timestamp: rsp.ExitedAt,
|
Timestamp: rsp.ExitedAt,
|
||||||
}, r.deleteBundle(lc.id)
|
}, r.deleteBundle(lc.containerID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Runtime) Containers(ctx context.Context) ([]plugin.Container, error) {
|
func (r *Runtime) Tasks(ctx context.Context) ([]plugin.Task, error) {
|
||||||
dir, err := ioutil.ReadDir(r.root)
|
dir, err := ioutil.ReadDir(r.root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var o []plugin.Container
|
var o []plugin.Task
|
||||||
for _, fi := range dir {
|
for _, fi := range dir {
|
||||||
if !fi.IsDir() {
|
if !fi.IsDir() {
|
||||||
continue
|
continue
|
||||||
@ -206,15 +206,15 @@ func (r *Runtime) forward(events shim.Shim_EventsClient) {
|
|||||||
}
|
}
|
||||||
var et plugin.EventType
|
var et plugin.EventType
|
||||||
switch e.Type {
|
switch e.Type {
|
||||||
case container.Event_CREATE:
|
case task.Event_CREATE:
|
||||||
et = plugin.CreateEvent
|
et = plugin.CreateEvent
|
||||||
case container.Event_EXEC_ADDED:
|
case task.Event_EXEC_ADDED:
|
||||||
et = plugin.ExecAddEvent
|
et = plugin.ExecAddEvent
|
||||||
case container.Event_EXIT:
|
case task.Event_EXIT:
|
||||||
et = plugin.ExitEvent
|
et = plugin.ExitEvent
|
||||||
case container.Event_OOM:
|
case task.Event_OOM:
|
||||||
et = plugin.OOMEvent
|
et = plugin.OOMEvent
|
||||||
case container.Event_START:
|
case task.Event_START:
|
||||||
et = plugin.StartEvent
|
et = plugin.StartEvent
|
||||||
}
|
}
|
||||||
r.events <- &plugin.Event{
|
r.events <- &plugin.Event{
|
||||||
@ -250,18 +250,20 @@ func (r *Runtime) deleteBundle(id string) error {
|
|||||||
return os.RemoveAll(filepath.Join(r.root, id))
|
return os.RemoveAll(filepath.Join(r.root, id))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Runtime) loadContainer(path string) (*Container, error) {
|
func (r *Runtime) loadContainer(path string) (*Task, error) {
|
||||||
id := filepath.Base(path)
|
id := filepath.Base(path)
|
||||||
s, err := loadShim(path, r.remote)
|
s, err := loadShim(path, r.remote)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := ioutil.ReadFile(filepath.Join(path, configFilename))
|
data, err := ioutil.ReadFile(filepath.Join(path, configFilename))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &Container{
|
|
||||||
id: id,
|
return &Task{
|
||||||
|
containerID: id,
|
||||||
shim: s,
|
shim: s,
|
||||||
spec: data,
|
spec: data,
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
shimapi "github.com/containerd/containerd/api/services/shim"
|
shimapi "github.com/containerd/containerd/api/services/shim"
|
||||||
"github.com/containerd/containerd/api/types/container"
|
"github.com/containerd/containerd/api/types/task"
|
||||||
runc "github.com/containerd/go-runc"
|
runc "github.com/containerd/go-runc"
|
||||||
google_protobuf "github.com/golang/protobuf/ptypes/empty"
|
google_protobuf "github.com/golang/protobuf/ptypes/empty"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
@ -104,11 +104,11 @@ func (c *client) Checkpoint(ctx context.Context, in *shimapi.CheckpointRequest,
|
|||||||
}
|
}
|
||||||
|
|
||||||
type events struct {
|
type events struct {
|
||||||
c chan *container.Event
|
c chan *task.Event
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *events) Recv() (*container.Event, error) {
|
func (e *events) Recv() (*task.Event, error) {
|
||||||
ev := <-e.c
|
ev := <-e.c
|
||||||
return ev, nil
|
return ev, nil
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
|
|
||||||
"github.com/containerd/console"
|
"github.com/containerd/console"
|
||||||
shimapi "github.com/containerd/containerd/api/services/shim"
|
shimapi "github.com/containerd/containerd/api/services/shim"
|
||||||
"github.com/containerd/containerd/api/types/container"
|
"github.com/containerd/containerd/api/types/task"
|
||||||
"github.com/containerd/containerd/reaper"
|
"github.com/containerd/containerd/reaper"
|
||||||
google_protobuf "github.com/golang/protobuf/ptypes/empty"
|
google_protobuf "github.com/golang/protobuf/ptypes/empty"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@ -25,7 +25,7 @@ func New(path string) *Service {
|
|||||||
return &Service{
|
return &Service{
|
||||||
path: path,
|
path: path,
|
||||||
processes: make(map[int]process),
|
processes: make(map[int]process),
|
||||||
events: make(chan *container.Event, 4096),
|
events: make(chan *task.Event, 4096),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ type Service struct {
|
|||||||
bundle string
|
bundle string
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
processes map[int]process
|
processes map[int]process
|
||||||
events chan *container.Event
|
events chan *task.Event
|
||||||
execID int
|
execID int
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,8 +56,9 @@ func (s *Service) Create(ctx context.Context, r *shimapi.CreateRequest) (*shimap
|
|||||||
ExitCh: make(chan int, 1),
|
ExitCh: make(chan int, 1),
|
||||||
}
|
}
|
||||||
reaper.Default.Register(pid, cmd)
|
reaper.Default.Register(pid, cmd)
|
||||||
s.events <- &container.Event{
|
go s.waitExit(process, pid, cmd)
|
||||||
Type: container.Event_CREATE,
|
s.events <- &task.Event{
|
||||||
|
Type: task.Event_CREATE,
|
||||||
ID: r.ID,
|
ID: r.ID,
|
||||||
Pid: uint32(pid),
|
Pid: uint32(pid),
|
||||||
}
|
}
|
||||||
@ -71,8 +72,8 @@ func (s *Service) Start(ctx context.Context, r *shimapi.StartRequest) (*google_p
|
|||||||
if err := s.initProcess.Start(ctx); err != nil {
|
if err := s.initProcess.Start(ctx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.events <- &container.Event{
|
s.events <- &task.Event{
|
||||||
Type: container.Event_START,
|
Type: task.Event_START,
|
||||||
ID: s.id,
|
ID: s.id,
|
||||||
Pid: uint32(s.initProcess.Pid()),
|
Pid: uint32(s.initProcess.Pid()),
|
||||||
}
|
}
|
||||||
@ -114,8 +115,9 @@ func (s *Service) Exec(ctx context.Context, r *shimapi.ExecRequest) (*shimapi.Ex
|
|||||||
}
|
}
|
||||||
reaper.Default.RegisterNL(pid, cmd)
|
reaper.Default.RegisterNL(pid, cmd)
|
||||||
reaper.Default.Unlock()
|
reaper.Default.Unlock()
|
||||||
s.events <- &container.Event{
|
go s.waitExit(process, pid, cmd)
|
||||||
Type: container.Event_EXEC_ADDED,
|
s.events <- &task.Event{
|
||||||
|
Type: task.Event_EXEC_ADDED,
|
||||||
ID: s.id,
|
ID: s.id,
|
||||||
Pid: uint32(pid),
|
Pid: uint32(pid),
|
||||||
}
|
}
|
||||||
@ -159,35 +161,35 @@ func (s *Service) State(ctx context.Context, r *shimapi.StateRequest) (*shimapi.
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
status := container.StatusUnknown
|
status := task.StatusUnknown
|
||||||
switch st {
|
switch st {
|
||||||
case "created":
|
case "created":
|
||||||
status = container.StatusCreated
|
status = task.StatusCreated
|
||||||
case "running":
|
case "running":
|
||||||
status = container.StatusRunning
|
status = task.StatusRunning
|
||||||
case "stopped":
|
case "stopped":
|
||||||
status = container.StatusStopped
|
status = task.StatusStopped
|
||||||
case "paused":
|
case "paused":
|
||||||
status = container.StatusPaused
|
status = task.StatusPaused
|
||||||
}
|
}
|
||||||
o := &shimapi.StateResponse{
|
o := &shimapi.StateResponse{
|
||||||
ID: s.id,
|
ID: s.id,
|
||||||
Bundle: s.bundle,
|
Bundle: s.bundle,
|
||||||
Pid: uint32(s.initProcess.Pid()),
|
Pid: uint32(s.initProcess.Pid()),
|
||||||
Status: status,
|
Status: status,
|
||||||
Processes: []*container.Process{},
|
Processes: []*task.Process{},
|
||||||
}
|
}
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
defer s.mu.Unlock()
|
defer s.mu.Unlock()
|
||||||
for _, p := range s.processes {
|
for _, p := range s.processes {
|
||||||
status := container.StatusRunning
|
status := task.StatusRunning
|
||||||
if err := unix.Kill(p.Pid(), 0); err != nil {
|
if err := unix.Kill(p.Pid(), 0); err != nil {
|
||||||
if err != syscall.ESRCH {
|
if err != syscall.ESRCH {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
status = container.StatusStopped
|
status = task.StatusStopped
|
||||||
}
|
}
|
||||||
o.Processes = append(o.Processes, &container.Process{
|
o.Processes = append(o.Processes, &task.Process{
|
||||||
Pid: uint32(p.Pid()),
|
Pid: uint32(p.Pid()),
|
||||||
Status: status,
|
Status: status,
|
||||||
})
|
})
|
||||||
@ -255,9 +257,9 @@ func (s *Service) Processes(ctx context.Context, r *shimapi.ProcessesRequest) (*
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ps := []*container.Process{}
|
ps := []*task.Process{}
|
||||||
for _, pid := range pids {
|
for _, pid := range pids {
|
||||||
ps = append(ps, &container.Process{
|
ps = append(ps, &task.Process{
|
||||||
Pid: pid,
|
Pid: pid,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -290,8 +292,8 @@ func (s *Service) Checkpoint(ctx context.Context, r *shimapi.CheckpointRequest)
|
|||||||
func (s *Service) waitExit(p process, pid int, cmd *reaper.Cmd) {
|
func (s *Service) waitExit(p process, pid int, cmd *reaper.Cmd) {
|
||||||
status := <-cmd.ExitCh
|
status := <-cmd.ExitCh
|
||||||
p.Exited(status)
|
p.Exited(status)
|
||||||
s.events <- &container.Event{
|
s.events <- &task.Event{
|
||||||
Type: container.Event_EXIT,
|
Type: task.Event_EXIT,
|
||||||
ID: s.id,
|
ID: s.id,
|
||||||
Pid: uint32(pid),
|
Pid: uint32(pid),
|
||||||
ExitStatus: uint32(status),
|
ExitStatus: uint32(status),
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/containerd/containerd/api/services/shim"
|
"github.com/containerd/containerd/api/services/shim"
|
||||||
"github.com/containerd/containerd/api/types/container"
|
"github.com/containerd/containerd/api/types/task"
|
||||||
"github.com/containerd/containerd/plugin"
|
"github.com/containerd/containerd/plugin"
|
||||||
protobuf "github.com/gogo/protobuf/types"
|
protobuf "github.com/gogo/protobuf/types"
|
||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
@ -25,48 +25,47 @@ func (s State) Status() plugin.Status {
|
|||||||
return s.status
|
return s.status
|
||||||
}
|
}
|
||||||
|
|
||||||
func newContainer(id string, spec []byte, shim shim.ShimClient) *Container {
|
type Task struct {
|
||||||
return &Container{
|
containerID string
|
||||||
id: id,
|
spec []byte
|
||||||
|
shim shim.ShimClient
|
||||||
|
}
|
||||||
|
|
||||||
|
func newTask(id string, spec []byte, shim shim.ShimClient) *Task {
|
||||||
|
return &Task{
|
||||||
|
containerID: id,
|
||||||
shim: shim,
|
shim: shim,
|
||||||
spec: spec,
|
spec: spec,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Container struct {
|
func (c *Task) Info() plugin.TaskInfo {
|
||||||
id string
|
return plugin.TaskInfo{
|
||||||
spec []byte
|
ContainerID: c.containerID,
|
||||||
|
|
||||||
shim shim.ShimClient
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Container) Info() plugin.ContainerInfo {
|
|
||||||
return plugin.ContainerInfo{
|
|
||||||
ID: c.id,
|
|
||||||
Runtime: runtimeName,
|
Runtime: runtimeName,
|
||||||
Spec: c.spec,
|
Spec: c.spec,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) Start(ctx context.Context) error {
|
func (c *Task) Start(ctx context.Context) error {
|
||||||
_, err := c.shim.Start(ctx, &shim.StartRequest{})
|
_, err := c.shim.Start(ctx, &shim.StartRequest{})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) State(ctx context.Context) (plugin.State, error) {
|
func (c *Task) State(ctx context.Context) (plugin.State, error) {
|
||||||
response, err := c.shim.State(ctx, &shim.StateRequest{})
|
response, err := c.shim.State(ctx, &shim.StateRequest{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var status plugin.Status
|
var status plugin.Status
|
||||||
switch response.Status {
|
switch response.Status {
|
||||||
case container.StatusCreated:
|
case task.StatusCreated:
|
||||||
status = plugin.CreatedStatus
|
status = plugin.CreatedStatus
|
||||||
case container.StatusRunning:
|
case task.StatusRunning:
|
||||||
status = plugin.RunningStatus
|
status = plugin.RunningStatus
|
||||||
case container.StatusStopped:
|
case task.StatusStopped:
|
||||||
status = plugin.StoppedStatus
|
status = plugin.StoppedStatus
|
||||||
case container.StatusPaused:
|
case task.StatusPaused:
|
||||||
status = plugin.PausedStatus
|
status = plugin.PausedStatus
|
||||||
// TODO: containerd.DeletedStatus
|
// TODO: containerd.DeletedStatus
|
||||||
}
|
}
|
||||||
@ -76,17 +75,17 @@ func (c *Container) State(ctx context.Context) (plugin.State, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) Pause(ctx context.Context) error {
|
func (c *Task) Pause(ctx context.Context) error {
|
||||||
_, err := c.shim.Pause(ctx, &shim.PauseRequest{})
|
_, err := c.shim.Pause(ctx, &shim.PauseRequest{})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) Resume(ctx context.Context) error {
|
func (c *Task) Resume(ctx context.Context) error {
|
||||||
_, err := c.shim.Resume(ctx, &shim.ResumeRequest{})
|
_, err := c.shim.Resume(ctx, &shim.ResumeRequest{})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) Kill(ctx context.Context, signal uint32, pid uint32, all bool) error {
|
func (c *Task) Kill(ctx context.Context, signal uint32, pid uint32, all bool) error {
|
||||||
_, err := c.shim.Kill(ctx, &shim.KillRequest{
|
_, err := c.shim.Kill(ctx, &shim.KillRequest{
|
||||||
Signal: signal,
|
Signal: signal,
|
||||||
Pid: pid,
|
Pid: pid,
|
||||||
@ -95,7 +94,7 @@ func (c *Container) Kill(ctx context.Context, signal uint32, pid uint32, all boo
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) Exec(ctx context.Context, opts plugin.ExecOpts) (plugin.Process, error) {
|
func (c *Task) Exec(ctx context.Context, opts plugin.ExecOpts) (plugin.Process, error) {
|
||||||
request := &shim.ExecRequest{
|
request := &shim.ExecRequest{
|
||||||
Stdin: opts.IO.Stdin,
|
Stdin: opts.IO.Stdin,
|
||||||
Stdout: opts.IO.Stdout,
|
Stdout: opts.IO.Stdout,
|
||||||
@ -117,9 +116,9 @@ func (c *Container) Exec(ctx context.Context, opts plugin.ExecOpts) (plugin.Proc
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) Processes(ctx context.Context) ([]uint32, error) {
|
func (c *Task) Processes(ctx context.Context) ([]uint32, error) {
|
||||||
resp, err := c.shim.Processes(ctx, &shim.ProcessesRequest{
|
resp, err := c.shim.Processes(ctx, &shim.ProcessesRequest{
|
||||||
ID: c.id,
|
ID: c.containerID,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -135,7 +134,7 @@ func (c *Container) Processes(ctx context.Context) ([]uint32, error) {
|
|||||||
return pids, nil
|
return pids, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) Pty(ctx context.Context, pid uint32, size plugin.ConsoleSize) error {
|
func (c *Task) Pty(ctx context.Context, pid uint32, size plugin.ConsoleSize) error {
|
||||||
_, err := c.shim.Pty(ctx, &shim.PtyRequest{
|
_, err := c.shim.Pty(ctx, &shim.PtyRequest{
|
||||||
Pid: pid,
|
Pid: pid,
|
||||||
Width: size.Width,
|
Width: size.Width,
|
||||||
@ -144,14 +143,14 @@ func (c *Container) Pty(ctx context.Context, pid uint32, size plugin.ConsoleSize
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) CloseStdin(ctx context.Context, pid uint32) error {
|
func (c *Task) CloseStdin(ctx context.Context, pid uint32) error {
|
||||||
_, err := c.shim.CloseStdin(ctx, &shim.CloseStdinRequest{
|
_, err := c.shim.CloseStdin(ctx, &shim.CloseStdinRequest{
|
||||||
Pid: pid,
|
Pid: pid,
|
||||||
})
|
})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) Checkpoint(ctx context.Context, opts plugin.CheckpointOpts) error {
|
func (c *Task) Checkpoint(ctx context.Context, opts plugin.CheckpointOpts) error {
|
||||||
_, err := c.shim.Checkpoint(ctx, &shim.CheckpointRequest{
|
_, err := c.shim.Checkpoint(ctx, &shim.CheckpointRequest{
|
||||||
Exit: opts.Exit,
|
Exit: opts.Exit,
|
||||||
AllowTcp: opts.AllowTCP,
|
AllowTcp: opts.AllowTCP,
|
||||||
@ -166,7 +165,7 @@ func (c *Container) Checkpoint(ctx context.Context, opts plugin.CheckpointOpts)
|
|||||||
|
|
||||||
type Process struct {
|
type Process struct {
|
||||||
pid int
|
pid int
|
||||||
c *Container
|
c *Task
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Process) Kill(ctx context.Context, signal uint32, _ bool) error {
|
func (p *Process) Kill(ctx context.Context, signal uint32, _ bool) error {
|
@ -14,7 +14,7 @@ const name = "cgroups"
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugin.Register(name, &plugin.Registration{
|
plugin.Register(name, &plugin.Registration{
|
||||||
Type: plugin.ContainerMonitorPlugin,
|
Type: plugin.TaskMonitorPlugin,
|
||||||
Init: New,
|
Init: New,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -43,7 +43,7 @@ type cgroupsMonitor struct {
|
|||||||
events chan<- *plugin.Event
|
events chan<- *plugin.Event
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *cgroupsMonitor) Monitor(c plugin.Container) error {
|
func (m *cgroupsMonitor) Monitor(c plugin.Task) error {
|
||||||
id := c.Info().ID
|
id := c.Info().ID
|
||||||
state, err := c.State(m.context)
|
state, err := c.State(m.context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -59,7 +59,7 @@ func (m *cgroupsMonitor) Monitor(c plugin.Container) error {
|
|||||||
return m.oom.Add(id, cg, m.trigger)
|
return m.oom.Add(id, cg, m.trigger)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *cgroupsMonitor) Stop(c plugin.Container) error {
|
func (m *cgroupsMonitor) Stop(c plugin.Task) error {
|
||||||
m.collector.Remove(c.Info().ID)
|
m.collector.Remove(c.Info().ID)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -2,15 +2,16 @@ package plugin
|
|||||||
|
|
||||||
import "context"
|
import "context"
|
||||||
|
|
||||||
type ContainerInfo struct {
|
type TaskInfo struct {
|
||||||
ID string
|
ID string
|
||||||
|
ContainerID string
|
||||||
Runtime string
|
Runtime string
|
||||||
Spec []byte
|
Spec []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
type Container interface {
|
type Task interface {
|
||||||
// Information of the container
|
// Information of the container
|
||||||
Info() ContainerInfo
|
Info() TaskInfo
|
||||||
// Start the container's user defined process
|
// Start the container's user defined process
|
||||||
Start(context.Context) error
|
Start(context.Context) error
|
||||||
// State returns the container's state
|
// State returns the container's state
|
||||||
|
@ -1,44 +1,44 @@
|
|||||||
package plugin
|
package plugin
|
||||||
|
|
||||||
// ContainerMonitor provides an interface for monitoring of containers within containerd
|
// TaskMonitor provides an interface for monitoring of containers within containerd
|
||||||
type ContainerMonitor interface {
|
type TaskMonitor interface {
|
||||||
// Monitor adds the provided container to the monitor
|
// Monitor adds the provided container to the monitor
|
||||||
Monitor(Container) error
|
Monitor(Task) error
|
||||||
// Stop stops and removes the provided container from the monitor
|
// Stop stops and removes the provided container from the monitor
|
||||||
Stop(Container) error
|
Stop(Task) error
|
||||||
// Events emits events from the monitor
|
// Events emits events from the monitor
|
||||||
Events(chan<- *Event)
|
Events(chan<- *Event)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMultiContainerMonitor(monitors ...ContainerMonitor) ContainerMonitor {
|
func NewMultiTaskMonitor(monitors ...TaskMonitor) TaskMonitor {
|
||||||
return &multiContainerMonitor{
|
return &multiTaskMonitor{
|
||||||
monitors: monitors,
|
monitors: monitors,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNoopMonitor() ContainerMonitor {
|
func NewNoopMonitor() TaskMonitor {
|
||||||
return &noopContainerMonitor{}
|
return &noopTaskMonitor{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type noopContainerMonitor struct {
|
type noopTaskMonitor struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mm *noopContainerMonitor) Monitor(c Container) error {
|
func (mm *noopTaskMonitor) Monitor(c Task) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mm *noopContainerMonitor) Stop(c Container) error {
|
func (mm *noopTaskMonitor) Stop(c Task) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mm *noopContainerMonitor) Events(events chan<- *Event) {
|
func (mm *noopTaskMonitor) Events(events chan<- *Event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type multiContainerMonitor struct {
|
type multiTaskMonitor struct {
|
||||||
monitors []ContainerMonitor
|
monitors []TaskMonitor
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mm *multiContainerMonitor) Monitor(c Container) error {
|
func (mm *multiTaskMonitor) Monitor(c Task) error {
|
||||||
for _, m := range mm.monitors {
|
for _, m := range mm.monitors {
|
||||||
if err := m.Monitor(c); err != nil {
|
if err := m.Monitor(c); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -47,7 +47,7 @@ func (mm *multiContainerMonitor) Monitor(c Container) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mm *multiContainerMonitor) Stop(c Container) error {
|
func (mm *multiTaskMonitor) Stop(c Task) error {
|
||||||
for _, m := range mm.monitors {
|
for _, m := range mm.monitors {
|
||||||
if err := m.Stop(c); err != nil {
|
if err := m.Stop(c); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -56,7 +56,7 @@ func (mm *multiContainerMonitor) Stop(c Container) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mm *multiContainerMonitor) Events(events chan<- *Event) {
|
func (mm *multiTaskMonitor) Events(events chan<- *Event) {
|
||||||
for _, m := range mm.monitors {
|
for _, m := range mm.monitors {
|
||||||
m.Events(events)
|
m.Events(events)
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ const (
|
|||||||
RuntimePlugin PluginType = iota + 1
|
RuntimePlugin PluginType = iota + 1
|
||||||
GRPCPlugin
|
GRPCPlugin
|
||||||
SnapshotPlugin
|
SnapshotPlugin
|
||||||
ContainerMonitorPlugin
|
TaskMonitorPlugin
|
||||||
)
|
)
|
||||||
|
|
||||||
type Registration struct {
|
type Registration struct {
|
||||||
@ -37,7 +37,7 @@ type InitContext struct {
|
|||||||
Snapshotter snapshot.Snapshotter
|
Snapshotter snapshot.Snapshotter
|
||||||
Config interface{}
|
Config interface{}
|
||||||
Context context.Context
|
Context context.Context
|
||||||
Monitor ContainerMonitor
|
Monitor TaskMonitor
|
||||||
}
|
}
|
||||||
|
|
||||||
type Service interface {
|
type Service interface {
|
||||||
|
@ -33,11 +33,11 @@ type Exit struct {
|
|||||||
// arch, or custom usage.
|
// arch, or custom usage.
|
||||||
type Runtime interface {
|
type Runtime interface {
|
||||||
// Create creates a container with the provided id and options
|
// Create creates a container with the provided id and options
|
||||||
Create(ctx context.Context, id string, opts CreateOpts) (Container, error)
|
Create(ctx context.Context, id string, opts CreateOpts) (Task, error)
|
||||||
// Containers returns all the current containers for the runtime
|
// Containers returns all the current containers for the runtime
|
||||||
Containers(context.Context) ([]Container, error)
|
Tasks(context.Context) ([]Task, error)
|
||||||
// Delete removes the container in the runtime
|
// Delete removes the container in the runtime
|
||||||
Delete(context.Context, Container) (*Exit, error)
|
Delete(context.Context, Task) (*Exit, error)
|
||||||
// Events returns events for the runtime and all containers created by the runtime
|
// Events returns events for the runtime and all containers created by the runtime
|
||||||
Events(context.Context) <-chan *Event
|
Events(context.Context) <-chan *Event
|
||||||
}
|
}
|
||||||
|
56
services/containers/helpers.go
Normal file
56
services/containers/helpers.go
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package containers
|
||||||
|
|
||||||
|
import (
|
||||||
|
api "github.com/containerd/containerd/api/services/containers"
|
||||||
|
"github.com/containerd/containerd/containers"
|
||||||
|
"github.com/gogo/protobuf/types"
|
||||||
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
)
|
||||||
|
|
||||||
|
func containersToProto(containers []containers.Container) []api.Container {
|
||||||
|
var containerspb []api.Container
|
||||||
|
|
||||||
|
for _, image := range containers {
|
||||||
|
containerspb = append(containerspb, containerToProto(&image))
|
||||||
|
}
|
||||||
|
|
||||||
|
return containerspb
|
||||||
|
}
|
||||||
|
|
||||||
|
func containerToProto(container *containers.Container) api.Container {
|
||||||
|
return api.Container{
|
||||||
|
ID: container.ID,
|
||||||
|
Labels: container.Labels,
|
||||||
|
Image: container.Image,
|
||||||
|
Runtime: container.Runtime,
|
||||||
|
Spec: &types.Any{
|
||||||
|
TypeUrl: specs.Version,
|
||||||
|
Value: container.Spec,
|
||||||
|
},
|
||||||
|
RootFS: container.RootFS,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func containerFromProto(containerpb *api.Container) containers.Container {
|
||||||
|
return containers.Container{
|
||||||
|
ID: containerpb.ID,
|
||||||
|
Labels: containerpb.Labels,
|
||||||
|
Image: containerpb.Image,
|
||||||
|
Runtime: containerpb.Runtime,
|
||||||
|
Spec: containerpb.Spec.Value,
|
||||||
|
RootFS: containerpb.RootFS,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func mapGRPCError(err error, id string) error {
|
||||||
|
switch {
|
||||||
|
case containers.IsNotFound(err):
|
||||||
|
return grpc.Errorf(codes.NotFound, "container %v not found", id)
|
||||||
|
case containers.IsExists(err):
|
||||||
|
return grpc.Errorf(codes.AlreadyExists, "container %v already exists", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
148
services/containers/service.go
Normal file
148
services/containers/service.go
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
package containers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/boltdb/bolt"
|
||||||
|
api "github.com/containerd/containerd/api/services/containers"
|
||||||
|
"github.com/containerd/containerd/containers"
|
||||||
|
"github.com/containerd/containerd/plugin"
|
||||||
|
"github.com/golang/protobuf/ptypes/empty"
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
plugin.Register("containers-grpc", &plugin.Registration{
|
||||||
|
Type: plugin.GRPCPlugin,
|
||||||
|
Init: func(ic *plugin.InitContext) (interface{}, error) {
|
||||||
|
return NewService(ic.Meta), nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type Service struct {
|
||||||
|
db *bolt.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewService(db *bolt.DB) api.ContainersServer {
|
||||||
|
return &Service{db: db}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) Register(server *grpc.Server) error {
|
||||||
|
api.RegisterContainersServer(server, s)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) Get(ctx context.Context, req *api.GetContainerRequest) (*api.GetContainerResponse, error) {
|
||||||
|
var resp api.GetContainerResponse
|
||||||
|
|
||||||
|
return &resp, s.withStoreView(ctx, func(ctx context.Context, store containers.Store) error {
|
||||||
|
container, err := store.Get(ctx, req.ID)
|
||||||
|
if err != nil {
|
||||||
|
return mapGRPCError(err, req.ID)
|
||||||
|
}
|
||||||
|
containerpb := containerToProto(&container)
|
||||||
|
resp.Container = containerpb
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) List(ctx context.Context, req *api.ListContainersRequest) (*api.ListContainersResponse, error) {
|
||||||
|
var resp api.ListContainersResponse
|
||||||
|
|
||||||
|
return &resp, s.withStoreView(ctx, func(ctx context.Context, store containers.Store) error {
|
||||||
|
containers, err := store.List(ctx, req.Filter)
|
||||||
|
if err != nil {
|
||||||
|
return mapGRPCError(err, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.Containers = containersToProto(containers)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) Create(ctx context.Context, req *api.CreateContainerRequest) (*api.CreateContainerResponse, error) {
|
||||||
|
var resp api.CreateContainerResponse
|
||||||
|
|
||||||
|
return &resp, s.withStoreUpdate(ctx, func(ctx context.Context, store containers.Store) error {
|
||||||
|
container := containerFromProto(&req.Container)
|
||||||
|
|
||||||
|
created, err := store.Create(ctx, container)
|
||||||
|
if err != nil {
|
||||||
|
return mapGRPCError(err, req.Container.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.Container = containerToProto(&created)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) Update(ctx context.Context, req *api.UpdateContainerRequest) (*api.UpdateContainerResponse, error) {
|
||||||
|
var resp api.UpdateContainerResponse
|
||||||
|
|
||||||
|
return &resp, s.withStoreUpdate(ctx, func(ctx context.Context, store containers.Store) error {
|
||||||
|
container := containerFromProto(&req.Container)
|
||||||
|
|
||||||
|
current, err := store.Get(ctx, container.ID)
|
||||||
|
if err != nil {
|
||||||
|
return mapGRPCError(err, container.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
if current.ID != container.ID {
|
||||||
|
return grpc.Errorf(codes.InvalidArgument, "container ids must match: %v != %v", current.ID, container.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply the field mask. If you update this code, you better follow the
|
||||||
|
// field mask rules in field_mask.proto. If you don't know what this
|
||||||
|
// is, do not update this code.
|
||||||
|
if req.UpdateMask != nil && len(req.UpdateMask.Paths) > 0 {
|
||||||
|
for _, path := range req.UpdateMask.Paths {
|
||||||
|
switch path {
|
||||||
|
case "labels":
|
||||||
|
current.Labels = container.Labels
|
||||||
|
case "image":
|
||||||
|
current.Image = container.Image
|
||||||
|
case "runtime":
|
||||||
|
// TODO(stevvooe): Should this actually be allowed?
|
||||||
|
current.Runtime = container.Runtime
|
||||||
|
case "spec":
|
||||||
|
current.Spec = container.Spec
|
||||||
|
case "rootfs":
|
||||||
|
current.RootFS = container.RootFS
|
||||||
|
default:
|
||||||
|
return grpc.Errorf(codes.InvalidArgument, "cannot update %q field", path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// no field mask present, just replace everything
|
||||||
|
current = container
|
||||||
|
}
|
||||||
|
|
||||||
|
created, err := store.Update(ctx, container)
|
||||||
|
if err != nil {
|
||||||
|
return mapGRPCError(err, req.Container.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.Container = containerToProto(&created)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) Delete(ctx context.Context, req *api.DeleteContainerRequest) (*empty.Empty, error) {
|
||||||
|
return &empty.Empty{}, s.withStoreUpdate(ctx, func(ctx context.Context, store containers.Store) error {
|
||||||
|
return mapGRPCError(store.Delete(ctx, req.ID), req.ID)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) withStore(ctx context.Context, fn func(ctx context.Context, store containers.Store) error) func(tx *bolt.Tx) error {
|
||||||
|
return func(tx *bolt.Tx) error { return fn(ctx, containers.NewStore(tx)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) withStoreView(ctx context.Context, fn func(ctx context.Context, store containers.Store) error) error {
|
||||||
|
return s.db.View(s.withStore(ctx, fn))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) withStoreUpdate(ctx context.Context, fn func(ctx context.Context, store containers.Store) error) error {
|
||||||
|
return s.db.Update(s.withStore(ctx, fn))
|
||||||
|
}
|
@ -9,10 +9,12 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/boltdb/bolt"
|
||||||
api "github.com/containerd/containerd/api/services/execution"
|
api "github.com/containerd/containerd/api/services/execution"
|
||||||
"github.com/containerd/containerd/api/types/container"
|
|
||||||
"github.com/containerd/containerd/api/types/descriptor"
|
"github.com/containerd/containerd/api/types/descriptor"
|
||||||
|
"github.com/containerd/containerd/api/types/task"
|
||||||
"github.com/containerd/containerd/archive"
|
"github.com/containerd/containerd/archive"
|
||||||
|
"github.com/containerd/containerd/containers"
|
||||||
"github.com/containerd/containerd/content"
|
"github.com/containerd/containerd/content"
|
||||||
"github.com/containerd/containerd/images"
|
"github.com/containerd/containerd/images"
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
@ -23,15 +25,16 @@ import (
|
|||||||
specs "github.com/opencontainers/image-spec/specs-go"
|
specs "github.com/opencontainers/image-spec/specs-go"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_ = (api.ContainerServiceServer)(&Service{})
|
_ = (api.TasksServer)(&Service{})
|
||||||
empty = &google_protobuf.Empty{}
|
empty = &google_protobuf.Empty{}
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugin.Register("runtime-grpc", &plugin.Registration{
|
plugin.Register("tasks-grpc", &plugin.Registration{
|
||||||
Type: plugin.GRPCPlugin,
|
Type: plugin.GRPCPlugin,
|
||||||
Init: New,
|
Init: New,
|
||||||
})
|
})
|
||||||
@ -44,7 +47,8 @@ func New(ic *plugin.InitContext) (interface{}, error) {
|
|||||||
}
|
}
|
||||||
return &Service{
|
return &Service{
|
||||||
runtimes: ic.Runtimes,
|
runtimes: ic.Runtimes,
|
||||||
containers: make(map[string]plugin.Container),
|
tasks: make(map[string]plugin.Task),
|
||||||
|
db: ic.Meta,
|
||||||
collector: c,
|
collector: c,
|
||||||
store: ic.Content,
|
store: ic.Content,
|
||||||
}, nil
|
}, nil
|
||||||
@ -54,21 +58,22 @@ type Service struct {
|
|||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
|
|
||||||
runtimes map[string]plugin.Runtime
|
runtimes map[string]plugin.Runtime
|
||||||
containers map[string]plugin.Container
|
tasks map[string]plugin.Task
|
||||||
|
db *bolt.DB
|
||||||
collector *collector
|
collector *collector
|
||||||
store content.Store
|
store content.Store
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Register(server *grpc.Server) error {
|
func (s *Service) Register(server *grpc.Server) error {
|
||||||
api.RegisterContainerServiceServer(server, s)
|
api.RegisterTasksServer(server, s)
|
||||||
// load all containers
|
// load all tasks
|
||||||
for _, r := range s.runtimes {
|
for _, r := range s.runtimes {
|
||||||
containers, err := r.Containers(context.Background())
|
tasks, err := r.Tasks(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, c := range containers {
|
for _, c := range tasks {
|
||||||
s.containers[c.Info().ID] = c
|
s.tasks[c.Info().ContainerID] = c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -80,7 +85,7 @@ func (s *Service) Create(ctx context.Context, r *api.CreateRequest) (*api.Create
|
|||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
if r.Checkpoint != nil {
|
if r.Checkpoint != nil {
|
||||||
checkpointPath, err = ioutil.TempDir("", "ctd-checkpoint")
|
checkpointPath, err = ioutil.TempDir("", "ctrd-checkpoint")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -97,8 +102,26 @@ func (s *Service) Create(ctx context.Context, r *api.CreateRequest) (*api.Create
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var container containers.Container
|
||||||
|
if err := s.db.View(func(tx *bolt.Tx) error {
|
||||||
|
store := containers.NewStore(tx)
|
||||||
|
var err error
|
||||||
|
container, err = store.Get(ctx, r.ContainerID)
|
||||||
|
return err
|
||||||
|
}); err != nil {
|
||||||
|
switch {
|
||||||
|
case containers.IsNotFound(err):
|
||||||
|
return nil, grpc.Errorf(codes.NotFound, "container %v not found", r.ContainerID)
|
||||||
|
case containers.IsExists(err):
|
||||||
|
return nil, grpc.Errorf(codes.AlreadyExists, "container %v already exists", r.ContainerID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
opts := plugin.CreateOpts{
|
opts := plugin.CreateOpts{
|
||||||
Spec: r.Spec.Value,
|
Spec: container.Spec,
|
||||||
IO: plugin.IO{
|
IO: plugin.IO{
|
||||||
Stdin: r.Stdin,
|
Stdin: r.Stdin,
|
||||||
Stdout: r.Stdout,
|
Stdout: r.Stdout,
|
||||||
@ -114,38 +137,38 @@ func (s *Service) Create(ctx context.Context, r *api.CreateRequest) (*api.Create
|
|||||||
Options: m.Options,
|
Options: m.Options,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
runtime, err := s.getRuntime(r.Runtime)
|
runtime, err := s.getRuntime(container.Runtime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
if _, ok := s.containers[r.ID]; ok {
|
if _, ok := s.tasks[r.ContainerID]; ok {
|
||||||
s.mu.Unlock()
|
s.mu.Unlock()
|
||||||
return nil, plugin.ErrContainerExists
|
return nil, grpc.Errorf(codes.AlreadyExists, "task %v already exists", r.ContainerID)
|
||||||
}
|
}
|
||||||
c, err := runtime.Create(ctx, r.ID, opts)
|
c, err := runtime.Create(ctx, r.ContainerID, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.mu.Unlock()
|
s.mu.Unlock()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.containers[r.ID] = c
|
s.tasks[r.ContainerID] = c
|
||||||
s.mu.Unlock()
|
s.mu.Unlock()
|
||||||
state, err := c.State(ctx)
|
state, err := c.State(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
delete(s.containers, r.ID)
|
delete(s.tasks, r.ContainerID)
|
||||||
runtime.Delete(ctx, c)
|
runtime.Delete(ctx, c)
|
||||||
s.mu.Unlock()
|
s.mu.Unlock()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &api.CreateResponse{
|
return &api.CreateResponse{
|
||||||
ID: r.ID,
|
ContainerID: r.ContainerID,
|
||||||
Pid: state.Pid(),
|
Pid: state.Pid(),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Start(ctx context.Context, r *api.StartRequest) (*google_protobuf.Empty, error) {
|
func (s *Service) Start(ctx context.Context, r *api.StartRequest) (*google_protobuf.Empty, error) {
|
||||||
c, err := s.getContainer(r.ID)
|
c, err := s.getTask(r.ContainerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -156,7 +179,7 @@ func (s *Service) Start(ctx context.Context, r *api.StartRequest) (*google_proto
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Delete(ctx context.Context, r *api.DeleteRequest) (*api.DeleteResponse, error) {
|
func (s *Service) Delete(ctx context.Context, r *api.DeleteRequest) (*api.DeleteResponse, error) {
|
||||||
c, err := s.getContainer(r.ID)
|
c, err := s.getTask(r.ContainerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -169,7 +192,7 @@ func (s *Service) Delete(ctx context.Context, r *api.DeleteRequest) (*api.Delete
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(s.containers, r.ID)
|
delete(s.tasks, r.ContainerID)
|
||||||
|
|
||||||
return &api.DeleteResponse{
|
return &api.DeleteResponse{
|
||||||
ExitStatus: exit.Status,
|
ExitStatus: exit.Status,
|
||||||
@ -177,26 +200,26 @@ func (s *Service) Delete(ctx context.Context, r *api.DeleteRequest) (*api.Delete
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func containerFromContainerd(ctx context.Context, c plugin.Container) (*container.Container, error) {
|
func taskFromContainerd(ctx context.Context, c plugin.Task) (*task.Task, error) {
|
||||||
state, err := c.State(ctx)
|
state, err := c.State(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var status container.Status
|
var status task.Status
|
||||||
switch state.Status() {
|
switch state.Status() {
|
||||||
case plugin.CreatedStatus:
|
case plugin.CreatedStatus:
|
||||||
status = container.StatusCreated
|
status = task.StatusCreated
|
||||||
case plugin.RunningStatus:
|
case plugin.RunningStatus:
|
||||||
status = container.StatusRunning
|
status = task.StatusRunning
|
||||||
case plugin.StoppedStatus:
|
case plugin.StoppedStatus:
|
||||||
status = container.StatusStopped
|
status = task.StatusStopped
|
||||||
case plugin.PausedStatus:
|
case plugin.PausedStatus:
|
||||||
status = container.StatusPaused
|
status = task.StatusPaused
|
||||||
default:
|
default:
|
||||||
log.G(ctx).WithField("status", state.Status()).Warn("unknown status")
|
log.G(ctx).WithField("status", state.Status()).Warn("unknown status")
|
||||||
}
|
}
|
||||||
return &container.Container{
|
return &task.Task{
|
||||||
ID: c.Info().ID,
|
ID: c.Info().ID,
|
||||||
Pid: state.Pid(),
|
Pid: state.Pid(),
|
||||||
Status: status,
|
Status: status,
|
||||||
@ -207,30 +230,36 @@ func containerFromContainerd(ctx context.Context, c plugin.Container) (*containe
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Info(ctx context.Context, r *api.InfoRequest) (*container.Container, error) {
|
func (s *Service) Info(ctx context.Context, r *api.InfoRequest) (*api.InfoResponse, error) {
|
||||||
c, err := s.getContainer(r.ID)
|
task, err := s.getTask(r.ContainerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return containerFromContainerd(ctx, c)
|
t, err := taskFromContainerd(ctx, task)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &api.InfoResponse{
|
||||||
|
Task: t,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) List(ctx context.Context, r *api.ListRequest) (*api.ListResponse, error) {
|
func (s *Service) List(ctx context.Context, r *api.ListRequest) (*api.ListResponse, error) {
|
||||||
resp := &api.ListResponse{}
|
resp := &api.ListResponse{}
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
defer s.mu.Unlock()
|
defer s.mu.Unlock()
|
||||||
for _, cd := range s.containers {
|
for _, cd := range s.tasks {
|
||||||
c, err := containerFromContainerd(ctx, cd)
|
c, err := taskFromContainerd(ctx, cd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp.Containers = append(resp.Containers, c)
|
resp.Tasks = append(resp.Tasks, c)
|
||||||
}
|
}
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Pause(ctx context.Context, r *api.PauseRequest) (*google_protobuf.Empty, error) {
|
func (s *Service) Pause(ctx context.Context, r *api.PauseRequest) (*google_protobuf.Empty, error) {
|
||||||
c, err := s.getContainer(r.ID)
|
c, err := s.getTask(r.ContainerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -242,7 +271,7 @@ func (s *Service) Pause(ctx context.Context, r *api.PauseRequest) (*google_proto
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Resume(ctx context.Context, r *api.ResumeRequest) (*google_protobuf.Empty, error) {
|
func (s *Service) Resume(ctx context.Context, r *api.ResumeRequest) (*google_protobuf.Empty, error) {
|
||||||
c, err := s.getContainer(r.ID)
|
c, err := s.getTask(r.ContainerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -254,7 +283,7 @@ func (s *Service) Resume(ctx context.Context, r *api.ResumeRequest) (*google_pro
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Kill(ctx context.Context, r *api.KillRequest) (*google_protobuf.Empty, error) {
|
func (s *Service) Kill(ctx context.Context, r *api.KillRequest) (*google_protobuf.Empty, error) {
|
||||||
c, err := s.getContainer(r.ID)
|
c, err := s.getTask(r.ContainerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -275,7 +304,7 @@ func (s *Service) Kill(ctx context.Context, r *api.KillRequest) (*google_protobu
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Processes(ctx context.Context, r *api.ProcessesRequest) (*api.ProcessesResponse, error) {
|
func (s *Service) Processes(ctx context.Context, r *api.ProcessesRequest) (*api.ProcessesResponse, error) {
|
||||||
c, err := s.getContainer(r.ID)
|
c, err := s.getTask(r.ContainerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -285,9 +314,9 @@ func (s *Service) Processes(ctx context.Context, r *api.ProcessesRequest) (*api.
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ps := []*container.Process{}
|
ps := []*task.Process{}
|
||||||
for _, pid := range pids {
|
for _, pid := range pids {
|
||||||
ps = append(ps, &container.Process{
|
ps = append(ps, &task.Process{
|
||||||
Pid: pid,
|
Pid: pid,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -299,7 +328,7 @@ func (s *Service) Processes(ctx context.Context, r *api.ProcessesRequest) (*api.
|
|||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Events(r *api.EventsRequest, server api.ContainerService_EventsServer) error {
|
func (s *Service) Events(r *api.EventsRequest, server api.Tasks_EventsServer) error {
|
||||||
w := &grpcEventWriter{
|
w := &grpcEventWriter{
|
||||||
server: server,
|
server: server,
|
||||||
}
|
}
|
||||||
@ -307,7 +336,7 @@ func (s *Service) Events(r *api.EventsRequest, server api.ContainerService_Event
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Exec(ctx context.Context, r *api.ExecRequest) (*api.ExecResponse, error) {
|
func (s *Service) Exec(ctx context.Context, r *api.ExecRequest) (*api.ExecResponse, error) {
|
||||||
c, err := s.getContainer(r.ID)
|
c, err := s.getTask(r.ContainerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -333,7 +362,7 @@ func (s *Service) Exec(ctx context.Context, r *api.ExecRequest) (*api.ExecRespon
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Pty(ctx context.Context, r *api.PtyRequest) (*google_protobuf.Empty, error) {
|
func (s *Service) Pty(ctx context.Context, r *api.PtyRequest) (*google_protobuf.Empty, error) {
|
||||||
c, err := s.getContainer(r.ID)
|
c, err := s.getTask(r.ContainerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -347,7 +376,7 @@ func (s *Service) Pty(ctx context.Context, r *api.PtyRequest) (*google_protobuf.
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) CloseStdin(ctx context.Context, r *api.CloseStdinRequest) (*google_protobuf.Empty, error) {
|
func (s *Service) CloseStdin(ctx context.Context, r *api.CloseStdinRequest) (*google_protobuf.Empty, error) {
|
||||||
c, err := s.getContainer(r.ID)
|
c, err := s.getTask(r.ContainerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -358,7 +387,7 @@ func (s *Service) CloseStdin(ctx context.Context, r *api.CloseStdinRequest) (*go
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Checkpoint(ctx context.Context, r *api.CheckpointRequest) (*api.CheckpointResponse, error) {
|
func (s *Service) Checkpoint(ctx context.Context, r *api.CheckpointRequest) (*api.CheckpointResponse, error) {
|
||||||
c, err := s.getContainer(r.ID)
|
c, err := s.getTask(r.ContainerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -423,12 +452,12 @@ func (s *Service) writeContent(ctx context.Context, mediaType, ref string, r io.
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) getContainer(id string) (plugin.Container, error) {
|
func (s *Service) getTask(id string) (plugin.Task, error) {
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
c, ok := s.containers[id]
|
c, ok := s.tasks[id]
|
||||||
s.mu.Unlock()
|
s.mu.Unlock()
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, plugin.ErrContainerNotExist
|
return nil, grpc.Errorf(codes.NotFound, "task %v not found", id)
|
||||||
}
|
}
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
@ -442,26 +471,26 @@ func (s *Service) getRuntime(name string) (plugin.Runtime, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type grpcEventWriter struct {
|
type grpcEventWriter struct {
|
||||||
server api.ContainerService_EventsServer
|
server api.Tasks_EventsServer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *grpcEventWriter) Write(e *plugin.Event) error {
|
func (g *grpcEventWriter) Write(e *plugin.Event) error {
|
||||||
var t container.Event_EventType
|
var t task.Event_EventType
|
||||||
switch e.Type {
|
switch e.Type {
|
||||||
case plugin.ExitEvent:
|
case plugin.ExitEvent:
|
||||||
t = container.Event_EXIT
|
t = task.Event_EXIT
|
||||||
case plugin.ExecAddEvent:
|
case plugin.ExecAddEvent:
|
||||||
t = container.Event_EXEC_ADDED
|
t = task.Event_EXEC_ADDED
|
||||||
case plugin.PausedEvent:
|
case plugin.PausedEvent:
|
||||||
t = container.Event_PAUSED
|
t = task.Event_PAUSED
|
||||||
case plugin.CreateEvent:
|
case plugin.CreateEvent:
|
||||||
t = container.Event_CREATE
|
t = task.Event_CREATE
|
||||||
case plugin.StartEvent:
|
case plugin.StartEvent:
|
||||||
t = container.Event_START
|
t = task.Event_START
|
||||||
case plugin.OOMEvent:
|
case plugin.OOMEvent:
|
||||||
t = container.Event_OOM
|
t = task.Event_OOM
|
||||||
}
|
}
|
||||||
return g.server.Send(&container.Event{
|
return g.server.Send(&task.Event{
|
||||||
Type: t,
|
Type: t,
|
||||||
ID: e.ID,
|
ID: e.ID,
|
||||||
Pid: e.Pid,
|
Pid: e.Pid,
|
||||||
|
@ -73,7 +73,7 @@ func (s *Service) Delete(ctx context.Context, req *imagesapi.DeleteRequest) (*em
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) withStore(ctx context.Context, fn func(ctx context.Context, store images.Store) error) func(tx *bolt.Tx) error {
|
func (s *Service) withStore(ctx context.Context, fn func(ctx context.Context, store images.Store) error) func(tx *bolt.Tx) error {
|
||||||
return func(tx *bolt.Tx) error { return fn(ctx, images.NewImageStore(tx)) }
|
return func(tx *bolt.Tx) error { return fn(ctx, images.NewStore(tx)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) withStoreView(ctx context.Context, fn func(ctx context.Context, store images.Store) error) error {
|
func (s *Service) withStoreView(ctx context.Context, fn func(ctx context.Context, store images.Store) error) error {
|
||||||
|
@ -68,8 +68,8 @@ type container struct {
|
|||||||
sendEvent eventCallback
|
sendEvent eventCallback
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *container) Info() plugin.ContainerInfo {
|
func (c *container) Info() plugin.TaskInfo {
|
||||||
return plugin.ContainerInfo{
|
return plugin.TaskInfo{
|
||||||
ID: c.ctr.ID(),
|
ID: c.ctr.ID(),
|
||||||
Runtime: runtimeName,
|
Runtime: runtimeName,
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ type RuntimeSpec struct {
|
|||||||
hcs.Configuration
|
hcs.Configuration
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Runtime) Create(ctx context.Context, id string, opts plugin.CreateOpts) (plugin.Container, error) {
|
func (r *Runtime) Create(ctx context.Context, id string, opts plugin.CreateOpts) (plugin.Task, error) {
|
||||||
var rtSpec RuntimeSpec
|
var rtSpec RuntimeSpec
|
||||||
if err := json.Unmarshal(opts.Spec, &rtSpec); err != nil {
|
if err := json.Unmarshal(opts.Spec, &rtSpec); err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to unmarshal oci spec")
|
return nil, errors.Wrap(err, "failed to unmarshal oci spec")
|
||||||
@ -118,7 +118,7 @@ func (r *Runtime) Create(ctx context.Context, id string, opts plugin.CreateOpts)
|
|||||||
return ctr, nil
|
return ctr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Runtime) Delete(ctx context.Context, c plugin.Container) (*plugin.Exit, error) {
|
func (r *Runtime) Delete(ctx context.Context, c plugin.Task) (*plugin.Exit, error) {
|
||||||
wc, ok := c.(*container)
|
wc, ok := c.(*container)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("container cannot be cast as *windows.container")
|
return nil, fmt.Errorf("container cannot be cast as *windows.container")
|
||||||
@ -140,10 +140,10 @@ func (r *Runtime) Delete(ctx context.Context, c plugin.Container) (*plugin.Exit,
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Runtime) Containers(ctx context.Context) ([]plugin.Container, error) {
|
func (r *Runtime) Tasks(ctx context.Context) ([]plugin.Task, error) {
|
||||||
r.Lock()
|
r.Lock()
|
||||||
defer r.Unlock()
|
defer r.Unlock()
|
||||||
list := make([]plugin.Container, len(r.containers))
|
list := make([]plugin.Task, len(r.containers))
|
||||||
for _, c := range r.containers {
|
for _, c := range r.containers {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
|
Loading…
Reference in New Issue
Block a user