api/services: define the container metadata service
Working from feedback on the existing implementation, we have now introduced a central metadata object to represent the lifecycle and pin the resources required to implement what people today know as containers. This includes the runtime specification and the root filesystem snapshots. We also allow arbitrary labeling of the container. Such provisions will bring the containerd definition of container closer to what is expected by users. The objects that encompass today's ContainerService, centered around the runtime, will be known as tasks. These tasks take on the existing lifecycle behavior of containerd's containers, which means that they are deleted when they exit. Largely, there are no other changes except for naming. The `Container` object will operate purely as a metadata object. No runtime state will be held on `Container`. It only informs the execution service on what is required for creating tasks and the resources in use by that container. The resources referenced by that container will be deleted when the container is deleted, if not in use. In this sense, users can create, list, label and delete containers in a similar way as they do with docker today, without the complexity of runtime locks that plagues current implementations. Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
parent
8f3b89c79d
commit
539742881d
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,7 +317,13 @@ 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)
|
||||||
}
|
}
|
||||||
dAtA[i] = 0x12
|
if len(m.Labels) > 0 {
|
||||||
|
dAtA[i] = 0x12
|
||||||
|
i++
|
||||||
|
i = encodeVarintImages(dAtA, i, uint64(len(m.Labels)))
|
||||||
|
i += copy(dAtA[i:], m.Labels)
|
||||||
|
}
|
||||||
|
dAtA[i] = 0x1a
|
||||||
i++
|
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:])
|
||||||
@ -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,22 +74,22 @@ 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 {
|
||||||
return err
|
return err
|
||||||
|
@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
gocontext "context"
|
gocontext "context"
|
||||||
|
|
||||||
|
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 +14,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 +32,20 @@ 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 {
|
||||||
|
return errors.Wrap(err, "failed to delete 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,8 +49,8 @@ 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,35 @@ 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
|
||||||
|
task, ok := tasksByContainerID[c.ID]
|
||||||
|
if ok {
|
||||||
|
status = task.Status.String()
|
||||||
|
} else {
|
||||||
|
status = "STOPPED" // TODO(stevvooe): Is this assumption correct?
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := fmt.Fprintf(w, "%s\t%s\t%d\t%s\n",
|
||||||
c.ID,
|
c.ID,
|
||||||
c.Pid,
|
c.Image,
|
||||||
c.Status.String(),
|
task.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
|
||||||
},
|
},
|
||||||
|
@ -80,7 +80,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 +93,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 +231,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 +262,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,8 +289,8 @@ 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
|
||||||
}
|
}
|
||||||
|
@ -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{
|
||||||
ID: id,
|
Container: containersapi.Container{
|
||||||
Spec: &protobuf.Any{
|
ID: id,
|
||||||
TypeUrl: specs.Version,
|
Spec: &protobuf.Any{
|
||||||
Value: spec,
|
TypeUrl: specs.Version,
|
||||||
|
Value: spec,
|
||||||
|
},
|
||||||
|
Runtime: context.String("runtime"),
|
||||||
|
RootFS: snapshot,
|
||||||
},
|
},
|
||||||
Runtime: context.String("runtime"),
|
|
||||||
Terminal: context.Bool("tty"),
|
|
||||||
Stdin: filepath.Join(tmpDir, "stdin"),
|
|
||||||
Stdout: filepath.Join(tmpDir, "stdout"),
|
|
||||||
Stderr: filepath.Join(tmpDir, "stderr"),
|
|
||||||
}
|
}
|
||||||
if checkpoint != nil {
|
|
||||||
create.Checkpoint = &descriptor.Descriptor{
|
return create, nil
|
||||||
MediaType: checkpoint.MediaType,
|
}
|
||||||
Size_: checkpoint.Size,
|
|
||||||
Digest: checkpoint.Digest,
|
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"),
|
||||||
|
Stdin: filepath.Join(tmpDir, "stdin"),
|
||||||
|
Stdout: filepath.Join(tmpDir, "stdout"),
|
||||||
|
Stderr: filepath.Join(tmpDir, "stderr"),
|
||||||
}
|
}
|
||||||
|
|
||||||
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,20 +310,29 @@ 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),
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -331,10 +346,10 @@ 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),
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
logrus.WithError(err).Error("resize pty")
|
logrus.WithError(err).Error("resize pty")
|
||||||
}
|
}
|
||||||
|
@ -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,17 +137,28 @@ 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{
|
||||||
ID: id,
|
Container: containersapi.Container{
|
||||||
Spec: &protobuf.Any{
|
ID: id,
|
||||||
TypeUrl: specs.Version,
|
Spec: &protobuf.Any{
|
||||||
Value: spec,
|
TypeUrl: specs.Version,
|
||||||
|
Value: spec,
|
||||||
|
},
|
||||||
|
Runtime: context.String("runtime"),
|
||||||
|
RootFS: snapshot,
|
||||||
},
|
},
|
||||||
Runtime: context.String("runtime"),
|
}
|
||||||
Terminal: context.Bool("tty"),
|
|
||||||
Stdin: fmt.Sprintf(`%s\ctr-%s-stdin`, pipeRoot, id),
|
return create, nil
|
||||||
Stdout: fmt.Sprintf(`%s\ctr-%s-stdout`, pipeRoot, id),
|
}
|
||||||
|
|
||||||
|
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"),
|
||||||
|
Stdin: fmt.Sprintf(`%s\ctr-%s-stdin`, pipeRoot, id),
|
||||||
|
Stdout: fmt.Sprintf(`%s\ctr-%s-stdout`, pipeRoot, id),
|
||||||
}
|
}
|
||||||
if !create.Terminal {
|
if !create.Terminal {
|
||||||
create.Stderr = fmt.Sprintf(`%s\ctr-%s-stderr`, pipeRoot, id)
|
create.Stderr = fmt.Sprintf(`%s\ctr-%s-stderr`, 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,10 +185,10 @@ 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),
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
log.G(ctx).WithError(err).Error("resize pty")
|
log.G(ctx).WithError(err).Error("resize pty")
|
||||||
}
|
}
|
||||||
|
@ -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,8 +126,8 @@ 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
|
||||||
|
}
|
57
containers/storage.go
Normal file
57
containers/storage.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package containers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"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) {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storage) List(ctx context.Context, filter string) ([]Container, error) {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storage) Create(ctx context.Context, container Container) (Container, error) {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storage) Update(ctx context.Context, container Container) (Container, error) {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *storage) Delete(ctx context.Context, id string) error {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
@ -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 create 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,20 +250,22 @@ 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{
|
||||||
shim: s,
|
containerID: id,
|
||||||
spec: data,
|
shim: s,
|
||||||
|
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,
|
shim shim.ShimClient
|
||||||
spec: spec,
|
}
|
||||||
|
|
||||||
|
func newTask(id string, spec []byte, shim shim.ShimClient) *Task {
|
||||||
|
return &Task{
|
||||||
|
containerID: id,
|
||||||
|
shim: shim,
|
||||||
|
spec: spec,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Container struct {
|
func (c *Task) Info() plugin.TaskInfo {
|
||||||
id string
|
return plugin.TaskInfo{
|
||||||
spec []byte
|
ContainerID: c.containerID,
|
||||||
|
Runtime: runtimeName,
|
||||||
shim shim.ShimClient
|
Spec: c.spec,
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Container) Info() plugin.ContainerInfo {
|
|
||||||
return plugin.ContainerInfo{
|
|
||||||
ID: c.id,
|
|
||||||
Runtime: runtimeName,
|
|
||||||
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
|
||||||
Runtime string
|
ContainerID string
|
||||||
Spec []byte
|
Runtime string
|
||||||
|
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,
|
||||||
})
|
})
|
||||||
@ -43,32 +46,34 @@ func New(ic *plugin.InitContext) (interface{}, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &Service{
|
return &Service{
|
||||||
runtimes: ic.Runtimes,
|
runtimes: ic.Runtimes,
|
||||||
containers: make(map[string]plugin.Container),
|
tasks: make(map[string]plugin.Task),
|
||||||
collector: c,
|
db: ic.Meta,
|
||||||
store: ic.Content,
|
collector: c,
|
||||||
|
store: ic.Content,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type Service struct {
|
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
|
||||||
collector *collector
|
db *bolt.DB
|
||||||
store content.Store
|
collector *collector
|
||||||
|
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, plugin.ErrContainerExists
|
||||||
}
|
}
|
||||||
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,9 +452,9 @@ 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, plugin.ErrContainerNotExist
|
||||||
@ -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