Add field to Container for client-defined data

This field allows a client to store specialized information in the
container metadata rather than having to store this itself and keep
the data in sync with containerd.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
This commit is contained in:
Brian Goff 2017-08-17 15:22:46 -04:00
parent d0457b2213
commit 3552ce5688
12 changed files with 350 additions and 48 deletions

View File

@ -185,6 +185,17 @@ file {
}
json_name: "updatedAt"
}
field {
name: "extensions"
number: 10
label: LABEL_REPEATED
type: TYPE_MESSAGE
type_name: ".google.protobuf.Any"
options {
65001: 0
}
json_name: "extensions"
}
nested_type {
name: "LabelsEntry"
field {

View File

@ -94,6 +94,11 @@ type Container struct {
CreatedAt time.Time `protobuf:"bytes,8,opt,name=created_at,json=createdAt,stdtime" json:"created_at"`
// UpdatedAt is the last time the container was mutated.
UpdatedAt time.Time `protobuf:"bytes,9,opt,name=updated_at,json=updatedAt,stdtime" json:"updated_at"`
// Extensions allow clients to provide zero or more blobs that are directly
// associated with the container. One may provide protobuf, json, or other
// encoding formats. The primary use of this is to further decorate the
// container object with fields that may be specific to a client integration.
Extensions []google_protobuf1.Any `protobuf:"bytes,10,rep,name=extensions" json:"extensions"`
}
func (m *Container) Reset() { *m = Container{} }
@ -518,6 +523,18 @@ func (m *Container) MarshalTo(dAtA []byte) (int, error) {
return 0, err
}
i += n4
if len(m.Extensions) > 0 {
for _, msg := range m.Extensions {
dAtA[i] = 0x52
i++
i = encodeVarintContainers(dAtA, i, uint64(msg.Size()))
n, err := msg.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n
}
}
return i, nil
}
@ -872,6 +889,12 @@ func (m *Container) Size() (n int) {
n += 1 + l + sovContainers(uint64(l))
l = github_com_gogo_protobuf_types.SizeOfStdTime(m.UpdatedAt)
n += 1 + l + sovContainers(uint64(l))
if len(m.Extensions) > 0 {
for _, e := range m.Extensions {
l = e.Size()
n += 1 + l + sovContainers(uint64(l))
}
}
return n
}
@ -1014,6 +1037,7 @@ func (this *Container) String() string {
`SnapshotKey:` + fmt.Sprintf("%v", this.SnapshotKey) + `,`,
`CreatedAt:` + strings.Replace(strings.Replace(this.CreatedAt.String(), "Timestamp", "google_protobuf4.Timestamp", 1), `&`, ``, 1) + `,`,
`UpdatedAt:` + strings.Replace(strings.Replace(this.UpdatedAt.String(), "Timestamp", "google_protobuf4.Timestamp", 1), `&`, ``, 1) + `,`,
`Extensions:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Extensions), "Any", "google_protobuf1.Any", 1), `&`, ``, 1) + `,`,
`}`,
}, "")
return s
@ -1515,6 +1539,37 @@ func (m *Container) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
case 10:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Extensions", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowContainers
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthContainers
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Extensions = append(m.Extensions, google_protobuf1.Any{})
if err := m.Extensions[len(m.Extensions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipContainers(dAtA[iNdEx:])
@ -2509,51 +2564,52 @@ func init() {
}
var fileDescriptorContainers = []byte{
// 730 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xcb, 0x72, 0x12, 0x41,
0x14, 0xcd, 0xc0, 0x04, 0xc2, 0xc5, 0x85, 0xd5, 0x22, 0x8e, 0x63, 0x15, 0x10, 0x56, 0x2c, 0x74,
0x30, 0x68, 0x69, 0x1e, 0xab, 0x90, 0x57, 0x59, 0x26, 0x56, 0xaa, 0x4b, 0x37, 0xba, 0x88, 0x0d,
0x74, 0xc8, 0xc8, 0xbc, 0x9c, 0x6e, 0xa8, 0xa2, 0x5c, 0xe8, 0x27, 0xf8, 0x17, 0xfe, 0x4a, 0x96,
0x2e, 0x5d, 0xc5, 0x84, 0x2f, 0xb1, 0xba, 0x67, 0x26, 0x43, 0x78, 0x94, 0x10, 0x65, 0x77, 0x2f,
0x7d, 0xcf, 0xbd, 0x67, 0x4e, 0x9f, 0x3b, 0x0c, 0x1c, 0xb6, 0x4d, 0x7e, 0xd6, 0x6d, 0x18, 0x4d,
0xd7, 0xae, 0x36, 0x5d, 0x87, 0x13, 0xd3, 0xa1, 0x7e, 0x6b, 0x38, 0x24, 0x9e, 0x59, 0x65, 0xd4,
0xef, 0x99, 0x4d, 0xca, 0xe2, 0xdf, 0x59, 0xb5, 0xb7, 0x36, 0x94, 0x19, 0x9e, 0xef, 0x72, 0x17,
0xad, 0xc6, 0x38, 0x23, 0xc2, 0x18, 0x43, 0x55, 0xbd, 0x35, 0x3d, 0xd7, 0x76, 0xdb, 0xae, 0xac,
0xae, 0x8a, 0x28, 0x00, 0xea, 0x0f, 0xdb, 0xae, 0xdb, 0xb6, 0x68, 0x55, 0x66, 0x8d, 0xee, 0x69,
0x95, 0x38, 0xfd, 0xf0, 0xe8, 0xd1, 0xe8, 0x11, 0xb5, 0x3d, 0x1e, 0x1d, 0x96, 0x46, 0x0f, 0x4f,
0x4d, 0x6a, 0xb5, 0x4e, 0x6c, 0xc2, 0x3a, 0x61, 0x45, 0x71, 0xb4, 0x82, 0x9b, 0x36, 0x65, 0x9c,
0xd8, 0x5e, 0x50, 0x50, 0xbe, 0x50, 0x21, 0xb3, 0x13, 0x51, 0x44, 0x79, 0x48, 0x98, 0x2d, 0x4d,
0x29, 0x29, 0x95, 0x4c, 0x3d, 0x35, 0xb8, 0x28, 0x26, 0x5e, 0xed, 0xe2, 0x84, 0xd9, 0x42, 0xc7,
0x90, 0xb2, 0x48, 0x83, 0x5a, 0x4c, 0x4b, 0x94, 0x92, 0x95, 0x6c, 0x6d, 0xdd, 0xf8, 0xeb, 0xa3,
0x1a, 0xd7, 0x5d, 0x8d, 0x43, 0x09, 0xdd, 0x73, 0xb8, 0xdf, 0xc7, 0x61, 0x1f, 0x94, 0x83, 0x65,
0xd3, 0x26, 0x6d, 0xaa, 0x25, 0xc5, 0x30, 0x1c, 0x24, 0xe8, 0x0d, 0xa4, 0xfd, 0xae, 0x23, 0x38,
0x6a, 0x6a, 0x49, 0xa9, 0x64, 0x6b, 0xcf, 0xe7, 0x1a, 0x84, 0x03, 0x2c, 0x8e, 0x9a, 0xa0, 0x0a,
0xa8, 0xcc, 0xa3, 0x4d, 0x6d, 0x59, 0x36, 0xcb, 0x19, 0x81, 0x1a, 0x46, 0xa4, 0x86, 0xb1, 0xed,
0xf4, 0xb1, 0xac, 0x40, 0x25, 0xc8, 0x32, 0x87, 0x78, 0xec, 0xcc, 0xe5, 0x9c, 0xfa, 0x5a, 0x4a,
0xb2, 0x1a, 0xfe, 0x09, 0xad, 0xc2, 0x9d, 0x28, 0x3d, 0xe9, 0xd0, 0xbe, 0x96, 0xbe, 0x59, 0xf2,
0x9a, 0xf6, 0xd1, 0x0e, 0x40, 0xd3, 0xa7, 0x84, 0xd3, 0xd6, 0x09, 0xe1, 0xda, 0x8a, 0x1c, 0xaa,
0x8f, 0x0d, 0x7d, 0x1b, 0x5d, 0x41, 0x7d, 0xe5, 0xfc, 0xa2, 0xb8, 0xf4, 0xfd, 0x77, 0x51, 0xc1,
0x99, 0x10, 0xb7, 0xcd, 0x45, 0x93, 0xae, 0xd7, 0x8a, 0x9a, 0x64, 0xe6, 0x69, 0x12, 0xe2, 0xb6,
0xb9, 0xbe, 0x01, 0xd9, 0x21, 0xd5, 0xd1, 0x5d, 0x48, 0x0a, 0xca, 0xf2, 0x62, 0xb1, 0x08, 0x85,
0xfe, 0x3d, 0x62, 0x75, 0xa9, 0x96, 0x08, 0xf4, 0x97, 0xc9, 0x66, 0x62, 0x5d, 0xd1, 0x8f, 0x20,
0x1d, 0xea, 0x88, 0x10, 0xa8, 0x0e, 0xb1, 0x69, 0x88, 0x93, 0x31, 0x32, 0x20, 0xed, 0x7a, 0xdc,
0x74, 0x1d, 0x26, 0xa1, 0xd3, 0x54, 0x8d, 0x8a, 0xca, 0x4f, 0xe0, 0xde, 0x01, 0xe5, 0xd7, 0x77,
0x84, 0xe9, 0xe7, 0x2e, 0x65, 0x7c, 0x9a, 0xd3, 0xca, 0x67, 0x90, 0xbb, 0x59, 0xce, 0x3c, 0xd7,
0x61, 0x14, 0x1d, 0x43, 0xe6, 0xfa, 0xd6, 0x25, 0x2c, 0x5b, 0x7b, 0x3c, 0x8f, 0x37, 0xea, 0xaa,
0x90, 0x09, 0xc7, 0x4d, 0xca, 0x6b, 0x70, 0xff, 0xd0, 0x64, 0xf1, 0x28, 0x16, 0x51, 0xd3, 0x20,
0x7d, 0x6a, 0x5a, 0x9c, 0xfa, 0x4c, 0x53, 0x4a, 0xc9, 0x4a, 0x06, 0x47, 0x69, 0xd9, 0x82, 0xfc,
0x28, 0x24, 0xa4, 0x87, 0x01, 0xe2, 0xc1, 0x12, 0x76, 0x3b, 0x7e, 0x43, 0x5d, 0xca, 0x9f, 0x20,
0xbf, 0x23, 0x5d, 0x31, 0x26, 0xde, 0xff, 0x17, 0xa3, 0x03, 0x0f, 0xc6, 0x66, 0x2d, 0x4c, 0xf9,
0x1f, 0x0a, 0xe4, 0xdf, 0x49, 0xab, 0x2e, 0xfe, 0xc9, 0xd0, 0x16, 0x64, 0x83, 0xb5, 0x90, 0xaf,
0xc5, 0xd0, 0xb3, 0xe3, 0xfb, 0xb4, 0x2f, 0xde, 0x9c, 0x47, 0x84, 0x75, 0x70, 0xb8, 0x7d, 0x22,
0x16, 0xb2, 0x8c, 0x11, 0x5d, 0x98, 0x2c, 0x4f, 0x21, 0xbf, 0x4b, 0x2d, 0x3a, 0x41, 0x95, 0x29,
0xcb, 0x52, 0xbb, 0x54, 0x01, 0x62, 0x33, 0xa2, 0x1e, 0x24, 0x0f, 0x28, 0x47, 0x2f, 0x66, 0xa0,
0x31, 0x61, 0x25, 0xf5, 0x97, 0x73, 0xe3, 0x42, 0x29, 0xbe, 0x80, 0x2a, 0xd6, 0x02, 0xcd, 0xf2,
0xaf, 0x30, 0x71, 0xe5, 0xf4, 0x8d, 0x5b, 0x20, 0xc3, 0xe1, 0x5f, 0x21, 0x15, 0x38, 0x17, 0xcd,
0xd2, 0x64, 0xf2, 0x42, 0xe9, 0x9b, 0xb7, 0x81, 0xc6, 0x04, 0x02, 0x8f, 0xcc, 0x44, 0x60, 0xb2,
0xef, 0x67, 0x22, 0x30, 0xcd, 0x89, 0x1f, 0x20, 0x15, 0xf8, 0x66, 0x26, 0x02, 0x93, 0x2d, 0xa6,
0xe7, 0xc7, 0x36, 0x62, 0x4f, 0x7c, 0x68, 0xd4, 0x3f, 0x9e, 0x5f, 0x15, 0x96, 0x7e, 0x5d, 0x15,
0x96, 0xbe, 0x0d, 0x0a, 0xca, 0xf9, 0xa0, 0xa0, 0xfc, 0x1c, 0x14, 0x94, 0xcb, 0x41, 0x41, 0x79,
0xbf, 0xff, 0x0f, 0xdf, 0x4e, 0x5b, 0x71, 0xd6, 0x48, 0xc9, 0x89, 0xcf, 0xfe, 0x04, 0x00, 0x00,
0xff, 0xff, 0x7e, 0x6d, 0xca, 0xbd, 0x8c, 0x09, 0x00, 0x00,
// 752 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x4d, 0x73, 0xd2, 0x5c,
0x14, 0x6e, 0x02, 0x85, 0x72, 0x78, 0x17, 0xef, 0x5c, 0x11, 0x63, 0x9c, 0x01, 0xca, 0x8a, 0x85,
0x06, 0x8b, 0x8e, 0xf6, 0x63, 0x55, 0xfa, 0x35, 0x8e, 0xad, 0xd3, 0xc9, 0xe8, 0x46, 0x17, 0x35,
0xc0, 0x29, 0x8d, 0xe4, 0xcb, 0xdc, 0x0b, 0x23, 0xe3, 0x42, 0x7f, 0x82, 0x6b, 0xff, 0x80, 0x7f,
0xa5, 0x4b, 0x97, 0xae, 0x6a, 0xcb, 0x2f, 0x71, 0x72, 0x93, 0x34, 0x29, 0xa4, 0x0a, 0x55, 0x76,
0xe7, 0xe4, 0x9e, 0xe7, 0x9c, 0xe7, 0x9e, 0xf3, 0x9c, 0x24, 0xb0, 0xdf, 0xd5, 0xd9, 0x49, 0xbf,
0xa5, 0xb4, 0x6d, 0xb3, 0xde, 0xb6, 0x2d, 0xa6, 0xe9, 0x16, 0xba, 0x9d, 0xb8, 0xa9, 0x39, 0x7a,
0x9d, 0xa2, 0x3b, 0xd0, 0xdb, 0x48, 0xa3, 0xe7, 0xb4, 0x3e, 0x58, 0x89, 0x79, 0x8a, 0xe3, 0xda,
0xcc, 0x26, 0xcb, 0x11, 0x4e, 0x09, 0x31, 0x4a, 0x2c, 0x6a, 0xb0, 0x22, 0x17, 0xba, 0x76, 0xd7,
0xe6, 0xd1, 0x75, 0xcf, 0xf2, 0x81, 0xf2, 0xdd, 0xae, 0x6d, 0x77, 0x0d, 0xac, 0x73, 0xaf, 0xd5,
0x3f, 0xae, 0x6b, 0xd6, 0x30, 0x38, 0xba, 0x37, 0x7e, 0x84, 0xa6, 0xc3, 0xc2, 0xc3, 0xca, 0xf8,
0xe1, 0xb1, 0x8e, 0x46, 0xe7, 0xc8, 0xd4, 0x68, 0x2f, 0x88, 0x28, 0x8f, 0x47, 0x30, 0xdd, 0x44,
0xca, 0x34, 0xd3, 0xf1, 0x03, 0xaa, 0x5f, 0x17, 0x21, 0xb7, 0x15, 0x52, 0x24, 0x45, 0x10, 0xf5,
0x8e, 0x24, 0x54, 0x84, 0x5a, 0xae, 0x99, 0x19, 0x9d, 0x95, 0xc5, 0x67, 0xdb, 0xaa, 0xa8, 0x77,
0xc8, 0x21, 0x64, 0x0c, 0xad, 0x85, 0x06, 0x95, 0xc4, 0x4a, 0xaa, 0x96, 0x6f, 0xac, 0x2a, 0x7f,
0xbc, 0xaa, 0x72, 0x99, 0x55, 0xd9, 0xe7, 0xd0, 0x1d, 0x8b, 0xb9, 0x43, 0x35, 0xc8, 0x43, 0x0a,
0xb0, 0xa8, 0x9b, 0x5a, 0x17, 0xa5, 0x94, 0x57, 0x4c, 0xf5, 0x1d, 0xf2, 0x02, 0xb2, 0x6e, 0xdf,
0xf2, 0x38, 0x4a, 0xe9, 0x8a, 0x50, 0xcb, 0x37, 0x1e, 0xcf, 0x54, 0x48, 0xf5, 0xb1, 0x6a, 0x98,
0x84, 0xd4, 0x20, 0x4d, 0x1d, 0x6c, 0x4b, 0x8b, 0x3c, 0x59, 0x41, 0xf1, 0xbb, 0xa1, 0x84, 0xdd,
0x50, 0x36, 0xad, 0xa1, 0xca, 0x23, 0x48, 0x05, 0xf2, 0xd4, 0xd2, 0x1c, 0x7a, 0x62, 0x33, 0x86,
0xae, 0x94, 0xe1, 0xac, 0xe2, 0x8f, 0xc8, 0x32, 0xfc, 0x17, 0xba, 0x47, 0x3d, 0x1c, 0x4a, 0xd9,
0xab, 0x21, 0xcf, 0x71, 0x48, 0xb6, 0x00, 0xda, 0x2e, 0x6a, 0x0c, 0x3b, 0x47, 0x1a, 0x93, 0x96,
0x78, 0x51, 0x79, 0xa2, 0xe8, 0xcb, 0x70, 0x04, 0xcd, 0xa5, 0xd3, 0xb3, 0xf2, 0xc2, 0x97, 0x9f,
0x65, 0x41, 0xcd, 0x05, 0xb8, 0x4d, 0xe6, 0x25, 0xe9, 0x3b, 0x9d, 0x30, 0x49, 0x6e, 0x96, 0x24,
0x01, 0x6e, 0x93, 0x91, 0x75, 0x00, 0xfc, 0xc0, 0xd0, 0xa2, 0xba, 0x6d, 0x51, 0x09, 0xf8, 0xd0,
0x12, 0xaf, 0xdf, 0x4c, 0x7b, 0x70, 0x35, 0x16, 0x2d, 0xaf, 0x41, 0x3e, 0x36, 0x31, 0xf2, 0x3f,
0xa4, 0xbc, 0xeb, 0x72, 0x51, 0xa8, 0x9e, 0xe9, 0xcd, 0x6e, 0xa0, 0x19, 0x7d, 0x94, 0x44, 0x7f,
0x76, 0xdc, 0x59, 0x17, 0x57, 0x05, 0xf9, 0x00, 0xb2, 0xc1, 0x0c, 0x08, 0x81, 0xb4, 0xa5, 0x99,
0x18, 0xe0, 0xb8, 0x4d, 0x14, 0xc8, 0xda, 0x0e, 0xe3, 0x94, 0xc4, 0xdf, 0x4c, 0x24, 0x0c, 0xaa,
0x3e, 0x80, 0x5b, 0x7b, 0xc8, 0x2e, 0xe7, 0xab, 0xe2, 0xfb, 0x3e, 0x52, 0x76, 0x9d, 0x4a, 0xab,
0x27, 0x50, 0xb8, 0x1a, 0x4e, 0x1d, 0xdb, 0xa2, 0x48, 0x0e, 0x21, 0x77, 0xa9, 0x18, 0x0e, 0xcb,
0x37, 0xee, 0xcf, 0xa2, 0xab, 0xa0, 0x47, 0x51, 0x92, 0xea, 0x0a, 0xdc, 0xde, 0xd7, 0x69, 0x54,
0x8a, 0x86, 0xd4, 0x24, 0xc8, 0x1e, 0xeb, 0x06, 0x43, 0x97, 0x4a, 0x42, 0x25, 0x55, 0xcb, 0xa9,
0xa1, 0x5b, 0x35, 0xa0, 0x38, 0x0e, 0x09, 0xe8, 0xa9, 0x00, 0x51, 0x61, 0x0e, 0xbb, 0x19, 0xbf,
0x58, 0x96, 0xea, 0x3b, 0x28, 0x6e, 0x71, 0x45, 0x4d, 0x34, 0xef, 0xdf, 0x37, 0xa3, 0x07, 0x77,
0x26, 0x6a, 0xcd, 0xad, 0xf3, 0xdf, 0x04, 0x28, 0xbe, 0xe2, 0x32, 0x9f, 0xff, 0xcd, 0xc8, 0x06,
0xe4, 0xfd, 0x95, 0xe2, 0xaf, 0xd4, 0x40, 0xb3, 0x93, 0xbb, 0xb8, 0xeb, 0xbd, 0x75, 0x0f, 0x34,
0xda, 0x53, 0x83, 0xcd, 0xf5, 0x6c, 0xaf, 0x2d, 0x13, 0x44, 0xe7, 0xd6, 0x96, 0x87, 0x50, 0xdc,
0x46, 0x03, 0x13, 0xba, 0x72, 0xcd, 0xb2, 0x34, 0xce, 0xd3, 0x00, 0x91, 0x18, 0xc9, 0x00, 0x52,
0x7b, 0xc8, 0xc8, 0x93, 0x29, 0x68, 0x24, 0xac, 0xa4, 0xfc, 0x74, 0x66, 0x5c, 0xd0, 0x8a, 0x8f,
0x90, 0xf6, 0xd6, 0x82, 0x4c, 0xf3, 0x45, 0x49, 0x5c, 0x39, 0x79, 0xed, 0x06, 0xc8, 0xa0, 0xf8,
0x27, 0xc8, 0xf8, 0xca, 0x25, 0xd3, 0x24, 0x49, 0x5e, 0x28, 0x79, 0xfd, 0x26, 0xd0, 0x88, 0x80,
0xaf, 0x91, 0xa9, 0x08, 0x24, 0xeb, 0x7e, 0x2a, 0x02, 0xd7, 0x29, 0xf1, 0x0d, 0x64, 0x7c, 0xdd,
0x4c, 0x45, 0x20, 0x59, 0x62, 0x72, 0x71, 0x62, 0x23, 0x76, 0xbc, 0x9f, 0x94, 0xe6, 0xdb, 0xd3,
0x8b, 0xd2, 0xc2, 0x8f, 0x8b, 0xd2, 0xc2, 0xe7, 0x51, 0x49, 0x38, 0x1d, 0x95, 0x84, 0xef, 0xa3,
0x92, 0x70, 0x3e, 0x2a, 0x09, 0xaf, 0x77, 0xff, 0xe2, 0xbf, 0x6b, 0x23, 0xf2, 0x5a, 0x19, 0x5e,
0xf1, 0xd1, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0x4b, 0xd5, 0xe0, 0xc8, 0x09, 0x00, 0x00,
}

View File

@ -84,6 +84,12 @@ message Container {
// UpdatedAt is the last time the container was mutated.
google.protobuf.Timestamp updated_at = 9 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
// Extensions allow clients to provide zero or more blobs that are directly
// associated with the container. One may provide protobuf, json, or other
// encoding formats. The primary use of this is to further decorate the
// container object with fields that may be specific to a client integration.
repeated google.protobuf.Any extensions = 10 [(gogoproto.nullable) = false];
}
message GetContainerRequest {

View File

@ -12,6 +12,7 @@ import (
"github.com/containerd/containerd/containers"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/typeurl"
prototypes "github.com/gogo/protobuf/types"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
)
@ -42,6 +43,8 @@ type Container interface {
Labels(context.Context) (map[string]string, error)
// SetLabels sets the provided labels for the container and returns the final label set
SetLabels(context.Context, map[string]string) (map[string]string, error)
// Extensions returns the extensions set on the container
Extensions() []prototypes.Any
}
func containerFromRecord(client *Client, c containers.Container) *container {
@ -158,6 +161,12 @@ func (c *container) Image(ctx context.Context) (Image, error) {
}, nil
}
func (c *container) Extensions() []prototypes.Any {
c.mu.Lock()
defer c.mu.Unlock()
return c.c.Extensions
}
func (c *container) NewTask(ctx context.Context, ioCreate IOCreation, opts ...NewTaskOpts) (Task, error) {
c.mu.Lock()
defer c.mu.Unlock()

View File

@ -127,3 +127,21 @@ func setSnapshotterIfEmpty(c *containers.Container) {
c.Snapshotter = DefaultSnapshotter
}
}
// WithContainerExtension appends extension data to the container object.
// Use this to decorate the container object with additional data for the client
// integration.
//
// Make sure to register the type of `extension` in the typeurl package via
// `typeurl.Register` otherwise the type data will be inferred, including how
// to encode and decode the object.
func WithContainerExtension(extension interface{}) NewContainerOpts {
return func(ctx context.Context, client *Client, c *containers.Container) error {
any, err := typeurl.MarshalAny(extension)
if err != nil {
return err
}
c.Extensions = append(c.Extensions, *any)
return nil
}
}

View File

@ -14,6 +14,7 @@ import (
_ "github.com/containerd/containerd/runtime"
"github.com/containerd/containerd/errdefs"
gogotypes "github.com/gogo/protobuf/types"
)
func empty() IOCreation {
@ -1368,3 +1369,45 @@ func TestContainerMetrics(t *testing.T) {
<-statusC
}
func TestContainerExtensions(t *testing.T) {
t.Parallel()
ctx, cancel := testContext()
defer cancel()
id := t.Name()
client, err := newClient(t, address)
if err != nil {
t.Fatal(err)
}
defer client.Close()
ext := gogotypes.Any{TypeUrl: "test.ext.url", Value: []byte("hello")}
container, err := client.NewContainer(ctx, id, WithNewSpec(), WithContainerExtension(&ext))
if err != nil {
t.Fatal(err)
}
defer container.Delete(ctx)
checkExt := func(container Container) {
cExts := container.Extensions()
if len(cExts) != 1 {
t.Fatal("expected 1 container extension")
}
if cExts[0].TypeUrl != ext.TypeUrl {
t.Fatalf("got unexpected type url for extension: %s", cExts[0].TypeUrl)
}
if !bytes.Equal(cExts[0].Value, ext.Value) {
t.Fatalf("expected extension value %q, got: %q", ext.Value, cExts[0].Value)
}
}
checkExt(container)
container, err = client.LoadContainer(ctx, container.ID())
if err != nil {
t.Fatal(err)
}
checkExt(container)
}

View File

@ -57,6 +57,9 @@ type Container struct {
// UpdatedAt is the time at which the container was updated.
UpdatedAt time.Time
// Extensions stores client-specified metadata
Extensions []types.Any
}
type RuntimeInfo struct {

View File

@ -97,6 +97,7 @@ func containerToProto(container *containers.Container) containersapi.Container {
Spec: container.Spec,
Snapshotter: container.Snapshotter,
SnapshotKey: container.SnapshotKey,
Extensions: container.Extensions,
}
}
@ -116,6 +117,7 @@ func containerFromProto(containerpb *containersapi.Container) containers.Contain
Spec: containerpb.Spec,
Snapshotter: containerpb.Snapshotter,
SnapshotKey: containerpb.SnapshotKey,
Extensions: containerpb.Extensions,
}
}

View File

@ -50,6 +50,7 @@ var (
bucketKeySnapshotKey = []byte("snapshotKey")
bucketKeySnapshotter = []byte("snapshotter")
bucketKeyTarget = []byte("target")
bucketKeyExtensions = []byte("extensions")
)
func getBucket(tx *bolt.Tx, keys ...[]byte) *bolt.Bucket {

View File

@ -146,7 +146,7 @@ func (s *containerStore) Update(ctx context.Context, container containers.Contai
if len(fieldpaths) == 0 {
// only allow updates to these field on full replace.
fieldpaths = []string{"labels", "spec"}
fieldpaths = []string{"labels", "spec", "extensions"}
// Fields that are immutable must cause an error when no field paths
// are provided. This allows these fields to become mutable in the
@ -186,6 +186,8 @@ func (s *containerStore) Update(ctx context.Context, container containers.Contai
updated.Labels = container.Labels
case "spec":
updated.Spec = container.Spec
case "extensions":
updated.Extensions = container.Extensions
default:
return containers.Container{}, errors.Wrapf(errdefs.ErrInvalidArgument, "cannot update %q field on %q", path, container.ID)
}
@ -288,6 +290,21 @@ func readContainer(container *containers.Container, bkt *bolt.Bucket) error {
container.SnapshotKey = string(v)
case string(bucketKeySnapshotter):
container.Snapshotter = string(v)
case string(bucketKeyExtensions):
buf := proto.NewBuffer(v)
n, err := buf.DecodeVarint()
if err != nil {
return errors.Wrap(err, "error reading number of container extensions")
}
extensions := make([]types.Any, 0, n)
for i := 0; i < int(n); i++ {
var any types.Any
if err := buf.DecodeMessage(&any); err != nil {
return errors.Wrap(err, "error decoding container extension")
}
extensions = append(extensions, any)
}
container.Extensions = extensions
}
return nil
@ -335,6 +352,21 @@ func writeContainer(bkt *bolt.Bucket, container *containers.Container) error {
return err
}
if container.Extensions != nil {
buf := proto.NewBuffer(nil)
if err := buf.EncodeVarint(uint64(len(container.Extensions))); err != nil {
return err
}
for _, ext := range container.Extensions {
if err := buf.EncodeMessage(&ext); err != nil {
return err
}
}
if err := bkt.Put(bucketKeyExtensions, buf.Bytes()); err != nil {
return err
}
}
if container.Runtime.Options != nil {
data, err := proto.Marshal(container.Runtime.Options)
if err != nil {

View File

@ -16,6 +16,7 @@ import (
"github.com/containerd/containerd/filters"
"github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/typeurl"
"github.com/gogo/protobuf/types"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
)
@ -420,6 +421,124 @@ func TestContainersCreateUpdateDelete(t *testing.T) {
},
createerr: errdefs.ErrInvalidArgument,
},
{
name: "UpdateExtensionsFull",
original: containers.Container{
Spec: encoded,
Runtime: containers.RuntimeInfo{
Name: "testruntime",
},
Extensions: []types.Any{
{
TypeUrl: "test.update.extensions",
Value: []byte("hello"),
},
},
},
input: containers.Container{
Spec: encoded,
Runtime: containers.RuntimeInfo{
Name: "testruntime",
},
Extensions: []types.Any{
{
TypeUrl: "test.update.extensions",
Value: []byte("world"),
},
},
},
expected: containers.Container{
Spec: encoded,
Runtime: containers.RuntimeInfo{
Name: "testruntime",
},
Extensions: []types.Any{
{
TypeUrl: "test.update.extensions",
Value: []byte("world"),
},
},
},
},
{
name: "UpdateExtensionsNotInFieldpath",
original: containers.Container{
Spec: encoded,
Runtime: containers.RuntimeInfo{
Name: "testruntime",
},
Extensions: []types.Any{
{
TypeUrl: "test.update.extensions",
Value: []byte("hello"),
},
},
},
input: containers.Container{
Spec: encoded,
Runtime: containers.RuntimeInfo{
Name: "testruntime",
},
Extensions: []types.Any{
{
TypeUrl: "test.update.extensions",
Value: []byte("world"),
},
},
},
fieldpaths: []string{"labels"},
expected: containers.Container{
Spec: encoded,
Runtime: containers.RuntimeInfo{
Name: "testruntime",
},
Extensions: []types.Any{
{
TypeUrl: "test.update.extensions",
Value: []byte("hello"),
},
},
},
},
{
name: "UpdateExtensionsFieldPath",
original: containers.Container{
Spec: encoded,
Runtime: containers.RuntimeInfo{
Name: "testruntime",
},
Extensions: []types.Any{
{
TypeUrl: "test.update.extensions",
Value: []byte("hello"),
},
},
},
input: containers.Container{
Labels: map[string]string{
"foo": "one",
},
Extensions: []types.Any{
{
TypeUrl: "test.update.extensions",
Value: []byte("world"),
},
},
},
fieldpaths: []string{"extensions"},
expected: containers.Container{
Spec: encoded,
Runtime: containers.RuntimeInfo{
Name: "testruntime",
},
Extensions: []types.Any{
{
TypeUrl: "test.update.extensions",
Value: []byte("world"),
},
},
},
},
} {
t.Run(testcase.name, func(t *testing.T) {
testcase.original.ID = testcase.name

View File

@ -27,6 +27,7 @@ func containerToProto(container *containers.Container) api.Container {
Spec: container.Spec,
Snapshotter: container.Snapshotter,
SnapshotKey: container.SnapshotKey,
Extensions: container.Extensions,
}
}
@ -46,5 +47,6 @@ func containerFromProto(containerpb *api.Container) containers.Container {
Spec: containerpb.Spec,
Snapshotter: containerpb.Snapshotter,
SnapshotKey: containerpb.SnapshotKey,
Extensions: containerpb.Extensions,
}
}