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