diff --git a/api/services/rootfs/rootfs.pb.go b/api/services/rootfs/rootfs.pb.go index 6362050..2a04ade 100644 --- a/api/services/rootfs/rootfs.pb.go +++ b/api/services/rootfs/rootfs.pb.go @@ -11,6 +11,9 @@ It has these top-level messages: PrepareRequest PrepareResponse + InitMountsRequest + MountsRequest + MountResponse */ package rootfs @@ -18,8 +21,7 @@ import proto "github.com/gogo/protobuf/proto" import fmt "fmt" import math "math" import _ "github.com/gogo/protobuf/gogoproto" -import _ "github.com/golang/protobuf/ptypes/empty" -import _ "github.com/docker/containerd/api/types/mount" +import containerd_v1_types "github.com/docker/containerd/api/types/mount" import containerd_v1_types1 "github.com/docker/containerd/api/types/descriptor" import github_com_opencontainers_go_digest "github.com/opencontainers/go-digest" @@ -61,9 +63,38 @@ func (m *PrepareResponse) Reset() { *m = PrepareResponse{} } func (*PrepareResponse) ProtoMessage() {} func (*PrepareResponse) Descriptor() ([]byte, []int) { return fileDescriptorRootfs, []int{1} } +type InitMountsRequest struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + ChainID github_com_opencontainers_go_digest.Digest `protobuf:"bytes,2,opt,name=chainID,proto3,customtype=github.com/opencontainers/go-digest.Digest" json:"chainID"` + Readonly bool `protobuf:"varint,3,opt,name=Readonly,proto3" json:"Readonly,omitempty"` +} + +func (m *InitMountsRequest) Reset() { *m = InitMountsRequest{} } +func (*InitMountsRequest) ProtoMessage() {} +func (*InitMountsRequest) Descriptor() ([]byte, []int) { return fileDescriptorRootfs, []int{2} } + +type MountsRequest struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (m *MountsRequest) Reset() { *m = MountsRequest{} } +func (*MountsRequest) ProtoMessage() {} +func (*MountsRequest) Descriptor() ([]byte, []int) { return fileDescriptorRootfs, []int{3} } + +type MountResponse struct { + Mounts []*containerd_v1_types.Mount `protobuf:"bytes,1,rep,name=mounts" json:"mounts,omitempty"` +} + +func (m *MountResponse) Reset() { *m = MountResponse{} } +func (*MountResponse) ProtoMessage() {} +func (*MountResponse) Descriptor() ([]byte, []int) { return fileDescriptorRootfs, []int{4} } + func init() { proto.RegisterType((*PrepareRequest)(nil), "containerd.v1.PrepareRequest") proto.RegisterType((*PrepareResponse)(nil), "containerd.v1.PrepareResponse") + proto.RegisterType((*InitMountsRequest)(nil), "containerd.v1.InitMountsRequest") + proto.RegisterType((*MountsRequest)(nil), "containerd.v1.MountsRequest") + proto.RegisterType((*MountResponse)(nil), "containerd.v1.MountResponse") } // Reference imports to suppress errors if they are not otherwise used. @@ -78,6 +109,8 @@ const _ = grpc.SupportPackageIsVersion4 type RootFSClient interface { Prepare(ctx context.Context, in *PrepareRequest, opts ...grpc.CallOption) (*PrepareResponse, error) + InitMounts(ctx context.Context, in *InitMountsRequest, opts ...grpc.CallOption) (*MountResponse, error) + Mounts(ctx context.Context, in *MountsRequest, opts ...grpc.CallOption) (*MountResponse, error) } type rootFSClient struct { @@ -97,10 +130,30 @@ func (c *rootFSClient) Prepare(ctx context.Context, in *PrepareRequest, opts ... return out, nil } +func (c *rootFSClient) InitMounts(ctx context.Context, in *InitMountsRequest, opts ...grpc.CallOption) (*MountResponse, error) { + out := new(MountResponse) + err := grpc.Invoke(ctx, "/containerd.v1.RootFS/InitMounts", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *rootFSClient) Mounts(ctx context.Context, in *MountsRequest, opts ...grpc.CallOption) (*MountResponse, error) { + out := new(MountResponse) + err := grpc.Invoke(ctx, "/containerd.v1.RootFS/Mounts", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // Server API for RootFS service type RootFSServer interface { Prepare(context.Context, *PrepareRequest) (*PrepareResponse, error) + InitMounts(context.Context, *InitMountsRequest) (*MountResponse, error) + Mounts(context.Context, *MountsRequest) (*MountResponse, error) } func RegisterRootFSServer(s *grpc.Server, srv RootFSServer) { @@ -125,6 +178,42 @@ func _RootFS_Prepare_Handler(srv interface{}, ctx context.Context, dec func(inte return interceptor(ctx, in, info, handler) } +func _RootFS_InitMounts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(InitMountsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RootFSServer).InitMounts(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/containerd.v1.RootFS/InitMounts", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RootFSServer).InitMounts(ctx, req.(*InitMountsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _RootFS_Mounts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MountsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RootFSServer).Mounts(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/containerd.v1.RootFS/Mounts", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RootFSServer).Mounts(ctx, req.(*MountsRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _RootFS_serviceDesc = grpc.ServiceDesc{ ServiceName: "containerd.v1.RootFS", HandlerType: (*RootFSServer)(nil), @@ -133,6 +222,14 @@ var _RootFS_serviceDesc = grpc.ServiceDesc{ MethodName: "Prepare", Handler: _RootFS_Prepare_Handler, }, + { + MethodName: "InitMounts", + Handler: _RootFS_InitMounts_Handler, + }, + { + MethodName: "Mounts", + Handler: _RootFS_Mounts_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "github.com/docker/containerd/api/services/rootfs/rootfs.proto", @@ -192,6 +289,100 @@ func (m *PrepareResponse) MarshalTo(dAtA []byte) (int, error) { return i, nil } +func (m *InitMountsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *InitMountsRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Name) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintRootfs(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + } + if len(m.ChainID) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintRootfs(dAtA, i, uint64(len(m.ChainID))) + i += copy(dAtA[i:], m.ChainID) + } + if m.Readonly { + dAtA[i] = 0x18 + i++ + if m.Readonly { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i++ + } + return i, nil +} + +func (m *MountsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MountsRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Name) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintRootfs(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + } + return i, nil +} + +func (m *MountResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MountResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Mounts) > 0 { + for _, msg := range m.Mounts { + dAtA[i] = 0xa + i++ + i = encodeVarintRootfs(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + func encodeFixed64Rootfs(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) dAtA[offset+1] = uint8(v >> 8) @@ -241,6 +432,45 @@ func (m *PrepareResponse) Size() (n int) { return n } +func (m *InitMountsRequest) Size() (n int) { + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovRootfs(uint64(l)) + } + l = len(m.ChainID) + if l > 0 { + n += 1 + l + sovRootfs(uint64(l)) + } + if m.Readonly { + n += 2 + } + return n +} + +func (m *MountsRequest) Size() (n int) { + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovRootfs(uint64(l)) + } + return n +} + +func (m *MountResponse) Size() (n int) { + var l int + _ = l + if len(m.Mounts) > 0 { + for _, e := range m.Mounts { + l = e.Size() + n += 1 + l + sovRootfs(uint64(l)) + } + } + return n +} + func sovRootfs(x uint64) (n int) { for { n++ @@ -274,6 +504,38 @@ func (this *PrepareResponse) String() string { }, "") return s } +func (this *InitMountsRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&InitMountsRequest{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `ChainID:` + fmt.Sprintf("%v", this.ChainID) + `,`, + `Readonly:` + fmt.Sprintf("%v", this.Readonly) + `,`, + `}`, + }, "") + return s +} +func (this *MountsRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&MountsRequest{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `}`, + }, "") + return s +} +func (this *MountResponse) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&MountResponse{`, + `Mounts:` + strings.Replace(fmt.Sprintf("%v", this.Mounts), "Mount", "containerd_v1_types.Mount", 1) + `,`, + `}`, + }, "") + return s +} func valueToStringRootfs(v interface{}) string { rv := reflect.ValueOf(v) if rv.IsNil() { @@ -442,6 +704,294 @@ func (m *PrepareResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *InitMountsRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRootfs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: InitMountsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: InitMountsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRootfs + } + 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 ErrInvalidLengthRootfs + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRootfs + } + 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 ErrInvalidLengthRootfs + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChainID = github_com_opencontainers_go_digest.Digest(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Readonly", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRootfs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Readonly = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipRootfs(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRootfs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MountsRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRootfs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MountsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MountsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRootfs + } + 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 ErrInvalidLengthRootfs + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRootfs(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRootfs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MountResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRootfs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MountResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MountResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Mounts", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRootfs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRootfs + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Mounts = append(m.Mounts, &containerd_v1_types.Mount{}) + if err := m.Mounts[len(m.Mounts)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRootfs(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRootfs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipRootfs(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 @@ -552,26 +1102,32 @@ func init() { } var fileDescriptorRootfs = []byte{ - // 335 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x90, 0xc1, 0x4f, 0xea, 0x40, - 0x10, 0xc6, 0xd9, 0xbc, 0x04, 0xf2, 0xf6, 0xe5, 0xbd, 0x97, 0x34, 0x1e, 0x08, 0xc6, 0x2d, 0xe1, - 0x44, 0x4c, 0xdc, 0x8d, 0x78, 0xd0, 0x0b, 0x17, 0x24, 0x46, 0x6e, 0xa6, 0x1e, 0x3c, 0x97, 0x76, - 0x58, 0x56, 0xa1, 0xb3, 0xee, 0x6e, 0x49, 0xb8, 0xf9, 0xe7, 0x71, 0xf4, 0x68, 0x3c, 0x10, 0xe9, - 0x5f, 0x62, 0x68, 0x0b, 0x82, 0x89, 0xd1, 0x4b, 0x67, 0x9a, 0xef, 0x9b, 0xdf, 0x7c, 0xb3, 0xb4, - 0x2b, 0x95, 0x1b, 0xa7, 0x43, 0x1e, 0xe1, 0x54, 0xc4, 0x18, 0x3d, 0x80, 0x11, 0x11, 0x26, 0x2e, - 0x54, 0x09, 0x98, 0x58, 0x84, 0x5a, 0x09, 0x0b, 0x66, 0xa6, 0x22, 0xb0, 0xc2, 0x20, 0xba, 0xd1, - 0xa6, 0x70, 0x6d, 0xd0, 0xa1, 0xf7, 0xf7, 0xc3, 0xcc, 0x67, 0xa7, 0x8d, 0x03, 0x89, 0x12, 0x73, - 0x45, 0xac, 0xbb, 0xc2, 0xd4, 0x38, 0x94, 0x88, 0x72, 0x02, 0x22, 0xff, 0x1b, 0xa6, 0x23, 0x01, - 0x53, 0xed, 0xe6, 0xa5, 0x78, 0xf1, 0x6d, 0x00, 0x37, 0xd7, 0x60, 0xc5, 0x14, 0xd3, 0xc4, 0x15, - 0xdf, 0x72, 0xb2, 0xf7, 0xc3, 0xc9, 0x18, 0x6c, 0x64, 0x94, 0x76, 0x68, 0x76, 0xda, 0x82, 0xd1, - 0x1a, 0xd0, 0x7f, 0x37, 0x06, 0x74, 0x68, 0x20, 0x80, 0xc7, 0x14, 0xac, 0xf3, 0xce, 0x69, 0x75, - 0x12, 0xce, 0xc1, 0xd8, 0x3a, 0x69, 0xfe, 0x6a, 0xff, 0xe9, 0xf8, 0x7c, 0xef, 0x44, 0x9e, 0x33, - 0x79, 0x7f, 0x0b, 0x0a, 0x4a, 0x7b, 0xeb, 0x9e, 0xfe, 0xdf, 0xa2, 0xac, 0xc6, 0xc4, 0x82, 0x77, - 0x47, 0x6b, 0xd1, 0x38, 0x54, 0x89, 0x8a, 0xeb, 0xa4, 0x49, 0xda, 0xbf, 0x7b, 0xdd, 0xc5, 0xd2, - 0xaf, 0xbc, 0x2e, 0xfd, 0xe3, 0x9d, 0xe8, 0xa8, 0x21, 0xd9, 0xae, 0xb0, 0x42, 0xe2, 0x49, 0xac, - 0x24, 0x58, 0xc7, 0xfb, 0x79, 0xc9, 0x96, 0x7e, 0xed, 0x72, 0x0d, 0x19, 0xf4, 0x83, 0x0d, 0xad, - 0x13, 0xd0, 0x6a, 0x80, 0xe8, 0xae, 0x6e, 0xbd, 0x6b, 0x5a, 0x2b, 0xb7, 0x7a, 0x47, 0x9f, 0x92, - 0xee, 0x1f, 0xd6, 0x60, 0x5f, 0xc9, 0x45, 0xd8, 0x5e, 0x7d, 0xb1, 0x62, 0x95, 0x97, 0x15, 0xab, - 0x3c, 0x65, 0x8c, 0x2c, 0x32, 0x46, 0x9e, 0x33, 0x46, 0xde, 0x32, 0x46, 0x86, 0xd5, 0xfc, 0xad, - 0xce, 0xde, 0x03, 0x00, 0x00, 0xff, 0xff, 0x4c, 0xa2, 0x59, 0x7e, 0x2c, 0x02, 0x00, 0x00, + // 428 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x92, 0x3f, 0x8f, 0xd3, 0x30, + 0x18, 0xc6, 0x6b, 0x0e, 0xa5, 0x87, 0xd1, 0x81, 0xb0, 0x18, 0xa2, 0x08, 0x92, 0x28, 0x2c, 0x15, + 0x12, 0xb1, 0x28, 0x03, 0x2c, 0xb7, 0xf4, 0x22, 0x44, 0x24, 0x90, 0x50, 0x18, 0x98, 0x73, 0xc9, + 0x4b, 0xce, 0x70, 0xf5, 0x1b, 0x6c, 0xf7, 0xa4, 0x6e, 0x7c, 0x10, 0x3e, 0x50, 0x47, 0x46, 0xc4, + 0x50, 0x71, 0x19, 0xf8, 0x1c, 0xa8, 0xf9, 0x77, 0xd7, 0x52, 0xd4, 0x0e, 0xb7, 0xc4, 0x6f, 0xe4, + 0xe7, 0xfd, 0xbd, 0x8f, 0x1f, 0x9b, 0x1e, 0x17, 0xc2, 0x9c, 0xcd, 0x4e, 0xc3, 0x0c, 0xa7, 0x3c, + 0xc7, 0xec, 0x0b, 0x28, 0x9e, 0xa1, 0x34, 0xa9, 0x90, 0xa0, 0x72, 0x9e, 0x96, 0x82, 0x6b, 0x50, + 0x17, 0x22, 0x03, 0xcd, 0x15, 0xa2, 0xf9, 0xd4, 0x2d, 0x61, 0xa9, 0xd0, 0x20, 0x3b, 0xba, 0x12, + 0x87, 0x17, 0xcf, 0x9d, 0x87, 0x05, 0x16, 0x58, 0xef, 0xf0, 0x55, 0xd5, 0x88, 0x9c, 0x57, 0x3b, + 0x67, 0x98, 0x79, 0x09, 0x9a, 0x4f, 0x71, 0x26, 0x4d, 0xf3, 0x6d, 0x3b, 0x27, 0x7b, 0x76, 0xe6, + 0xa0, 0x33, 0x25, 0x4a, 0x83, 0xea, 0x5a, 0xd9, 0x30, 0x82, 0x98, 0xde, 0x7b, 0xaf, 0xa0, 0x4c, + 0x15, 0x24, 0xf0, 0x75, 0x06, 0xda, 0xb0, 0x97, 0xd4, 0x3a, 0x4f, 0xe7, 0xa0, 0xb4, 0x4d, 0xfc, + 0x83, 0xd1, 0xdd, 0xb1, 0x17, 0xae, 0x9d, 0x22, 0xac, 0x99, 0x61, 0xd4, 0x83, 0x92, 0x56, 0x1e, + 0x7c, 0xa6, 0xf7, 0x7b, 0x94, 0x2e, 0x51, 0x6a, 0x60, 0x1f, 0xe9, 0x30, 0x3b, 0x4b, 0x85, 0x14, + 0xb9, 0x4d, 0x7c, 0x32, 0xba, 0x33, 0x39, 0x5e, 0x2c, 0xbd, 0xc1, 0xaf, 0xa5, 0xf7, 0xf4, 0x9a, + 0x75, 0x2c, 0x41, 0xf6, 0x23, 0x34, 0x2f, 0xf0, 0x59, 0x2e, 0x0a, 0xd0, 0x26, 0x8c, 0xea, 0xa5, + 0x5a, 0x7a, 0xc3, 0x93, 0x15, 0x24, 0x8e, 0x92, 0x8e, 0x16, 0x7c, 0x27, 0xf4, 0x41, 0x2c, 0x85, + 0x79, 0xb7, 0x8a, 0x43, 0x77, 0xd6, 0x19, 0xbd, 0x2d, 0xd3, 0x29, 0x34, 0xb3, 0x92, 0xba, 0xee, + 0x2d, 0xc4, 0x91, 0x7d, 0xeb, 0xe6, 0x2c, 0xc4, 0x11, 0x73, 0xe8, 0x61, 0x02, 0x69, 0x8e, 0xf2, + 0x7c, 0x6e, 0x1f, 0xf8, 0x64, 0x74, 0x98, 0xf4, 0xff, 0xc1, 0x13, 0x7a, 0xb4, 0xd3, 0x59, 0x70, + 0xd2, 0x8a, 0xfa, 0xb4, 0xc6, 0xd4, 0xaa, 0xaf, 0xb7, 0x4b, 0xde, 0xd9, 0x9a, 0x7c, 0xd3, 0xd3, + 0x2a, 0xc7, 0x7f, 0x08, 0xb5, 0x12, 0x44, 0xf3, 0xfa, 0x03, 0x7b, 0x43, 0x87, 0x6d, 0xfe, 0xec, + 0xf1, 0x46, 0xe7, 0xfa, 0x15, 0x3b, 0xee, 0xff, 0xb6, 0x5b, 0x23, 0x6f, 0x29, 0xbd, 0x0a, 0x97, + 0xf9, 0x1b, 0xea, 0x7f, 0x72, 0x77, 0x1e, 0x6d, 0x28, 0xd6, 0x8f, 0x15, 0x51, 0xab, 0x25, 0x6d, + 0xd5, 0xed, 0x47, 0x99, 0xd8, 0x8b, 0x4b, 0x77, 0xf0, 0xf3, 0xd2, 0x1d, 0x7c, 0xab, 0x5c, 0xb2, + 0xa8, 0x5c, 0xf2, 0xa3, 0x72, 0xc9, 0xef, 0xca, 0x25, 0xa7, 0x56, 0xfd, 0x92, 0x5f, 0xfc, 0x0d, + 0x00, 0x00, 0xff, 0xff, 0xca, 0x73, 0x7a, 0x14, 0xad, 0x03, 0x00, 0x00, } diff --git a/api/services/rootfs/rootfs.proto b/api/services/rootfs/rootfs.proto index 866f78a..190e88d 100644 --- a/api/services/rootfs/rootfs.proto +++ b/api/services/rootfs/rootfs.proto @@ -3,16 +3,13 @@ syntax = "proto3"; package containerd.v1; import "gogoproto/gogo.proto"; -import "google/protobuf/empty.proto"; import "github.com/docker/containerd/api/types/mount/mount.proto"; import "github.com/docker/containerd/api/types/descriptor/descriptor.proto"; service RootFS { rpc Prepare(PrepareRequest) returns (PrepareResponse); - - // TODO: Add method for initializing and retrieving mounts - //rpc InitMounts(InitRequest) returns (MountResponse); - //rpc Mounts(MountRequest) returns (MountResponse); + rpc InitMounts(InitMountsRequest) returns (MountResponse); + rpc Mounts(MountsRequest) returns (MountResponse); } message PrepareRequest { @@ -23,16 +20,16 @@ message PrepareResponse { string chainid = 1 [(gogoproto.customtype) = "github.com/opencontainers/go-digest.Digest", (gogoproto.nullable) = false, (gogoproto.customname) = "ChainID"]; } -//message InitRequest { -// string name = 1; -// string chainID = 2; -// bool Readonly = 3; -//} -// -//message MountRequest { -// string name = 1; -//} -// -//message MountResponse { -// repeated containerd.v1.types.Mount mounts = 1; -//} +message InitMountsRequest { + string name = 1; + string chainID = 2 [(gogoproto.customtype) = "github.com/opencontainers/go-digest.Digest", (gogoproto.nullable) = false, (gogoproto.customname) = "ChainID"]; + bool Readonly = 3; +} + +message MountsRequest { + string name = 1; +} + +message MountResponse { + repeated containerd.v1.types.Mount mounts = 1; +} diff --git a/rootfs/init.go b/rootfs/init.go new file mode 100644 index 0000000..e2fe777 --- /dev/null +++ b/rootfs/init.go @@ -0,0 +1,98 @@ +package rootfs + +import ( + "context" + "fmt" + "io/ioutil" + "os" + + "github.com/docker/containerd" + "github.com/docker/containerd/log" + "github.com/docker/containerd/snapshot" + digest "github.com/opencontainers/go-digest" + "github.com/pkg/errors" +) + +var ( + initializers = map[string]initializerFunc{} +) + +type initializerFunc func(string) error + +func InitRootFS(ctx context.Context, name string, parent digest.Digest, readonly bool, snapshotter snapshot.Snapshotter, mounter Mounter) ([]containerd.Mount, error) { + _, err := snapshotter.Stat(ctx, name) + if err == nil { + return nil, errors.Errorf("rootfs already exists") + } + // TODO: check if should return error + + parentS := parent.String() + + initName := defaultInitializer + initFn := initializers[initName] + if initFn != nil { + parentS, err = createInitLayer(ctx, parentS, initName, initFn, snapshotter, mounter) + if err != nil { + return nil, err + } + } + + if readonly { + return snapshotter.View(ctx, name, parentS) + } + + return snapshotter.Prepare(ctx, name, parentS) +} + +func GetRootFS(ctx context.Context, name string, snapshotter snapshot.Snapshotter) ([]containerd.Mount, error) { + return snapshotter.Mounts(ctx, name) +} + +func createInitLayer(ctx context.Context, parent, initName string, initFn func(string) error, snapshotter snapshot.Snapshotter, mounter Mounter) (string, error) { + initS := fmt.Sprintf("%s %s", parent, initName) + if _, err := snapshotter.Stat(ctx, initS); err == nil { + return initS, nil + } + // TODO: check if should return error + + // Create tempdir + td, err := ioutil.TempDir("", "create-init-") + if err != nil { + return "", err + } + defer os.RemoveAll(td) + + mounts, err := snapshotter.Prepare(ctx, td, parent) + if err != nil { + return "", err + } + defer func() { + if err != nil { + // TODO: once implemented uncomment + //if rerr := snapshotter.Remove(ctx, td); rerr != nil { + // log.G(ctx).Errorf("Failed to remove snapshot %s: %v", td, merr) + //} + } + }() + + if err = mounter.Mount(td, mounts...); err != nil { + return "", err + } + + if err = initFn(td); err != nil { + if merr := mounter.Unmount(td); merr != nil { + log.G(ctx).Errorf("Failed to unmount %s: %v", td, merr) + } + return "", err + } + + if err = mounter.Unmount(td); err != nil { + return "", err + } + + if err := snapshotter.Commit(ctx, initS, td); err != nil { + return "", err + } + + return initS, nil +} diff --git a/rootfs/init_linux.go b/rootfs/init_linux.go new file mode 100644 index 0000000..cabc457 --- /dev/null +++ b/rootfs/init_linux.go @@ -0,0 +1,114 @@ +package rootfs + +import ( + "os" + "path/filepath" + "syscall" +) + +const ( + defaultInitializer = "linux-init" +) + +func init() { + initializers[defaultInitializer] = initFS +} + +func createDirectory(name string, uid, gid int) initializerFunc { + return func(root string) error { + dname := filepath.Join(root, name) + st, err := os.Stat(dname) + if err != nil && !os.IsNotExist(err) { + return err + } else if err == nil { + if st.IsDir() { + stat := st.Sys().(*syscall.Stat_t) + if int(stat.Gid) == gid && int(stat.Uid) == uid { + return nil + } + } else { + if err := os.Remove(dname); err != nil { + return err + } + if err := os.Mkdir(dname, 0755); err != nil { + return err + } + } + } else { + if err := os.Mkdir(dname, 0755); err != nil { + return err + } + } + + return os.Chown(dname, uid, gid) + } +} + +func touchFile(name string, uid, gid int) initializerFunc { + return func(root string) error { + fname := filepath.Join(root, name) + + st, err := os.Stat(fname) + if err != nil && !os.IsNotExist(err) { + return err + } else if err == nil { + stat := st.Sys().(*syscall.Stat_t) + if int(stat.Gid) == gid && int(stat.Uid) == uid { + return nil + } + return os.Chown(fname, uid, gid) + } + + f, err := os.OpenFile(fname, os.O_CREATE, 0644) + if err != nil { + return err + } + defer f.Close() + + return f.Chown(uid, gid) + } +} + +func symlink(oldname, newname string) initializerFunc { + return func(root string) error { + linkName := filepath.Join(root, newname) + if _, err := os.Stat(linkName); err != nil && !os.IsNotExist(err) { + return err + } else if err == nil { + return nil + } + return os.Symlink(oldname, linkName) + } +} + +func initFS(root string) error { + st, err := os.Stat(root) + if err != nil { + return err + } + stat := st.Sys().(*syscall.Stat_t) + uid := int(stat.Uid) + gid := int(stat.Gid) + + initFuncs := []initializerFunc{ + createDirectory("/dev", uid, gid), + createDirectory("/dev/pts", uid, gid), + createDirectory("/dev/shm", uid, gid), + touchFile("/dev/console", uid, gid), + createDirectory("/proc", uid, gid), + createDirectory("/sys", uid, gid), + createDirectory("/etc", uid, gid), + touchFile("/etc/resolv.conf", uid, gid), + touchFile("/etc/hosts", uid, gid), + touchFile("/etc/hostname", uid, gid), + symlink("/proc/mounts", "/etc/mtab"), + } + + for _, fn := range initFuncs { + if err := fn(root); err != nil { + return err + } + } + + return nil +} diff --git a/rootfs/init_other.go b/rootfs/init_other.go new file mode 100644 index 0000000..b5e04e2 --- /dev/null +++ b/rootfs/init_other.go @@ -0,0 +1,7 @@ +// +build !linux + +package rootfs + +const ( + defaultInitializer = "" +) diff --git a/services/rootfs/service.go b/services/rootfs/service.go index 817cbf1..ab6cb72 100644 --- a/services/rootfs/service.go +++ b/services/rootfs/service.go @@ -5,6 +5,7 @@ import ( "github.com/docker/containerd" rootfsapi "github.com/docker/containerd/api/services/rootfs" + containerd_v1_types "github.com/docker/containerd/api/types/mount" "github.com/docker/containerd/content" "github.com/docker/containerd/log" "github.com/docker/containerd/plugin" @@ -63,6 +64,38 @@ func (s *Service) Prepare(ctx context.Context, pr *rootfsapi.PrepareRequest) (*r }, nil } +func (s *Service) InitMounts(ctx context.Context, ir *rootfsapi.InitMountsRequest) (*rootfsapi.MountResponse, error) { + mounts, err := rootfs.InitRootFS(ctx, ir.Name, ir.ChainID, ir.Readonly, s.snapshotter, mounter{}) + if err != nil { + return nil, err + } + return &rootfsapi.MountResponse{ + Mounts: apiMounts(mounts), + }, nil +} + +func (s *Service) Mounts(ctx context.Context, mr *rootfsapi.MountsRequest) (*rootfsapi.MountResponse, error) { + mounts, err := rootfs.GetRootFS(ctx, mr.Name, s.snapshotter) + if err != nil { + return nil, err + } + return &rootfsapi.MountResponse{ + Mounts: apiMounts(mounts), + }, nil +} + +func apiMounts(mounts []containerd.Mount) []*containerd_v1_types.Mount { + am := make([]*containerd_v1_types.Mount, len(mounts)) + for i, m := range mounts { + am[i] = &containerd_v1_types.Mount{ + Type: m.Type, + Source: m.Source, + Options: m.Options, + } + } + return am +} + type mounter struct{} func (mounter) Mount(dir string, mounts ...containerd.Mount) error { @@ -80,7 +113,3 @@ func emptyResolver(digest.Digest) digest.Digest { func noopRegister(digest.Digest, digest.Digest) error { return nil } - -//func (s *Service) Mounts(ctx context.Context, mr *rootfsapi.MountRequest) (*rootfsapi.MountResponse, error) { -// -//}