Make AllocateResponse artifacts global across all devices per container in device plugin API

There is no use case known for passing artifacts per device as it currently exists. The current API is also
complex to use for simple clients. Hence this PR creates a flat namespace where artifacts like environment variables
and mount points apply globally to all devices returned as part of AllocateResponse proto.

Signed-off-by: Vishnu kannan <vishnuk@google.com>
This commit is contained in:
Vishnu kannan 2017-09-25 18:13:25 -07:00
parent 900c0761e3
commit 18eee1eaa0
4 changed files with 117 additions and 317 deletions

View File

@ -31,7 +31,6 @@ limitations under the License.
Device Device
AllocateRequest AllocateRequest
AllocateResponse AllocateResponse
DeviceRuntimeSpec
Mount Mount
DeviceSpec DeviceSpec
*/ */
@ -177,64 +176,42 @@ func (m *AllocateRequest) GetDevicesIDs() []string {
return nil return nil
} }
// AllocateResponse includes the artifacts that needs to be injected into
// a container for accessing 'deviceIDs' that were mentioned as part of
// 'AllocateRequest'.
// Failure Handling: // Failure Handling:
// if Kubelet sends an allocation request for dev1 and dev2. // if Kubelet sends an allocation request for dev1 and dev2.
// Allocation on dev1 succeeds but allocation on dev2 fails. // Allocation on dev1 succeeds but allocation on dev2 fails.
// The Device plugin should send a ListAndWatch update and fail the // The Device plugin should send a ListAndWatch update and fail the
// Allocation request // Allocation request
type AllocateResponse struct { type AllocateResponse struct {
Spec []*DeviceRuntimeSpec `protobuf:"bytes,1,rep,name=spec" json:"spec,omitempty"` // List of environment variable to be set in the container to access one of more devices.
Envs map[string]string `protobuf:"bytes,1,rep,name=envs" json:"envs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
// Mounts for the container.
Mounts []*Mount `protobuf:"bytes,2,rep,name=mounts" json:"mounts,omitempty"`
// Devices for the container.
Devices []*DeviceSpec `protobuf:"bytes,3,rep,name=devices" json:"devices,omitempty"`
} }
func (m *AllocateResponse) Reset() { *m = AllocateResponse{} } func (m *AllocateResponse) Reset() { *m = AllocateResponse{} }
func (*AllocateResponse) ProtoMessage() {} func (*AllocateResponse) ProtoMessage() {}
func (*AllocateResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{5} } func (*AllocateResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{5} }
func (m *AllocateResponse) GetSpec() []*DeviceRuntimeSpec { func (m *AllocateResponse) GetEnvs() map[string]string {
if m != nil {
return m.Spec
}
return nil
}
// The list to be added to the CRI spec
type DeviceRuntimeSpec struct {
// ID of the Device
ID string `protobuf:"bytes,1,opt,name=ID,json=iD,proto3" json:"ID,omitempty"`
// List of environment variable to set in the container.
Envs map[string]string `protobuf:"bytes,2,rep,name=envs" json:"envs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
// Mounts for the container.
Mounts []*Mount `protobuf:"bytes,3,rep,name=mounts" json:"mounts,omitempty"`
// Devices for the container
Devices []*DeviceSpec `protobuf:"bytes,4,rep,name=devices" json:"devices,omitempty"`
}
func (m *DeviceRuntimeSpec) Reset() { *m = DeviceRuntimeSpec{} }
func (*DeviceRuntimeSpec) ProtoMessage() {}
func (*DeviceRuntimeSpec) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{6} }
func (m *DeviceRuntimeSpec) GetID() string {
if m != nil {
return m.ID
}
return ""
}
func (m *DeviceRuntimeSpec) GetEnvs() map[string]string {
if m != nil { if m != nil {
return m.Envs return m.Envs
} }
return nil return nil
} }
func (m *DeviceRuntimeSpec) GetMounts() []*Mount { func (m *AllocateResponse) GetMounts() []*Mount {
if m != nil { if m != nil {
return m.Mounts return m.Mounts
} }
return nil return nil
} }
func (m *DeviceRuntimeSpec) GetDevices() []*DeviceSpec { func (m *AllocateResponse) GetDevices() []*DeviceSpec {
if m != nil { if m != nil {
return m.Devices return m.Devices
} }
@ -254,7 +231,7 @@ type Mount struct {
func (m *Mount) Reset() { *m = Mount{} } func (m *Mount) Reset() { *m = Mount{} }
func (*Mount) ProtoMessage() {} func (*Mount) ProtoMessage() {}
func (*Mount) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{7} } func (*Mount) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{6} }
func (m *Mount) GetContainerPath() string { func (m *Mount) GetContainerPath() string {
if m != nil { if m != nil {
@ -292,7 +269,7 @@ type DeviceSpec struct {
func (m *DeviceSpec) Reset() { *m = DeviceSpec{} } func (m *DeviceSpec) Reset() { *m = DeviceSpec{} }
func (*DeviceSpec) ProtoMessage() {} func (*DeviceSpec) ProtoMessage() {}
func (*DeviceSpec) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{8} } func (*DeviceSpec) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{7} }
func (m *DeviceSpec) GetContainerPath() string { func (m *DeviceSpec) GetContainerPath() string {
if m != nil { if m != nil {
@ -322,7 +299,6 @@ func init() {
proto.RegisterType((*Device)(nil), "deviceplugin.Device") proto.RegisterType((*Device)(nil), "deviceplugin.Device")
proto.RegisterType((*AllocateRequest)(nil), "deviceplugin.AllocateRequest") proto.RegisterType((*AllocateRequest)(nil), "deviceplugin.AllocateRequest")
proto.RegisterType((*AllocateResponse)(nil), "deviceplugin.AllocateResponse") proto.RegisterType((*AllocateResponse)(nil), "deviceplugin.AllocateResponse")
proto.RegisterType((*DeviceRuntimeSpec)(nil), "deviceplugin.DeviceRuntimeSpec")
proto.RegisterType((*Mount)(nil), "deviceplugin.Mount") proto.RegisterType((*Mount)(nil), "deviceplugin.Mount")
proto.RegisterType((*DeviceSpec)(nil), "deviceplugin.DeviceSpec") proto.RegisterType((*DeviceSpec)(nil), "deviceplugin.DeviceSpec")
} }
@ -698,45 +674,9 @@ func (m *AllocateResponse) MarshalTo(dAtA []byte) (int, error) {
_ = i _ = i
var l int var l int
_ = l _ = l
if len(m.Spec) > 0 {
for _, msg := range m.Spec {
dAtA[i] = 0xa
i++
i = encodeVarintApi(dAtA, i, uint64(msg.Size()))
n, err := msg.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n
}
}
return i, nil
}
func (m *DeviceRuntimeSpec) 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 *DeviceRuntimeSpec) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if len(m.ID) > 0 {
dAtA[i] = 0xa
i++
i = encodeVarintApi(dAtA, i, uint64(len(m.ID)))
i += copy(dAtA[i:], m.ID)
}
if len(m.Envs) > 0 { if len(m.Envs) > 0 {
for k := range m.Envs { for k := range m.Envs {
dAtA[i] = 0x12 dAtA[i] = 0xa
i++ i++
v := m.Envs[k] v := m.Envs[k]
mapSize := 1 + len(k) + sovApi(uint64(len(k))) + 1 + len(v) + sovApi(uint64(len(v))) mapSize := 1 + len(k) + sovApi(uint64(len(k))) + 1 + len(v) + sovApi(uint64(len(v)))
@ -753,7 +693,7 @@ func (m *DeviceRuntimeSpec) MarshalTo(dAtA []byte) (int, error) {
} }
if len(m.Mounts) > 0 { if len(m.Mounts) > 0 {
for _, msg := range m.Mounts { for _, msg := range m.Mounts {
dAtA[i] = 0x1a dAtA[i] = 0x12
i++ i++
i = encodeVarintApi(dAtA, i, uint64(msg.Size())) i = encodeVarintApi(dAtA, i, uint64(msg.Size()))
n, err := msg.MarshalTo(dAtA[i:]) n, err := msg.MarshalTo(dAtA[i:])
@ -765,7 +705,7 @@ func (m *DeviceRuntimeSpec) MarshalTo(dAtA []byte) (int, error) {
} }
if len(m.Devices) > 0 { if len(m.Devices) > 0 {
for _, msg := range m.Devices { for _, msg := range m.Devices {
dAtA[i] = 0x22 dAtA[i] = 0x1a
i++ i++
i = encodeVarintApi(dAtA, i, uint64(msg.Size())) i = encodeVarintApi(dAtA, i, uint64(msg.Size()))
n, err := msg.MarshalTo(dAtA[i:]) n, err := msg.MarshalTo(dAtA[i:])
@ -946,22 +886,6 @@ func (m *AllocateRequest) Size() (n int) {
func (m *AllocateResponse) Size() (n int) { func (m *AllocateResponse) Size() (n int) {
var l int var l int
_ = l _ = l
if len(m.Spec) > 0 {
for _, e := range m.Spec {
l = e.Size()
n += 1 + l + sovApi(uint64(l))
}
}
return n
}
func (m *DeviceRuntimeSpec) Size() (n int) {
var l int
_ = l
l = len(m.ID)
if l > 0 {
n += 1 + l + sovApi(uint64(l))
}
if len(m.Envs) > 0 { if len(m.Envs) > 0 {
for k, v := range m.Envs { for k, v := range m.Envs {
_ = k _ = k
@ -1086,16 +1010,6 @@ func (this *AllocateRequest) String() string {
return s return s
} }
func (this *AllocateResponse) String() string { func (this *AllocateResponse) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&AllocateResponse{`,
`Spec:` + strings.Replace(fmt.Sprintf("%v", this.Spec), "DeviceRuntimeSpec", "DeviceRuntimeSpec", 1) + `,`,
`}`,
}, "")
return s
}
func (this *DeviceRuntimeSpec) String() string {
if this == nil { if this == nil {
return "nil" return "nil"
} }
@ -1109,8 +1023,7 @@ func (this *DeviceRuntimeSpec) String() string {
mapStringForEnvs += fmt.Sprintf("%v: %v,", k, this.Envs[k]) mapStringForEnvs += fmt.Sprintf("%v: %v,", k, this.Envs[k])
} }
mapStringForEnvs += "}" mapStringForEnvs += "}"
s := strings.Join([]string{`&DeviceRuntimeSpec{`, s := strings.Join([]string{`&AllocateResponse{`,
`ID:` + fmt.Sprintf("%v", this.ID) + `,`,
`Envs:` + mapStringForEnvs + `,`, `Envs:` + mapStringForEnvs + `,`,
`Mounts:` + strings.Replace(fmt.Sprintf("%v", this.Mounts), "Mount", "Mount", 1) + `,`, `Mounts:` + strings.Replace(fmt.Sprintf("%v", this.Mounts), "Mount", "Mount", 1) + `,`,
`Devices:` + strings.Replace(fmt.Sprintf("%v", this.Devices), "DeviceSpec", "DeviceSpec", 1) + `,`, `Devices:` + strings.Replace(fmt.Sprintf("%v", this.Devices), "DeviceSpec", "DeviceSpec", 1) + `,`,
@ -1635,116 +1548,6 @@ func (m *AllocateResponse) Unmarshal(dAtA []byte) error {
} }
switch fieldNum { switch fieldNum {
case 1: case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApi
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthApi
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Spec = append(m.Spec, &DeviceRuntimeSpec{})
if err := m.Spec[len(m.Spec)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipApi(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthApi
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *DeviceRuntimeSpec) 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 ErrIntOverflowApi
}
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: DeviceRuntimeSpec: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: DeviceRuntimeSpec: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApi
}
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 ErrInvalidLengthApi
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.ID = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Envs", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Envs", wireType)
} }
@ -1860,7 +1663,7 @@ func (m *DeviceRuntimeSpec) Unmarshal(dAtA []byte) error {
m.Envs[mapkey] = mapvalue m.Envs[mapkey] = mapvalue
} }
iNdEx = postIndex iNdEx = postIndex
case 3: case 2:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Mounts", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Mounts", wireType)
} }
@ -1891,7 +1694,7 @@ func (m *DeviceRuntimeSpec) Unmarshal(dAtA []byte) error {
return err return err
} }
iNdEx = postIndex iNdEx = postIndex
case 4: case 3:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Devices", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Devices", wireType)
} }
@ -2316,42 +2119,41 @@ var (
func init() { proto.RegisterFile("api.proto", fileDescriptorApi) } func init() { proto.RegisterFile("api.proto", fileDescriptorApi) }
var fileDescriptorApi = []byte{ var fileDescriptorApi = []byte{
// 590 bytes of a gzipped FileDescriptorProto // 562 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0xcd, 0x6e, 0xd3, 0x40, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0xcb, 0x8e, 0xd3, 0x4a,
0x10, 0xce, 0x26, 0x6d, 0x9a, 0x4c, 0xd3, 0x1f, 0x96, 0x0a, 0x59, 0x01, 0x4c, 0x65, 0x84, 0x54, 0x10, 0x4d, 0x27, 0x77, 0xf2, 0xa8, 0xc9, 0x3c, 0xd4, 0x37, 0x42, 0x96, 0x01, 0x2b, 0x32, 0x42,
0x84, 0x70, 0x4b, 0x7a, 0x00, 0x21, 0x21, 0x51, 0x94, 0x82, 0xaa, 0xf2, 0x53, 0x99, 0x03, 0xc7, 0x8a, 0x84, 0xf0, 0x0c, 0x61, 0x01, 0x42, 0x2c, 0x18, 0x94, 0x20, 0x8d, 0x86, 0x47, 0x64, 0x16,
0x6a, 0xeb, 0x0c, 0xf1, 0x0a, 0x7b, 0xd7, 0x78, 0xd7, 0x91, 0x72, 0xe3, 0x11, 0x78, 0x0c, 0x1e, 0x2c, 0xa3, 0x8e, 0x53, 0xc4, 0x16, 0x76, 0xb7, 0x71, 0xb7, 0x23, 0x65, 0xc7, 0x27, 0xf0, 0x19,
0xa5, 0x47, 0x8e, 0x1c, 0x69, 0x78, 0x0d, 0x0e, 0xc8, 0xeb, 0x75, 0x9b, 0xa6, 0x41, 0x5c, 0xb8, 0x7c, 0xca, 0x2c, 0x59, 0xb2, 0x64, 0xc2, 0x8e, 0xaf, 0x40, 0x6e, 0xdb, 0x79, 0x29, 0x62, 0xc5,
0x79, 0xbe, 0xf9, 0x66, 0xe6, 0x9b, 0xcd, 0x7c, 0x81, 0x36, 0x4b, 0xb9, 0x9f, 0x66, 0x52, 0x4b, 0xce, 0x75, 0xea, 0x9c, 0xd4, 0xa9, 0xca, 0xb1, 0xa1, 0xc5, 0xe2, 0xc0, 0x89, 0x13, 0xa1, 0x04,
0xda, 0x19, 0xe0, 0x88, 0x87, 0x98, 0xc6, 0xf9, 0x90, 0x8b, 0xee, 0xc3, 0x21, 0xd7, 0x51, 0x7e, 0x6d, 0x4f, 0x71, 0x1e, 0x78, 0x18, 0x87, 0xe9, 0x2c, 0xe0, 0xe6, 0xc3, 0x59, 0xa0, 0xfc, 0x74,
0xe2, 0x87, 0x32, 0xd9, 0x1e, 0xca, 0xa1, 0xdc, 0x36, 0xa4, 0x93, 0xfc, 0xa3, 0x89, 0x4c, 0x60, 0xe2, 0x78, 0x22, 0x3a, 0x9b, 0x89, 0x99, 0x38, 0xd3, 0xa4, 0x49, 0xfa, 0x51, 0x57, 0xba, 0xd0,
0xbe, 0xca, 0x62, 0x2f, 0x86, 0xb5, 0x00, 0x87, 0x5c, 0x69, 0xcc, 0x02, 0xfc, 0x9c, 0xa3, 0xd2, 0x4f, 0xb9, 0xd8, 0x0e, 0xe1, 0xc4, 0xc5, 0x59, 0x20, 0x15, 0x26, 0x2e, 0x7e, 0x4e, 0x51, 0x2a,
0xd4, 0x81, 0xa5, 0x11, 0x66, 0x8a, 0x4b, 0xe1, 0x90, 0x4d, 0xb2, 0xd5, 0x0e, 0xaa, 0x90, 0x76, 0x6a, 0x40, 0x63, 0x8e, 0x89, 0x0c, 0x04, 0x37, 0x48, 0x97, 0xf4, 0x5a, 0x6e, 0x59, 0x52, 0x13,
0xa1, 0x85, 0x62, 0x90, 0x4a, 0x2e, 0xb4, 0x53, 0x37, 0xa9, 0xf3, 0x98, 0xde, 0x85, 0x95, 0x0c, 0x9a, 0xc8, 0xa7, 0xb1, 0x08, 0xb8, 0x32, 0xaa, 0xba, 0xb5, 0xaa, 0xe9, 0x3d, 0x38, 0x4a, 0x50,
0x95, 0xcc, 0xb3, 0x10, 0x8f, 0x05, 0x4b, 0xd0, 0x69, 0x18, 0x42, 0xa7, 0x02, 0xdf, 0xb2, 0x04, 0x8a, 0x34, 0xf1, 0x70, 0xcc, 0x59, 0x84, 0x46, 0x4d, 0x13, 0xda, 0x25, 0xf8, 0x96, 0x45, 0x68,
0xbd, 0x25, 0x58, 0xdc, 0x4f, 0x52, 0x3d, 0xf6, 0x5e, 0xc2, 0xc6, 0x6b, 0xae, 0xf4, 0x9e, 0x18, 0x37, 0xe0, 0x60, 0x18, 0xc5, 0x6a, 0x61, 0xbf, 0x82, 0xce, 0xeb, 0x40, 0xaa, 0x0b, 0x3e, 0xfd,
0x7c, 0x60, 0x3a, 0x8c, 0x02, 0x54, 0xa9, 0x14, 0x0a, 0xa9, 0x0f, 0x4b, 0xe5, 0x36, 0xca, 0x21, 0xc0, 0x94, 0xe7, 0xbb, 0x28, 0x63, 0xc1, 0x25, 0x52, 0x07, 0x1a, 0xf9, 0x36, 0xd2, 0x20, 0xdd,
0x9b, 0x8d, 0xad, 0xe5, 0xde, 0x86, 0x3f, 0xbd, 0x9d, 0xdf, 0x37, 0x41, 0x50, 0x91, 0xbc, 0x1d, 0x5a, 0xef, 0xb0, 0xdf, 0x71, 0x36, 0xb7, 0x73, 0x06, 0xba, 0x70, 0x4b, 0x92, 0x7d, 0x0e, 0xf5,
0x68, 0x96, 0x10, 0x5d, 0x85, 0xfa, 0x41, 0xdf, 0x0a, 0xae, 0xf3, 0x3e, 0xbd, 0x01, 0xcd, 0x08, 0x1c, 0xa2, 0xc7, 0x50, 0xbd, 0x1c, 0x14, 0x86, 0xab, 0xc1, 0x80, 0xde, 0x82, 0xba, 0x8f, 0x2c,
0x59, 0xac, 0x23, 0xab, 0xd4, 0x46, 0xde, 0x23, 0x58, 0xdb, 0x8b, 0x63, 0x19, 0x32, 0x8d, 0xd5, 0x54, 0x7e, 0xe1, 0xb4, 0xa8, 0xec, 0x47, 0x70, 0x72, 0x11, 0x86, 0xc2, 0x63, 0x0a, 0xcb, 0x85,
0xc2, 0x2e, 0x80, 0xed, 0x77, 0xd0, 0x2f, 0xe7, 0xb6, 0x83, 0x29, 0xc4, 0x7b, 0x05, 0xeb, 0x17, 0x2d, 0x80, 0xe2, 0xf7, 0x2e, 0x07, 0xf9, 0xdc, 0x96, 0xbb, 0x81, 0xd8, 0xbf, 0x09, 0x9c, 0xae,
0x25, 0x56, 0xe8, 0x2e, 0x2c, 0xa8, 0x14, 0x43, 0xab, 0xf2, 0xce, 0x5c, 0x95, 0xb9, 0xd0, 0x3c, 0x35, 0x85, 0xd3, 0xe7, 0xf0, 0x1f, 0xf2, 0x79, 0x69, 0xb3, 0xb7, 0x6d, 0x73, 0x97, 0xed, 0x0c,
0xc1, 0xf7, 0x29, 0x86, 0x81, 0x21, 0x7b, 0xbf, 0x09, 0x5c, 0xbb, 0x92, 0xbb, 0xa2, 0xfc, 0x19, 0xf9, 0x5c, 0x0e, 0xb9, 0x4a, 0x16, 0xae, 0x56, 0xd1, 0x07, 0x50, 0x8f, 0x44, 0xca, 0x95, 0x34,
0x2c, 0xa0, 0x18, 0x29, 0xa7, 0x6e, 0x5a, 0xdf, 0xff, 0x47, 0x6b, 0x7f, 0x5f, 0x8c, 0xd4, 0xbe, 0xaa, 0x5a, 0xff, 0xff, 0xb6, 0xfe, 0x4d, 0xd6, 0x73, 0x0b, 0x0a, 0xed, 0xaf, 0x8f, 0x52, 0xd3,
0xd0, 0xd9, 0x38, 0x30, 0x65, 0xf4, 0x01, 0x34, 0x13, 0x99, 0x0b, 0xad, 0x9c, 0x86, 0x69, 0x70, 0x6c, 0x63, 0xdf, 0x51, 0xde, 0xc7, 0xe8, 0xad, 0x0e, 0x63, 0x3e, 0x81, 0xd6, 0x6a, 0x26, 0x3d,
0xfd, 0x72, 0x83, 0x37, 0x45, 0x2e, 0xb0, 0x14, 0xda, 0xbb, 0x78, 0xef, 0x05, 0xc3, 0x76, 0xe6, 0x85, 0xda, 0x27, 0x5c, 0x14, 0xc7, 0xc9, 0x1e, 0x69, 0x07, 0x0e, 0xe6, 0x2c, 0x4c, 0xb1, 0x38,
0x8d, 0x33, 0x2b, 0x54, 0xc4, 0xee, 0x63, 0x68, 0x9f, 0xcf, 0xa4, 0xeb, 0xd0, 0xf8, 0x84, 0x63, 0x4e, 0x5e, 0x3c, 0xab, 0x3e, 0x25, 0xb6, 0x0f, 0x07, 0x7a, 0x3a, 0xbd, 0x0f, 0xc7, 0x9e, 0xe0,
0xab, 0xbe, 0xf8, 0xa4, 0x1b, 0xb0, 0x38, 0x62, 0x71, 0x8e, 0xf6, 0xdd, 0xcb, 0xe0, 0x69, 0xfd, 0x8a, 0x05, 0x1c, 0x93, 0x71, 0xcc, 0x94, 0x5f, 0xe8, 0x8f, 0x56, 0xe8, 0x88, 0x29, 0x9f, 0xde,
0x09, 0xf1, 0x22, 0x58, 0x34, 0xd3, 0xe9, 0x3d, 0x58, 0x0d, 0xa5, 0xd0, 0x8c, 0x0b, 0xcc, 0x8e, 0x86, 0x96, 0x2f, 0xa4, 0xca, 0x19, 0x45, 0x28, 0x32, 0xa0, 0x6c, 0x26, 0xc8, 0xa6, 0x63, 0xc1,
0x53, 0xa6, 0x23, 0x5b, 0xbf, 0x72, 0x8e, 0x1e, 0x31, 0x1d, 0xd1, 0x9b, 0xd0, 0x8e, 0xa4, 0xd2, 0xc3, 0x85, 0x0e, 0x44, 0xd3, 0x6d, 0x66, 0xc0, 0x3b, 0x1e, 0x2e, 0xec, 0x04, 0x60, 0xed, 0xfc,
0x25, 0xc3, 0xde, 0x5b, 0x01, 0x54, 0xc9, 0x0c, 0xd9, 0xe0, 0x58, 0x8a, 0x78, 0x6c, 0x6e, 0xad, 0x9f, 0x8c, 0xeb, 0xc2, 0x61, 0x8c, 0x49, 0x14, 0xc8, 0x2c, 0xad, 0xb2, 0x48, 0xe0, 0x26, 0xd4,
0x15, 0xb4, 0x0a, 0xe0, 0x9d, 0x88, 0xc7, 0x5e, 0x06, 0x70, 0xa1, 0xfc, 0xbf, 0x8c, 0xdb, 0x84, 0x1f, 0x41, 0x3b, 0x8f, 0x7b, 0xc2, 0x54, 0x96, 0xe8, 0x17, 0xd0, 0x2c, 0xe3, 0x4f, 0xef, 0x6e,
0xe5, 0x14, 0xb3, 0x84, 0xab, 0xc2, 0x08, 0xca, 0x1e, 0xf7, 0x34, 0xd4, 0x3b, 0x82, 0x4e, 0xe9, 0x5f, 0x75, 0xe7, 0xb5, 0x30, 0x77, 0xfe, 0xa2, 0x3c, 0xc7, 0x95, 0xfe, 0x37, 0x02, 0xed, 0x7c,
0xa4, 0x8c, 0xe9, 0xc2, 0x2c, 0xcf, 0xa1, 0x55, 0x39, 0x8b, 0xde, 0xbe, 0xfc, 0xaa, 0x33, 0x8e, 0x8d, 0x91, 0x6e, 0xd0, 0x2b, 0x68, 0x6f, 0x46, 0x9b, 0xee, 0xd3, 0x99, 0xf6, 0x36, 0xb8, 0xef,
0xeb, 0xce, 0xfc, 0x44, 0xa5, 0x45, 0x6a, 0xbd, 0x6f, 0x04, 0x3a, 0xe5, 0x1a, 0x47, 0x26, 0x41, 0x5d, 0xb0, 0x2b, 0xe7, 0x84, 0x5e, 0x41, 0xb3, 0xcc, 0xd2, 0xae, 0xbf, 0x9d, 0x14, 0x9b, 0xd6,
0x0f, 0xa1, 0x33, 0xed, 0x1a, 0x3a, 0xaf, 0xae, 0xeb, 0x5d, 0x06, 0xe7, 0xd9, 0xcc, 0xab, 0xed, 0xdf, 0x23, 0x68, 0x57, 0x5e, 0xde, 0xb9, 0xbe, 0xb1, 0xc8, 0x8f, 0x1b, 0xab, 0xf2, 0x65, 0x69,
0x10, 0x7a, 0x08, 0xad, 0xea, 0xaa, 0x67, 0xf5, 0xcd, 0x18, 0xa4, 0xeb, 0xfe, 0x2d, 0x5d, 0xb5, 0x91, 0xeb, 0xa5, 0x45, 0xbe, 0x2f, 0x2d, 0xf2, 0x73, 0x69, 0x91, 0xaf, 0xbf, 0xac, 0xca, 0xa4,
0x7b, 0x71, 0xeb, 0xf4, 0xcc, 0x25, 0x3f, 0xce, 0xdc, 0xda, 0x97, 0x89, 0x4b, 0x4e, 0x27, 0x2e, 0xae, 0x3f, 0x08, 0x8f, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x17, 0x55, 0xaf, 0xe1, 0x5a, 0x04,
0xf9, 0x3e, 0x71, 0xc9, 0xcf, 0x89, 0x4b, 0xbe, 0xfe, 0x72, 0x6b, 0x27, 0x4d, 0xf3, 0x5f, 0xb3, 0x00, 0x00,
0xfb, 0x27, 0x00, 0x00, 0xff, 0xff, 0x99, 0xda, 0x39, 0xd8, 0xb5, 0x04, 0x00, 0x00,
} }

View File

@ -81,25 +81,21 @@ message AllocateRequest {
repeated string devicesIDs = 1; repeated string devicesIDs = 1;
} }
// AllocateResponse includes the artifacts that needs to be injected into
// a container for accessing 'deviceIDs' that were mentioned as part of
// 'AllocateRequest'.
// Failure Handling: // Failure Handling:
// if Kubelet sends an allocation request for dev1 and dev2. // if Kubelet sends an allocation request for dev1 and dev2.
// Allocation on dev1 succeeds but allocation on dev2 fails. // Allocation on dev1 succeeds but allocation on dev2 fails.
// The Device plugin should send a ListAndWatch update and fail the // The Device plugin should send a ListAndWatch update and fail the
// Allocation request // Allocation request
message AllocateResponse { message AllocateResponse {
repeated DeviceRuntimeSpec spec = 1; // List of environment variable to be set in the container to access one of more devices.
} map<string, string> envs = 1;
// The list to be added to the CRI spec
message DeviceRuntimeSpec {
// ID of the Device
string ID = 1;
// List of environment variable to set in the container.
map<string, string> envs = 2;
// Mounts for the container. // Mounts for the container.
repeated Mount mounts = 3; repeated Mount mounts = 2;
// Devices for the container // Devices for the container.
repeated DeviceSpec devices = 4; repeated DeviceSpec devices = 3;
} }
// Mount specifies a host volume to mount into a container. // Mount specifies a host volume to mount into a container.

View File

@ -628,56 +628,60 @@ func (cm *containerManagerImpl) GetResources(pod *v1.Pod, container *v1.Containe
} }
// Loops through AllocationResponses of all required extended resources. // Loops through AllocationResponses of all required extended resources.
for _, resp := range allocResps { for _, resp := range allocResps {
// Loops through runtime spec of all devices of the given resource. // Each Allocate response has the following artifacts.
for _, devRuntime := range resp.Spec { // Environment variables
// Updates RunContainerOptions.Devices. // Mount points
for _, dev := range devRuntime.Devices { // Device files
if d, ok := devsMap[dev.ContainerPath]; ok { // These artifacts are per resource per container.
glog.V(3).Infof("skip existing device %s %s", dev.ContainerPath, dev.HostPath) // Updates RunContainerOptions.Envs.
if d != dev.HostPath { for k, v := range resp.Envs {
glog.Errorf("Container device %s has conflicting mapping host devices: %s and %s", if e, ok := envsMap[k]; ok {
dev.ContainerPath, d, dev.HostPath) glog.V(3).Infof("skip existing envs %s %s", k, v)
} if e != v {
continue glog.Errorf("Environment variable %s has conflicting setting: %s and %s", k, e, v)
} }
devsMap[dev.ContainerPath] = dev.HostPath continue
opts.Devices = append(opts.Devices, kubecontainer.DeviceInfo{
PathOnHost: dev.HostPath,
PathInContainer: dev.ContainerPath,
Permissions: dev.Permissions,
})
} }
// Updates RunContainerOptions.Mounts. envsMap[k] = v
for _, mount := range devRuntime.Mounts { opts.Envs = append(opts.Envs, kubecontainer.EnvVar{Name: k, Value: v})
if m, ok := mountsMap[mount.ContainerPath]; ok { }
glog.V(3).Infof("skip existing mount %s %s", mount.ContainerPath, mount.HostPath)
if m != mount.HostPath { // Updates RunContainerOptions.Devices.
glog.Errorf("Container mount %s has conflicting mapping host mounts: %s and %s", for _, dev := range resp.Devices {
mount.ContainerPath, m, mount.HostPath) if d, ok := devsMap[dev.ContainerPath]; ok {
} glog.V(3).Infof("skip existing device %s %s", dev.ContainerPath, dev.HostPath)
continue if d != dev.HostPath {
glog.Errorf("Container device %s has conflicting mapping host devices: %s and %s",
dev.ContainerPath, d, dev.HostPath)
} }
mountsMap[mount.ContainerPath] = mount.HostPath continue
opts.Mounts = append(opts.Mounts, kubecontainer.Mount{
Name: mount.ContainerPath,
ContainerPath: mount.ContainerPath,
HostPath: mount.HostPath,
ReadOnly: mount.ReadOnly,
SELinuxRelabel: false,
})
} }
// Updates RunContainerOptions.Envs. devsMap[dev.ContainerPath] = dev.HostPath
for k, v := range devRuntime.Envs { opts.Devices = append(opts.Devices, kubecontainer.DeviceInfo{
if e, ok := envsMap[k]; ok { PathOnHost: dev.HostPath,
glog.V(3).Infof("skip existing envs %s %s", k, v) PathInContainer: dev.ContainerPath,
if e != v { Permissions: dev.Permissions,
glog.Errorf("Environment variable %s has conflicting setting: %s and %s", k, e, v) })
} }
continue // Updates RunContainerOptions.Mounts.
for _, mount := range resp.Mounts {
if m, ok := mountsMap[mount.ContainerPath]; ok {
glog.V(3).Infof("skip existing mount %s %s", mount.ContainerPath, mount.HostPath)
if m != mount.HostPath {
glog.Errorf("Container mount %s has conflicting mapping host mounts: %s and %s",
mount.ContainerPath, m, mount.HostPath)
} }
envsMap[k] = v continue
opts.Envs = append(opts.Envs, kubecontainer.EnvVar{Name: k, Value: v})
} }
mountsMap[mount.ContainerPath] = mount.HostPath
opts.Mounts = append(opts.Mounts, kubecontainer.Mount{
Name: mount.ContainerPath,
ContainerPath: mount.ContainerPath,
HostPath: mount.HostPath,
ReadOnly: mount.ReadOnly,
// TODO: This may need to be part of Device plugin API.
SELinuxRelabel: false,
})
} }
} }
return opts, nil return opts, nil

View File

@ -99,9 +99,8 @@ func (m *DevicePluginManagerTestStub) Allocate(resourceName string, devIds []str
for _, id := range devIds { for _, id := range devIds {
key := resourceName + id key := resourceName + id
fmt.Printf("Alloc device %q for resource %q\n", id, resourceName) fmt.Printf("Alloc device %q for resource %q\n", id, resourceName)
devRuntime := new(pluginapi.DeviceRuntimeSpec)
for _, dev := range m.devRuntimeDevices[key] { for _, dev := range m.devRuntimeDevices[key] {
devRuntime.Devices = append(devRuntime.Devices, &pluginapi.DeviceSpec{ resp.Devices = append(resp.Devices, &pluginapi.DeviceSpec{
ContainerPath: dev.value1, ContainerPath: dev.value1,
HostPath: dev.value2, HostPath: dev.value2,
Permissions: "mrw", Permissions: "mrw",
@ -109,17 +108,16 @@ func (m *DevicePluginManagerTestStub) Allocate(resourceName string, devIds []str
} }
for _, mount := range m.devRuntimeMounts[key] { for _, mount := range m.devRuntimeMounts[key] {
fmt.Printf("Add mount %q %q\n", mount.value1, mount.value2) fmt.Printf("Add mount %q %q\n", mount.value1, mount.value2)
devRuntime.Mounts = append(devRuntime.Mounts, &pluginapi.Mount{ resp.Mounts = append(resp.Mounts, &pluginapi.Mount{
ContainerPath: mount.value1, ContainerPath: mount.value1,
HostPath: mount.value2, HostPath: mount.value2,
ReadOnly: true, ReadOnly: true,
}) })
} }
devRuntime.Envs = make(map[string]string) resp.Envs = make(map[string]string)
for _, env := range m.devRuntimeEnvs[key] { for _, env := range m.devRuntimeEnvs[key] {
devRuntime.Envs[env.value1] = env.value2 resp.Envs[env.value1] = env.value2
} }
resp.Spec = append(resp.Spec, devRuntime)
} }
return resp, nil return resp, nil
} }