Merge pull request #39298 from feiskyer/images

Automatic merge from submit-queue

Kubelet: add image ref to ImageService interfaces

This PR adds image ref (digest or ID, depending on runtime) to PullImage result, and pass image ref in CreateContainer instead of image name. It also

* Adds image ref to CRI's PullImageResponse
* Updates related image puller
* Updates related testing utilities

~~One remaining issue is: it breaks some e2e tests because they [checks image repoTags](https://github.com/kubernetes/kubernetes/blob/master/test/e2e/framework/util.go#L1941) while docker always returns digest in this PR. Should we update e2e test or continue to return repoTags in `containerStatuses.image`?~~

Fixes #38833.
pull/6/head
Kubernetes Submit Queue 2016-12-30 22:51:18 -08:00 committed by GitHub
commit f5d9c430e9
28 changed files with 450 additions and 356 deletions

View File

@ -94,7 +94,7 @@ type ImageManagerService interface {
// ImageStatus returns the status of the image.
ImageStatus(image *runtimeapi.ImageSpec) (*runtimeapi.Image, error)
// PullImage pulls an image with the authentication config.
PullImage(image *runtimeapi.ImageSpec, auth *runtimeapi.AuthConfig) error
PullImage(image *runtimeapi.ImageSpec, auth *runtimeapi.AuthConfig) (string, error)
// RemoveImage removes the image.
RemoveImage(image *runtimeapi.ImageSpec) error
}

View File

@ -91,7 +91,7 @@ func (r *FakeImageService) ImageStatus(image *runtimeapi.ImageSpec) (*runtimeapi
return r.Images[image.GetImage()], nil
}
func (r *FakeImageService) PullImage(image *runtimeapi.ImageSpec, auth *runtimeapi.AuthConfig) error {
func (r *FakeImageService) PullImage(image *runtimeapi.ImageSpec, auth *runtimeapi.AuthConfig) (string, error) {
r.Lock()
defer r.Unlock()
@ -104,7 +104,7 @@ func (r *FakeImageService) PullImage(image *runtimeapi.ImageSpec, auth *runtimea
r.Images[imageID] = r.makeFakeImage(image.GetImage())
}
return nil
return imageID, nil
}
func (r *FakeImageService) RemoveImage(image *runtimeapi.ImageSpec) error {

View File

@ -1194,9 +1194,8 @@ func (m *ListPodSandboxResponse) GetItems() []*PodSandbox {
}
// ImageSpec is an internal representation of an image. Currently, it wraps the
// value of a Container's Image field (e.g. imageName, imageName:tag, or
// imageName:digest), but in the future it will include more detailed
// information about the different image types.
// value of a Container's Image field (e.g. imageID or imageDigest), but in the
// future it will include more detailed information about the different image types.
type ImageSpec struct {
Image *string `protobuf:"bytes,1,opt,name=image" json:"image,omitempty"`
XXX_unrecognized []byte `json:"-"`
@ -2741,7 +2740,10 @@ func (m *PullImageRequest) GetSandboxConfig() *PodSandboxConfig {
}
type PullImageResponse struct {
XXX_unrecognized []byte `json:"-"`
// Reference to the image in use. For most runtimes, this should be an
// image ID or digest.
ImageRef *string `protobuf:"bytes,1,opt,name=image_ref,json=imageRef" json:"image_ref,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *PullImageResponse) Reset() { *m = PullImageResponse{} }
@ -2749,6 +2751,13 @@ func (m *PullImageResponse) String() string { return proto.CompactTex
func (*PullImageResponse) ProtoMessage() {}
func (*PullImageResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{67} }
func (m *PullImageResponse) GetImageRef() string {
if m != nil && m.ImageRef != nil {
return *m.ImageRef
}
return ""
}
type RemoveImageRequest struct {
// Spec of the image to remove.
Image *ImageSpec `protobuf:"bytes,1,opt,name=image" json:"image,omitempty"`
@ -3910,217 +3919,217 @@ var _ImageService_serviceDesc = grpc.ServiceDesc{
}
var fileDescriptorApi = []byte{
// 3380 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x3a, 0x4d, 0x73, 0x1b, 0xc7,
0xb1, 0x04, 0x40, 0x82, 0x40, 0x83, 0x00, 0xc1, 0x21, 0x45, 0x42, 0xa0, 0x25, 0x51, 0x6b, 0x49,
0x96, 0x64, 0x5b, 0xcf, 0xe2, 0x7b, 0xcf, 0x7a, 0x96, 0x2d, 0xd9, 0x30, 0x49, 0xbb, 0x68, 0x49,
0x10, 0xbd, 0x90, 0xfc, 0xec, 0xf8, 0xb0, 0x59, 0x61, 0x87, 0xe0, 0x4a, 0xc0, 0xee, 0x7a, 0x77,
0x40, 0x8b, 0xf9, 0x05, 0x39, 0x24, 0x55, 0xb9, 0xfa, 0x96, 0x4a, 0xa5, 0xca, 0x95, 0xe4, 0x96,
0xaa, 0x54, 0xe5, 0x96, 0x1f, 0x90, 0xca, 0x0f, 0xc8, 0x4f, 0xc8, 0xbf, 0x48, 0xcd, 0xd7, 0xee,
0xcc, 0x7e, 0x50, 0xa4, 0xec, 0x8a, 0x75, 0xdb, 0xe9, 0xee, 0xe9, 0xe9, 0xe9, 0xee, 0xe9, 0xe9,
0xee, 0x59, 0xa8, 0xdb, 0x81, 0x7b, 0x23, 0x08, 0x7d, 0xe2, 0xa3, 0xf9, 0x70, 0xea, 0x11, 0x77,
0x82, 0x8d, 0xeb, 0xd0, 0xfa, 0x02, 0x87, 0x91, 0xeb, 0x7b, 0x26, 0xfe, 0x66, 0x8a, 0x23, 0x82,
0x3a, 0x30, 0x7f, 0xc8, 0x21, 0x9d, 0xd2, 0x46, 0xe9, 0x6a, 0xdd, 0x94, 0x43, 0xe3, 0xfb, 0x12,
0x2c, 0xc6, 0xc4, 0x51, 0xe0, 0x7b, 0x11, 0x2e, 0xa6, 0x46, 0x17, 0x61, 0x41, 0x2c, 0x62, 0x79,
0xf6, 0x04, 0x77, 0xca, 0x0c, 0xdd, 0x10, 0xb0, 0xbe, 0x3d, 0xc1, 0xe8, 0x0d, 0x58, 0x94, 0x24,
0x92, 0x49, 0x85, 0x51, 0xb5, 0x04, 0x58, 0xac, 0x86, 0x6e, 0xc0, 0xb2, 0x24, 0xb4, 0x03, 0x37,
0x26, 0x9e, 0x65, 0xc4, 0x4b, 0x02, 0xd5, 0x0b, 0x5c, 0x41, 0x6f, 0x7c, 0x0d, 0xf5, 0xed, 0xfe,
0x60, 0xcb, 0xf7, 0xf6, 0xdd, 0x11, 0x15, 0x31, 0xc2, 0x21, 0x9d, 0xd3, 0x29, 0x6d, 0x54, 0xa8,
0x88, 0x62, 0x88, 0xba, 0x50, 0x8b, 0xb0, 0x1d, 0x0e, 0x0f, 0x70, 0xd4, 0x29, 0x33, 0x54, 0x3c,
0xa6, 0xb3, 0xfc, 0x80, 0xb8, 0xbe, 0x17, 0x75, 0x2a, 0x7c, 0x96, 0x18, 0x1a, 0xdf, 0x95, 0xa0,
0xb1, 0xe7, 0x87, 0xe4, 0x81, 0x1d, 0x04, 0xae, 0x37, 0x42, 0x6f, 0x43, 0x8d, 0x29, 0x75, 0xe8,
0x8f, 0x99, 0x0e, 0x5a, 0x9b, 0x4b, 0x37, 0x84, 0x48, 0x37, 0xf6, 0x04, 0xc2, 0x8c, 0x49, 0xd0,
0x65, 0x68, 0x0d, 0x7d, 0x8f, 0xd8, 0xae, 0x87, 0x43, 0x2b, 0xf0, 0x43, 0xc2, 0x34, 0x33, 0x67,
0x36, 0x63, 0x28, 0x65, 0x8e, 0xd6, 0xa1, 0x7e, 0xe0, 0x47, 0x84, 0x53, 0x54, 0x18, 0x45, 0x8d,
0x02, 0x18, 0x72, 0x0d, 0xe6, 0x19, 0xd2, 0x0d, 0x84, 0x0e, 0xaa, 0x74, 0xb8, 0x1b, 0x18, 0xbf,
0x29, 0xc1, 0xdc, 0x03, 0x7f, 0xea, 0x91, 0xd4, 0x32, 0x36, 0x39, 0x10, 0xf6, 0x51, 0x96, 0xb1,
0xc9, 0x41, 0xb2, 0x0c, 0xa5, 0xe0, 0x26, 0xe2, 0xcb, 0x50, 0x64, 0x17, 0x6a, 0x21, 0xb6, 0x1d,
0xdf, 0x1b, 0x1f, 0x31, 0x11, 0x6a, 0x66, 0x3c, 0xa6, 0xb6, 0x8b, 0xf0, 0xd8, 0xf5, 0xa6, 0xcf,
0xad, 0x10, 0x8f, 0xed, 0x27, 0x78, 0xcc, 0x44, 0xa9, 0x99, 0x2d, 0x01, 0x36, 0x39, 0xd4, 0x78,
0x0a, 0x8b, 0xd4, 0xd8, 0x51, 0x60, 0x0f, 0xf1, 0x43, 0xa6, 0x42, 0xea, 0x1a, 0x6c, 0x51, 0x0f,
0x93, 0x6f, 0xfd, 0xf0, 0x19, 0x93, 0xac, 0x66, 0x36, 0x28, 0xac, 0xcf, 0x41, 0xe8, 0x2c, 0xd4,
0xb8, 0x5c, 0xae, 0xc3, 0xc4, 0xaa, 0x99, 0x6c, 0xc7, 0x7b, 0xae, 0x13, 0xa3, 0xdc, 0x60, 0x28,
0xa4, 0x9a, 0xe7, 0xbb, 0x1f, 0x1a, 0x7f, 0x2b, 0xc3, 0xfa, 0x7d, 0xba, 0xf8, 0xc0, 0xf6, 0x9c,
0x27, 0xfe, 0xf3, 0x01, 0x1e, 0x4e, 0x43, 0x97, 0x1c, 0x6d, 0xf9, 0x1e, 0xc1, 0xcf, 0x09, 0xda,
0x81, 0x25, 0x4f, 0xca, 0x62, 0x49, 0xf3, 0xd2, 0xd5, 0x1b, 0x9b, 0x9d, 0xd8, 0x66, 0x29, 0x69,
0xcd, 0xb6, 0xa7, 0x03, 0x22, 0xf4, 0x61, 0xb2, 0x77, 0xc9, 0xa4, 0xcc, 0x98, 0xac, 0xc6, 0x4c,
0x06, 0x3b, 0x4c, 0x0e, 0xc1, 0x42, 0xea, 0x44, 0x32, 0x38, 0x0f, 0xf4, 0x1c, 0x58, 0x76, 0x64,
0x4d, 0x23, 0x1c, 0xb2, 0x5d, 0x54, 0xcc, 0x7a, 0x38, 0xf5, 0x7a, 0xd1, 0xe3, 0x08, 0x87, 0xec,
0x60, 0x08, 0x45, 0x5b, 0xa1, 0xef, 0x93, 0xfd, 0x48, 0x2a, 0x57, 0x82, 0x4d, 0x06, 0x45, 0xff,
0x05, 0xcb, 0xd1, 0x34, 0x08, 0xc6, 0x78, 0x82, 0x3d, 0x62, 0x8f, 0xad, 0x51, 0xe8, 0x4f, 0x83,
0xa8, 0x33, 0xb7, 0x51, 0xb9, 0x5a, 0x31, 0x91, 0x8a, 0xfa, 0x94, 0x61, 0xd0, 0x79, 0x80, 0x20,
0x74, 0x0f, 0xdd, 0x31, 0x1e, 0x61, 0xa7, 0x53, 0x65, 0x4c, 0x15, 0x88, 0xf1, 0xeb, 0x12, 0x9c,
0x61, 0x92, 0xef, 0xf9, 0x8e, 0x50, 0xa2, 0x38, 0x46, 0xaf, 0x43, 0x73, 0xc8, 0xd8, 0x5b, 0x81,
0x1d, 0x62, 0x8f, 0x08, 0x7f, 0x5a, 0xe0, 0xc0, 0x3d, 0x06, 0x43, 0x0f, 0xa1, 0x1d, 0x09, 0x9d,
0x5b, 0x43, 0xae, 0x74, 0xa1, 0x9a, 0x4b, 0xb1, 0x6a, 0x8e, 0x31, 0x90, 0xb9, 0x18, 0xe9, 0x00,
0x23, 0x04, 0x94, 0x48, 0xf2, 0x00, 0x13, 0xdb, 0xb1, 0x89, 0x8d, 0x10, 0xcc, 0xb2, 0x98, 0xc2,
0x45, 0x60, 0xdf, 0xa8, 0x0d, 0x95, 0xa9, 0x70, 0x96, 0xba, 0x49, 0x3f, 0xd1, 0x6b, 0x50, 0x8f,
0x4d, 0x27, 0x02, 0x4b, 0x02, 0xa0, 0x07, 0xdc, 0x26, 0x04, 0x4f, 0x02, 0xc2, 0x74, 0xdb, 0x34,
0xe5, 0xd0, 0xf8, 0xeb, 0x2c, 0xb4, 0x33, 0xdb, 0xbf, 0x05, 0xb5, 0x89, 0x58, 0x5e, 0x78, 0xcc,
0x7a, 0x72, 0xca, 0x33, 0x12, 0x9a, 0x31, 0x31, 0x3d, 0x44, 0xd4, 0x3d, 0x95, 0x18, 0x18, 0x8f,
0xa9, 0x4e, 0xc7, 0xfe, 0xc8, 0x72, 0xdc, 0x10, 0x0f, 0x89, 0x1f, 0x1e, 0x09, 0x29, 0x17, 0xc6,
0xfe, 0x68, 0x5b, 0xc2, 0xd0, 0x4d, 0x00, 0xc7, 0x8b, 0xa8, 0x3a, 0xf7, 0xdd, 0x11, 0x93, 0xb5,
0xb1, 0x89, 0xe2, 0xb5, 0xe3, 0x38, 0x67, 0xd6, 0x1d, 0x2f, 0x12, 0xc2, 0xbe, 0x07, 0x4d, 0x1a,
0x37, 0xac, 0x09, 0x0f, 0x51, 0xdc, 0x21, 0x1a, 0x9b, 0x2b, 0x8a, 0xc4, 0x71, 0xfc, 0x32, 0x17,
0x82, 0x64, 0x10, 0xa1, 0x3b, 0x50, 0x65, 0xe7, 0x36, 0xea, 0x54, 0xd9, 0x9c, 0xcb, 0x39, 0xbb,
0xe4, 0xab, 0xdc, 0xb8, 0xcf, 0xe8, 0x76, 0x3c, 0x12, 0x1e, 0x99, 0x62, 0x12, 0xba, 0x0f, 0x0d,
0xdb, 0xf3, 0x7c, 0x62, 0xf3, 0x63, 0x31, 0xcf, 0x78, 0x5c, 0x2f, 0xe6, 0xd1, 0x4b, 0x88, 0x39,
0x23, 0x75, 0x3a, 0xfa, 0x1f, 0x98, 0x63, 0xe7, 0xa6, 0x53, 0x63, 0xbb, 0x3e, 0xaf, 0xfb, 0x50,
0x9a, 0x99, 0xc9, 0x89, 0xbb, 0xef, 0x41, 0x43, 0x11, 0x8d, 0x3a, 0xc6, 0x33, 0x7c, 0x24, 0x7c,
0x85, 0x7e, 0xa2, 0x15, 0x98, 0x3b, 0xb4, 0xc7, 0x53, 0x69, 0x0f, 0x3e, 0xb8, 0x5d, 0xfe, 0xbf,
0x52, 0xf7, 0x2e, 0xb4, 0xd3, 0x12, 0x9d, 0x66, 0xbe, 0xb1, 0x0b, 0x2b, 0xe6, 0xd4, 0x4b, 0x04,
0x93, 0x97, 0xea, 0x4d, 0xa8, 0x0a, 0xfb, 0x71, 0xdf, 0x39, 0x5b, 0xa8, 0x11, 0x53, 0x10, 0x1a,
0x77, 0xe0, 0x4c, 0x8a, 0x95, 0xb8, 0x72, 0x2f, 0x41, 0x2b, 0xf0, 0x1d, 0x2b, 0xe2, 0x60, 0xcb,
0x75, 0xe4, 0x49, 0x0c, 0x62, 0xda, 0x5d, 0x87, 0x4e, 0x1f, 0x10, 0x3f, 0xc8, 0x8a, 0x72, 0xb2,
0xe9, 0x1d, 0x58, 0x4d, 0x4f, 0xe7, 0xcb, 0x1b, 0x1f, 0xc2, 0x9a, 0x89, 0x27, 0xfe, 0x21, 0x7e,
0x59, 0xd6, 0x5d, 0xe8, 0x64, 0x19, 0x24, 0xcc, 0x13, 0xe8, 0x80, 0xd8, 0x64, 0x1a, 0x9d, 0x8e,
0xf9, 0x35, 0x95, 0x81, 0xb8, 0x4c, 0x38, 0x1f, 0xd4, 0x82, 0xb2, 0x1b, 0x88, 0x49, 0x65, 0x37,
0x30, 0xbe, 0x82, 0x7a, 0x5f, 0x8d, 0x06, 0xea, 0x6d, 0x54, 0x37, 0xe5, 0x10, 0x6d, 0x26, 0x89,
0x40, 0xf9, 0x05, 0x37, 0x45, 0x9c, 0x22, 0xdc, 0xcb, 0x04, 0x51, 0x21, 0xc3, 0x26, 0x40, 0x1c,
0x81, 0xe4, 0xcd, 0x83, 0xb2, 0xfc, 0x4c, 0x85, 0xca, 0xf8, 0xbd, 0x16, 0x8e, 0x94, 0xcd, 0x38,
0xf1, 0x66, 0x1c, 0x2d, 0x3c, 0x95, 0x4f, 0x13, 0x9e, 0x6e, 0xc0, 0x5c, 0x44, 0x6c, 0xc2, 0x03,
0x64, 0x4b, 0xd9, 0x9c, 0xbe, 0x24, 0x36, 0x39, 0x19, 0x3a, 0x07, 0x30, 0x0c, 0xb1, 0x4d, 0xb0,
0x63, 0xd9, 0x3c, 0x72, 0x56, 0xcc, 0xba, 0x80, 0xf4, 0x08, 0xba, 0x9d, 0xe8, 0x71, 0x8e, 0x89,
0xb1, 0x91, 0xc3, 0x50, 0xb3, 0x4b, 0xa2, 0xe9, 0xf8, 0xb4, 0x57, 0x8f, 0x3f, 0xed, 0x62, 0x1e,
0x27, 0x56, 0x02, 0xd6, 0x7c, 0x61, 0xc0, 0xe2, 0x33, 0x4e, 0x12, 0xb0, 0x6a, 0x85, 0x01, 0x4b,
0xf0, 0x38, 0x36, 0x60, 0xfd, 0x94, 0xa1, 0xe7, 0x01, 0x74, 0xb2, 0x47, 0x47, 0x84, 0x8c, 0x9b,
0x50, 0x8d, 0x18, 0xe4, 0x98, 0xf0, 0x23, 0xa6, 0x08, 0x42, 0xe3, 0x5f, 0x25, 0xd5, 0xeb, 0x3e,
0x71, 0xc7, 0x04, 0x87, 0x19, 0xaf, 0x8b, 0x9d, 0xa7, 0x7c, 0x32, 0xe7, 0x19, 0x40, 0x8b, 0xa9,
0xdd, 0x8a, 0xf0, 0x98, 0xdd, 0x6e, 0x2c, 0xb7, 0x6e, 0x6c, 0xbe, 0x95, 0x33, 0x91, 0x2f, 0xc9,
0x6d, 0x36, 0x10, 0xe4, 0x5c, 0xe3, 0xcd, 0xb1, 0x0a, 0xeb, 0x7e, 0x04, 0x28, 0x4b, 0x74, 0x2a,
0xd5, 0x7d, 0x46, 0x8f, 0x2b, 0x4d, 0xad, 0x73, 0xc2, 0xf6, 0x3e, 0x13, 0xe3, 0x18, 0xbd, 0x71,
0x39, 0x4d, 0x41, 0x68, 0xfc, 0xb6, 0x02, 0x90, 0x20, 0x5f, 0xd9, 0x73, 0x7a, 0x2b, 0x3e, 0x35,
0x3c, 0x35, 0xb8, 0x90, 0xc3, 0x2f, 0xf7, 0xbc, 0x7c, 0xa2, 0x9f, 0x17, 0x9e, 0x24, 0x5c, 0xca,
0x9b, 0xfd, 0xca, 0x9e, 0x94, 0x2d, 0x58, 0x4d, 0x9b, 0x5b, 0x9c, 0x93, 0x6b, 0x30, 0xe7, 0x12,
0x3c, 0xe1, 0x85, 0x62, 0x63, 0x73, 0x39, 0x67, 0x5b, 0x26, 0xa7, 0x30, 0x2e, 0x42, 0x7d, 0x77,
0x62, 0x8f, 0xf0, 0x20, 0xc0, 0x43, 0xba, 0x96, 0x4b, 0x07, 0x62, 0x7d, 0x3e, 0x30, 0x36, 0xa1,
0x76, 0x0f, 0x1f, 0x7d, 0x41, 0xd7, 0x3d, 0xa9, 0x7c, 0xc6, 0xdf, 0x4b, 0xb0, 0xc6, 0xc2, 0xdd,
0x96, 0x2c, 0xd3, 0x4c, 0x1c, 0xf9, 0xd3, 0x70, 0x88, 0x23, 0x66, 0xd2, 0x60, 0x6a, 0x05, 0x38,
0x74, 0x7d, 0xee, 0x53, 0xd4, 0xa4, 0xc1, 0x74, 0x8f, 0x01, 0x68, 0x29, 0x47, 0xd1, 0xdf, 0x4c,
0x7d, 0xe1, 0x5b, 0x15, 0xb3, 0x36, 0x0c, 0xa6, 0x9f, 0xd3, 0xb1, 0x9c, 0x1b, 0x1d, 0xd8, 0x21,
0x8e, 0x64, 0xc1, 0x31, 0x0c, 0xa6, 0x03, 0x06, 0x40, 0x37, 0xe1, 0xcc, 0x04, 0x4f, 0xfc, 0xf0,
0xc8, 0x1a, 0xbb, 0x13, 0x97, 0x58, 0xae, 0x67, 0x3d, 0x39, 0x22, 0x38, 0x12, 0x8e, 0x83, 0x38,
0xf2, 0x3e, 0xc5, 0xed, 0x7a, 0x1f, 0x53, 0x0c, 0x32, 0xa0, 0xe9, 0xfb, 0x13, 0x2b, 0x1a, 0xfa,
0x21, 0xb6, 0x6c, 0xe7, 0x29, 0x8b, 0xf7, 0x15, 0xb3, 0xe1, 0xfb, 0x93, 0x01, 0x85, 0xf5, 0x9c,
0xa7, 0x86, 0x0d, 0x4d, 0xad, 0x10, 0xa2, 0x89, 0x3b, 0xab, 0x78, 0x44, 0xe2, 0x4e, 0xbf, 0x29,
0x2c, 0xf4, 0xc7, 0x52, 0x0f, 0xec, 0x9b, 0xc2, 0xc8, 0x51, 0x20, 0xb3, 0x76, 0xf6, 0x4d, 0x15,
0x36, 0xc6, 0x87, 0xa2, 0xce, 0xac, 0x9b, 0x7c, 0x60, 0x38, 0x00, 0x5b, 0x76, 0x60, 0x3f, 0x71,
0xc7, 0x2e, 0x39, 0x42, 0xd7, 0xa0, 0x6d, 0x3b, 0x8e, 0x35, 0x94, 0x10, 0x17, 0xcb, 0xa2, 0x7f,
0xd1, 0x76, 0x9c, 0x2d, 0x05, 0x8c, 0xde, 0x84, 0x25, 0x27, 0xf4, 0x03, 0x9d, 0x96, 0x77, 0x01,
0xda, 0x14, 0xa1, 0x12, 0x1b, 0xbf, 0xab, 0xc0, 0x39, 0xdd, 0x2c, 0xe9, 0xd2, 0xf2, 0x16, 0x2c,
0xa4, 0x56, 0x2d, 0x69, 0x1e, 0x94, 0x08, 0x69, 0x6a, 0x84, 0xa9, 0x8a, 0xac, 0x9c, 0xae, 0xc8,
0xf2, 0x6b, 0xd6, 0xca, 0x8f, 0x51, 0xb3, 0xce, 0xfe, 0x90, 0x9a, 0x75, 0x2e, 0x5d, 0xb3, 0x5e,
0x61, 0xcd, 0x1c, 0x89, 0x67, 0xe5, 0x4e, 0x95, 0x77, 0x1c, 0x62, 0x1a, 0x4f, 0x36, 0x7d, 0x52,
0xb5, 0xed, 0xfc, 0x69, 0x6a, 0xdb, 0x5a, 0x51, 0x6d, 0x6b, 0xfc, 0xa1, 0x04, 0x2b, 0xba, 0x91,
0x44, 0x39, 0x74, 0x17, 0xea, 0xa1, 0x3c, 0x45, 0xc2, 0x30, 0x1b, 0x7a, 0x72, 0x91, 0x3d, 0x6d,
0x66, 0x32, 0x05, 0x7d, 0x5e, 0x58, 0xd5, 0x5e, 0x29, 0x60, 0xf3, 0xc2, 0xba, 0xb6, 0x07, 0x4b,
0x31, 0xf1, 0xb1, 0x65, 0xad, 0x52, 0xa6, 0x96, 0xf5, 0x32, 0xd5, 0x83, 0xea, 0x36, 0x3e, 0x74,
0x87, 0xf8, 0x47, 0xe9, 0xf5, 0x6c, 0x40, 0x23, 0xc0, 0xe1, 0xc4, 0x8d, 0xa2, 0xd8, 0xc1, 0xea,
0xa6, 0x0a, 0x32, 0xfe, 0x39, 0x07, 0x8b, 0x69, 0xcd, 0xbe, 0x9b, 0xa9, 0x8a, 0xbb, 0x89, 0xc7,
0xa7, 0xf7, 0xa7, 0xdc, 0x66, 0x57, 0x65, 0xc0, 0x2c, 0xa7, 0x52, 0xe0, 0x38, 0xa6, 0x8a, 0x20,
0x4a, 0xf7, 0x3f, 0xf4, 0x27, 0x13, 0xdb, 0x73, 0x64, 0x1f, 0x4e, 0x0c, 0xa9, 0xb6, 0xec, 0x70,
0x44, 0xdd, 0x98, 0x82, 0xd9, 0x37, 0xba, 0x00, 0x0d, 0x9a, 0x4a, 0xba, 0x1e, 0x2b, 0xaa, 0x99,
0x93, 0xd6, 0x4d, 0x10, 0xa0, 0x6d, 0x37, 0x44, 0x97, 0x61, 0x16, 0x7b, 0x87, 0xf2, 0xde, 0x4a,
0x1a, 0x75, 0x32, 0x50, 0x9b, 0x0c, 0x8d, 0xae, 0x40, 0x75, 0xe2, 0x4f, 0x3d, 0x22, 0x93, 0xca,
0x56, 0x4c, 0xc8, 0xba, 0x6b, 0xa6, 0xc0, 0xa2, 0x6b, 0x30, 0xef, 0x30, 0x1b, 0xc8, 0xcc, 0x71,
0x31, 0x29, 0xcc, 0x19, 0xdc, 0x94, 0x78, 0xf4, 0x41, 0x7c, 0xe3, 0xd6, 0x53, 0x77, 0x66, 0x4a,
0xa9, 0xb9, 0xd7, 0xee, 0x3d, 0xfd, 0xda, 0x05, 0xc6, 0xe2, 0x5a, 0x21, 0x8b, 0xe3, 0xcb, 0xea,
0xb3, 0x50, 0x1b, 0xfb, 0x23, 0xee, 0x07, 0x0d, 0x5e, 0xed, 0x8c, 0xfd, 0x11, 0x73, 0x83, 0x15,
0x9a, 0x66, 0x38, 0xae, 0xd7, 0x59, 0x60, 0x67, 0x92, 0x0f, 0xe8, 0xed, 0xc1, 0x3e, 0x2c, 0xdf,
0x1b, 0xe2, 0x4e, 0x93, 0xa1, 0xea, 0x0c, 0xf2, 0xd0, 0x1b, 0xb2, 0xcb, 0x8d, 0x90, 0xa3, 0x4e,
0x8b, 0xc1, 0xe9, 0x27, 0xfa, 0x6f, 0x99, 0xca, 0x2f, 0x32, 0xfb, 0x9e, 0x2b, 0x38, 0x26, 0xaf,
0x4c, 0xdd, 0xfe, 0xe7, 0x12, 0xac, 0x6e, 0xb1, 0xe4, 0x48, 0x89, 0x04, 0xa7, 0xa8, 0x3b, 0xd1,
0x3b, 0x71, 0x81, 0x9f, 0x2e, 0x12, 0xd3, 0x9b, 0x15, 0x74, 0xe8, 0x23, 0x68, 0x49, 0x9e, 0x62,
0x66, 0xe5, 0x45, 0xad, 0x81, 0x66, 0xa4, 0x0e, 0x8d, 0x0f, 0x60, 0x2d, 0x23, 0xb3, 0x48, 0x64,
0x2e, 0xc2, 0x42, 0x12, 0x11, 0x62, 0x91, 0x1b, 0x31, 0x6c, 0xd7, 0x31, 0x6e, 0xc3, 0x99, 0x01,
0xb1, 0x43, 0x92, 0xd9, 0xf0, 0x09, 0xe6, 0xb2, 0xee, 0x80, 0x3e, 0x57, 0x14, 0xf0, 0x03, 0x58,
0x19, 0x10, 0x3f, 0x78, 0x09, 0xa6, 0xf4, 0xa4, 0xd3, 0x6d, 0xfb, 0x53, 0x22, 0xb2, 0x17, 0x39,
0x34, 0xd6, 0x78, 0x2f, 0x23, 0xbb, 0xda, 0xfb, 0xb0, 0xca, 0x5b, 0x09, 0x2f, 0xb3, 0x89, 0xb3,
0xb2, 0x91, 0x91, 0xe5, 0xfb, 0xab, 0xb2, 0x12, 0xea, 0x0a, 0x6a, 0x9f, 0xb7, 0xf5, 0xda, 0x67,
0x2d, 0x6b, 0x70, 0x2d, 0x1f, 0xcf, 0xba, 0x51, 0x25, 0xc7, 0x8d, 0xcc, 0x4c, 0x81, 0x34, 0xcb,
0x4e, 0xfa, 0x9b, 0x59, 0xee, 0xff, 0xc1, 0xfa, 0x68, 0x97, 0xd7, 0x47, 0xf1, 0xd2, 0x71, 0x4f,
0xe6, 0x9d, 0x54, 0x7d, 0xd4, 0x29, 0x12, 0x33, 0x2e, 0x8f, 0x7e, 0x39, 0x0b, 0xf5, 0x18, 0x97,
0xd1, 0x69, 0x56, 0x49, 0xe5, 0x1c, 0x25, 0xa9, 0x97, 0x4e, 0xe5, 0x65, 0x2e, 0x9d, 0xd9, 0x17,
0x5d, 0x3a, 0xeb, 0x50, 0x67, 0x1f, 0x56, 0x88, 0xf7, 0xc5, 0x25, 0x52, 0x63, 0x00, 0x13, 0xef,
0x27, 0x86, 0xaf, 0x9e, 0xc8, 0xf0, 0x7a, 0x21, 0x36, 0x9f, 0x2e, 0xc4, 0xde, 0x8d, 0xaf, 0x05,
0x7e, 0x81, 0x9c, 0xcf, 0xb2, 0xcb, 0xbd, 0x10, 0x76, 0xf4, 0x0b, 0x81, 0xdf, 0x29, 0xaf, 0xe7,
0x4c, 0x7e, 0x65, 0xcb, 0xb0, 0xfb, 0xbc, 0x0c, 0x53, 0xbd, 0x4a, 0x44, 0xaf, 0x4d, 0x80, 0xf8,
0xa0, 0xca, 0x5a, 0x0c, 0x65, 0xb7, 0x66, 0x2a, 0x54, 0x34, 0x14, 0x68, 0xfa, 0x4f, 0x1a, 0x87,
0x27, 0x08, 0x05, 0x7f, 0x52, 0x53, 0x9b, 0x82, 0x0e, 0xdb, 0xbb, 0x99, 0xca, 0xfd, 0x64, 0x5e,
0xf7, 0xb6, 0x5e, 0xb8, 0x9f, 0xce, 0x5d, 0x32, 0x75, 0x3b, 0xbb, 0x89, 0xed, 0x50, 0xa0, 0x45,
0x12, 0x2e, 0x20, 0x3d, 0x42, 0xf3, 0x9f, 0x7d, 0xd7, 0x73, 0xa3, 0x03, 0x8e, 0xaf, 0x32, 0x3c,
0x48, 0x50, 0x8f, 0x3d, 0x2b, 0xe2, 0xe7, 0x2e, 0xb1, 0x86, 0xbe, 0x83, 0x99, 0x33, 0xce, 0x99,
0x35, 0x0a, 0xd8, 0xf2, 0x1d, 0x9c, 0x1c, 0x90, 0xda, 0xa9, 0x0e, 0x48, 0x3d, 0x75, 0x40, 0x56,
0xa1, 0x1a, 0x62, 0x3b, 0xf2, 0xbd, 0x0e, 0xf0, 0xc7, 0x49, 0x3e, 0xa2, 0x01, 0x7e, 0x82, 0xa3,
0x88, 0x2e, 0x20, 0xb2, 0x0e, 0x31, 0x54, 0x72, 0xa3, 0x85, 0xa2, 0xdc, 0xe8, 0x98, 0x16, 0x5e,
0x2a, 0x37, 0x6a, 0x16, 0xe5, 0x46, 0x27, 0xe9, 0xe0, 0x29, 0x99, 0x5f, 0xeb, 0xb8, 0xcc, 0xef,
0xa7, 0x3c, 0x38, 0xf7, 0x60, 0x2d, 0xe3, 0xea, 0xe2, 0xe4, 0xbc, 0x93, 0x6a, 0xf4, 0x75, 0x8a,
0xb4, 0x10, 0xf7, 0xf9, 0x7e, 0x0e, 0x8b, 0x3b, 0xcf, 0xf1, 0x70, 0x70, 0xe4, 0x0d, 0x4f, 0x71,
0x57, 0xb7, 0xa1, 0x32, 0x9c, 0x38, 0xa2, 0x5c, 0xa6, 0x9f, 0xea, 0xed, 0x5d, 0xd1, 0x6f, 0x6f,
0x0b, 0xda, 0xc9, 0x0a, 0x42, 0xce, 0x55, 0x2a, 0xa7, 0x43, 0x89, 0x29, 0xf3, 0x05, 0x53, 0x8c,
0x04, 0x1c, 0x87, 0x21, 0xdb, 0x35, 0x87, 0xe3, 0x30, 0xd4, 0xdd, 0xb6, 0xa2, 0xbb, 0xad, 0xf1,
0x14, 0x1a, 0x74, 0x81, 0x1f, 0x24, 0xbe, 0x48, 0x61, 0x2b, 0x49, 0x0a, 0x1b, 0x67, 0xc2, 0xb3,
0x4a, 0x26, 0x6c, 0x6c, 0xc0, 0x02, 0x5f, 0x4b, 0x6c, 0xa4, 0x0d, 0x95, 0x69, 0x38, 0x96, 0x76,
0x9b, 0x86, 0x63, 0xe3, 0x67, 0xd0, 0xec, 0x11, 0x62, 0x0f, 0x0f, 0x4e, 0x21, 0x4f, 0xbc, 0x56,
0x59, 0xcd, 0xba, 0x33, 0x32, 0x19, 0x06, 0xb4, 0x24, 0xef, 0xc2, 0xf5, 0xfb, 0x80, 0xf6, 0xfc,
0x90, 0x7c, 0xe2, 0x87, 0xdf, 0xda, 0xa1, 0x73, 0xba, 0x2c, 0x16, 0xc1, 0xac, 0xf8, 0x23, 0xa1,
0x72, 0x75, 0xce, 0x64, 0xdf, 0xc6, 0x1b, 0xb0, 0xac, 0xf1, 0x2b, 0x5c, 0xf8, 0x16, 0x34, 0x58,
0x9c, 0x10, 0xf9, 0xd2, 0x55, 0xb5, 0x27, 0x76, 0x5c, 0x30, 0xa1, 0xb5, 0x30, 0xbd, 0x08, 0x18,
0x3c, 0x8e, 0xda, 0x6f, 0xa5, 0x52, 0x8b, 0x15, 0x7d, 0x7e, 0x2a, 0xad, 0xf8, 0xae, 0x04, 0x73,
0x0c, 0x9e, 0x09, 0xdb, 0xeb, 0xb4, 0xf6, 0x0f, 0x7c, 0x8b, 0xd8, 0xa3, 0xf8, 0x27, 0x0f, 0x0a,
0x78, 0x64, 0x8f, 0x22, 0xf6, 0x8f, 0x0a, 0x45, 0x3a, 0xee, 0x08, 0x47, 0x44, 0xfe, 0xe9, 0xd1,
0xa0, 0xb0, 0x6d, 0x0e, 0xa2, 0x2a, 0x89, 0xdc, 0x5f, 0xf0, 0x9c, 0x61, 0xd6, 0x64, 0xdf, 0xf2,
0xa9, 0x99, 0x47, 0x5f, 0xf6, 0xd4, 0xdc, 0x85, 0x5a, 0xaa, 0xeb, 0x11, 0x8f, 0x8d, 0x0f, 0x00,
0xa9, 0xdb, 0x13, 0xfa, 0xbb, 0x02, 0x55, 0xb6, 0x7b, 0x79, 0xbf, 0xb5, 0xf4, 0xfd, 0x99, 0x02,
0x6b, 0xdc, 0x05, 0xc4, 0x15, 0xa6, 0xdd, 0x69, 0x27, 0x57, 0xee, 0xfb, 0xb0, 0xac, 0xcd, 0x8f,
0x1f, 0x11, 0x35, 0x06, 0xe9, 0xd5, 0xc5, 0xe4, 0x7f, 0x94, 0x00, 0x7a, 0x53, 0x72, 0x20, 0xaa,
0x7d, 0x75, 0x97, 0x25, 0x7d, 0x97, 0x14, 0x17, 0xd8, 0x51, 0xf4, 0xad, 0x1f, 0xca, 0xa4, 0x2d,
0x1e, 0xb3, 0x4a, 0x7d, 0x4a, 0x0e, 0x64, 0x37, 0x8f, 0x7e, 0xa3, 0xcb, 0xd0, 0xe2, 0xbf, 0xe1,
0x58, 0xb6, 0xe3, 0x84, 0x38, 0x8a, 0x44, 0x5b, 0xaf, 0xc9, 0xa1, 0x3d, 0x0e, 0xa4, 0x64, 0xae,
0x83, 0x3d, 0xe2, 0x92, 0x23, 0x8b, 0xf8, 0xcf, 0xb0, 0x27, 0xd2, 0xb1, 0xa6, 0x84, 0x3e, 0xa2,
0x40, 0x4a, 0x16, 0xe2, 0x91, 0x1b, 0x91, 0x50, 0x92, 0xc9, 0xde, 0x93, 0x80, 0x32, 0x32, 0xe3,
0xfb, 0x12, 0xb4, 0xf7, 0xa6, 0xe3, 0x31, 0xdf, 0xe4, 0x69, 0x75, 0x89, 0xde, 0x10, 0xfb, 0x28,
0xa7, 0x7a, 0x7b, 0x89, 0x8a, 0xc4, 0xe6, 0x7e, 0x78, 0x6d, 0xb7, 0x0c, 0x4b, 0x8a, 0xa0, 0xa2,
0x2c, 0xb9, 0x0b, 0x88, 0x57, 0x2c, 0x2f, 0x27, 0xbf, 0x71, 0x06, 0x96, 0xb5, 0xf9, 0x82, 0xed,
0x75, 0x68, 0x8a, 0x17, 0x39, 0x61, 0xe7, 0xb3, 0x50, 0xa3, 0xc1, 0x62, 0xe8, 0x3a, 0xb2, 0x53,
0x3b, 0x1f, 0xf8, 0xce, 0x96, 0xeb, 0x84, 0x46, 0x1f, 0x9a, 0x26, 0x67, 0x2f, 0x68, 0xef, 0x40,
0x4b, 0xbc, 0xdf, 0x59, 0xda, 0x0b, 0x77, 0xd2, 0x56, 0xd4, 0x78, 0x9b, 0x4d, 0x4f, 0x1d, 0x1a,
0x5f, 0x43, 0xf7, 0x71, 0xe0, 0xd0, 0xfc, 0x47, 0xe5, 0x2a, 0xb7, 0x76, 0x07, 0xe4, 0x9f, 0x60,
0x45, 0xcc, 0xf5, 0x69, 0xcd, 0x50, 0x1d, 0x1a, 0xe7, 0x60, 0x3d, 0x97, 0xb9, 0xd8, 0x77, 0x00,
0xed, 0x04, 0xe1, 0xb8, 0xb2, 0x41, 0xcd, 0x1a, 0xcf, 0x25, 0xa5, 0xf1, 0xbc, 0x1a, 0x5f, 0xaa,
0x3c, 0x3c, 0x8b, 0x91, 0x92, 0xe7, 0x54, 0x8a, 0xf2, 0x9c, 0x59, 0x2d, 0xcf, 0x31, 0x3e, 0x8b,
0xb5, 0x27, 0x92, 0xcc, 0xf7, 0x58, 0xa6, 0xcb, 0xd7, 0x96, 0x91, 0xe0, 0x6c, 0xce, 0xe6, 0x38,
0x85, 0xa9, 0x10, 0x1b, 0x8b, 0xd0, 0xd4, 0x62, 0x82, 0xf1, 0x11, 0xb4, 0x52, 0x87, 0xfc, 0x46,
0x2a, 0x1b, 0xc8, 0xa8, 0x4d, 0xcf, 0x05, 0xae, 0xbf, 0x06, 0x35, 0xf9, 0xc3, 0x1a, 0x9a, 0x87,
0xca, 0xa3, 0xad, 0xbd, 0xf6, 0x0c, 0xfd, 0x78, 0xbc, 0xbd, 0xd7, 0x2e, 0x5d, 0xbf, 0x0d, 0x8b,
0xa9, 0xb7, 0x26, 0xb4, 0x04, 0xcd, 0x41, 0xaf, 0xbf, 0xfd, 0xf1, 0xc3, 0x2f, 0x2d, 0x73, 0xa7,
0xb7, 0xfd, 0x55, 0x7b, 0x06, 0xad, 0x40, 0x5b, 0x82, 0xfa, 0x0f, 0x1f, 0x71, 0x68, 0xe9, 0xfa,
0x33, 0x68, 0xe9, 0xe9, 0x2e, 0x3a, 0x03, 0x4b, 0x5b, 0x0f, 0xfb, 0x8f, 0x7a, 0xbb, 0xfd, 0x1d,
0xd3, 0xda, 0x32, 0x77, 0x7a, 0x8f, 0x76, 0xb6, 0xdb, 0x33, 0x3a, 0xd8, 0x7c, 0xdc, 0xef, 0xef,
0xf6, 0x3f, 0x6d, 0x97, 0x28, 0xd7, 0x04, 0xbc, 0xf3, 0xe5, 0x2e, 0x25, 0x2e, 0xeb, 0xc4, 0x8f,
0xfb, 0xf7, 0xfa, 0x0f, 0xff, 0xbf, 0xdf, 0xae, 0x6c, 0xfe, 0xb1, 0x01, 0x2d, 0xb9, 0x41, 0x1c,
0xb2, 0x0e, 0xe9, 0x5d, 0x98, 0x97, 0xff, 0x12, 0x26, 0x09, 0xb8, 0xfe, 0xe3, 0x63, 0xb7, 0x93,
0x45, 0x08, 0x47, 0x99, 0x41, 0x7b, 0xcc, 0x70, 0xca, 0xbb, 0xde, 0x39, 0x55, 0x95, 0x99, 0x87,
0xc3, 0xee, 0xf9, 0x22, 0x74, 0xcc, 0x71, 0x40, 0xad, 0xa5, 0xfe, 0x60, 0x81, 0x92, 0x39, 0xb9,
0x3f, 0x6e, 0x74, 0x2f, 0x14, 0xe2, 0x63, 0xa6, 0x5f, 0x41, 0x3b, 0xfd, 0x6b, 0x05, 0x4a, 0x3a,
0xdd, 0x05, 0xbf, 0x6d, 0x74, 0x2f, 0x1e, 0x43, 0xa1, 0xb2, 0xce, 0xfc, 0x84, 0xb0, 0x51, 0xfc,
0x8c, 0x9c, 0x61, 0x5d, 0xf4, 0x36, 0xcd, 0x55, 0xa1, 0xbf, 0xc7, 0x21, 0xf5, 0xe9, 0x3f, 0xe7,
0x5d, 0x56, 0x51, 0x45, 0xfe, 0x43, 0x9e, 0x31, 0x83, 0xbe, 0x80, 0xc5, 0x54, 0x73, 0x0c, 0x25,
0xb3, 0xf2, 0x5b, 0x7d, 0xdd, 0x8d, 0x62, 0x02, 0xdd, 0x6e, 0x6a, 0xeb, 0x4b, 0xb3, 0x5b, 0x4e,
0x3f, 0x4d, 0xb3, 0x5b, 0x6e, 0xcf, 0x8c, 0xb9, 0x97, 0xd6, 0xe0, 0x52, 0xdc, 0x2b, 0xaf, 0x9b,
0xd6, 0x3d, 0x5f, 0x84, 0x56, 0xb7, 0x9f, 0x6a, 0x6e, 0x29, 0xdb, 0xcf, 0xef, 0x99, 0x75, 0x37,
0x8a, 0x09, 0xd2, 0xb6, 0x4a, 0x8a, 0xf6, 0x94, 0xad, 0x32, 0x3d, 0xa2, 0x94, 0xad, 0xb2, 0xd5,
0xbe, 0xb0, 0x55, 0xaa, 0xfa, 0xbe, 0x50, 0x58, 0xb8, 0x64, 0x6d, 0x95, 0x5f, 0x0b, 0x19, 0x33,
0xa8, 0x07, 0x35, 0x59, 0x79, 0xa0, 0xe4, 0x74, 0xa7, 0xca, 0x9d, 0xee, 0xd9, 0x1c, 0x4c, 0xcc,
0xe2, 0x7f, 0x61, 0x96, 0x42, 0xd1, 0x8a, 0x46, 0x24, 0xa7, 0x9e, 0x49, 0x41, 0xe3, 0x69, 0xef,
0x43, 0x95, 0x27, 0xea, 0x28, 0x89, 0xb9, 0x5a, 0x55, 0xd0, 0x5d, 0xcb, 0xc0, 0xe3, 0xc9, 0x9f,
0xf1, 0xff, 0x8b, 0x45, 0xc6, 0x8d, 0xd6, 0xb5, 0xbf, 0xf6, 0xf4, 0xbc, 0xbe, 0xfb, 0x5a, 0x3e,
0x32, 0xe6, 0xf5, 0x04, 0x96, 0x73, 0xae, 0x40, 0x94, 0x34, 0x8a, 0x8a, 0x6f, 0xdf, 0xee, 0xa5,
0xe3, 0x89, 0xd4, 0xcd, 0x0a, 0xab, 0xad, 0xaa, 0xae, 0xae, 0x18, 0x6b, 0x2d, 0x03, 0x97, 0x93,
0x37, 0xff, 0x52, 0x86, 0x05, 0x9e, 0xa8, 0x88, 0x50, 0xfd, 0x29, 0x40, 0x92, 0x2e, 0xa3, 0xae,
0xe6, 0x3d, 0x5a, 0x89, 0xd0, 0x5d, 0xcf, 0xc5, 0xa9, 0x6a, 0x54, 0x32, 0x5f, 0x45, 0x8d, 0xd9,
0x7c, 0x5a, 0x51, 0x63, 0x4e, 0xb2, 0x6c, 0xcc, 0xa0, 0x6d, 0xa8, 0xc7, 0xe9, 0x18, 0x52, 0xb2,
0xb8, 0x54, 0x2e, 0xd9, 0xed, 0xe6, 0xa1, 0x54, 0x89, 0x94, 0xfc, 0x4b, 0x91, 0x28, 0x9b, 0xd5,
0x29, 0x12, 0xe5, 0xa5, 0x6c, 0x33, 0xff, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xb2, 0xd7, 0x78, 0x03,
0xcd, 0x2f, 0x00, 0x00,
// 3385 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x3a, 0x5f, 0x73, 0xdb, 0xc6,
0xf1, 0x22, 0x29, 0x51, 0xe4, 0x52, 0xa4, 0xa8, 0xb3, 0x2c, 0xd1, 0x54, 0x6c, 0xcb, 0x88, 0xed,
0xd8, 0x4e, 0xe2, 0x9f, 0xad, 0x5f, 0x1b, 0x37, 0x4e, 0xec, 0x84, 0x91, 0x94, 0x8c, 0x62, 0x9b,
0x56, 0x40, 0x3b, 0x4d, 0x9a, 0x07, 0x14, 0x26, 0x4e, 0x14, 0x6c, 0x12, 0x40, 0x80, 0xa3, 0x62,
0xf5, 0x13, 0xf4, 0xa1, 0x9d, 0xe9, 0x6b, 0xde, 0x3a, 0x9d, 0xce, 0x64, 0xda, 0xbe, 0x75, 0xa6,
0x33, 0x7d, 0xeb, 0x07, 0xe8, 0xf4, 0x03, 0xf4, 0x23, 0xf4, 0x5b, 0x74, 0xee, 0x1f, 0x70, 0x87,
0x3f, 0xb2, 0xe4, 0x64, 0x1a, 0xbf, 0xe1, 0x76, 0xf7, 0xf6, 0xf6, 0x76, 0xf7, 0xf6, 0x76, 0x17,
0x07, 0x75, 0x3b, 0x70, 0xaf, 0x07, 0xa1, 0x4f, 0x7c, 0x34, 0x1f, 0x4e, 0x3d, 0xe2, 0x4e, 0xb0,
0x71, 0x0d, 0x5a, 0x9f, 0xe3, 0x30, 0x72, 0x7d, 0xcf, 0xc4, 0x5f, 0x4f, 0x71, 0x44, 0x50, 0x07,
0xe6, 0x0f, 0x38, 0xa4, 0x53, 0x5a, 0x2f, 0x5d, 0xa9, 0x9b, 0x72, 0x68, 0x7c, 0x57, 0x82, 0xc5,
0x98, 0x38, 0x0a, 0x7c, 0x2f, 0xc2, 0xc5, 0xd4, 0xe8, 0x02, 0x2c, 0x88, 0x45, 0x2c, 0xcf, 0x9e,
0xe0, 0x4e, 0x99, 0xa1, 0x1b, 0x02, 0xd6, 0xb7, 0x27, 0x18, 0xbd, 0x01, 0x8b, 0x92, 0x44, 0x32,
0xa9, 0x30, 0xaa, 0x96, 0x00, 0x8b, 0xd5, 0xd0, 0x75, 0x38, 0x25, 0x09, 0xed, 0xc0, 0x8d, 0x89,
0x67, 0x19, 0xf1, 0x92, 0x40, 0xf5, 0x02, 0x57, 0xd0, 0x1b, 0x5f, 0x41, 0x7d, 0xab, 0x3f, 0xd8,
0xf4, 0xbd, 0x3d, 0x77, 0x44, 0x45, 0x8c, 0x70, 0x48, 0xe7, 0x74, 0x4a, 0xeb, 0x15, 0x2a, 0xa2,
0x18, 0xa2, 0x2e, 0xd4, 0x22, 0x6c, 0x87, 0xc3, 0x7d, 0x1c, 0x75, 0xca, 0x0c, 0x15, 0x8f, 0xe9,
0x2c, 0x3f, 0x20, 0xae, 0xef, 0x45, 0x9d, 0x0a, 0x9f, 0x25, 0x86, 0xc6, 0xb7, 0x25, 0x68, 0xec,
0xfa, 0x21, 0x79, 0x60, 0x07, 0x81, 0xeb, 0x8d, 0xd0, 0xdb, 0x50, 0x63, 0x4a, 0x1d, 0xfa, 0x63,
0xa6, 0x83, 0xd6, 0xc6, 0xd2, 0x75, 0x21, 0xd2, 0xf5, 0x5d, 0x81, 0x30, 0x63, 0x12, 0x74, 0x09,
0x5a, 0x43, 0xdf, 0x23, 0xb6, 0xeb, 0xe1, 0xd0, 0x0a, 0xfc, 0x90, 0x30, 0xcd, 0xcc, 0x99, 0xcd,
0x18, 0x4a, 0x99, 0xa3, 0x35, 0xa8, 0xef, 0xfb, 0x11, 0xe1, 0x14, 0x15, 0x46, 0x51, 0xa3, 0x00,
0x86, 0x5c, 0x85, 0x79, 0x86, 0x74, 0x03, 0xa1, 0x83, 0x2a, 0x1d, 0xee, 0x04, 0xc6, 0xef, 0x4a,
0x30, 0xf7, 0xc0, 0x9f, 0x7a, 0x24, 0xb5, 0x8c, 0x4d, 0xf6, 0x85, 0x7d, 0x94, 0x65, 0x6c, 0xb2,
0x9f, 0x2c, 0x43, 0x29, 0xb8, 0x89, 0xf8, 0x32, 0x14, 0xd9, 0x85, 0x5a, 0x88, 0x6d, 0xc7, 0xf7,
0xc6, 0x87, 0x4c, 0x84, 0x9a, 0x19, 0x8f, 0xa9, 0xed, 0x22, 0x3c, 0x76, 0xbd, 0xe9, 0x73, 0x2b,
0xc4, 0x63, 0xfb, 0x09, 0x1e, 0x33, 0x51, 0x6a, 0x66, 0x4b, 0x80, 0x4d, 0x0e, 0x35, 0x9e, 0xc2,
0x22, 0x35, 0x76, 0x14, 0xd8, 0x43, 0xfc, 0x90, 0xa9, 0x90, 0xba, 0x06, 0x5b, 0xd4, 0xc3, 0xe4,
0x1b, 0x3f, 0x7c, 0xc6, 0x24, 0xab, 0x99, 0x0d, 0x0a, 0xeb, 0x73, 0x10, 0x3a, 0x03, 0x35, 0x2e,
0x97, 0xeb, 0x30, 0xb1, 0x6a, 0x26, 0xdb, 0xf1, 0xae, 0xeb, 0xc4, 0x28, 0x37, 0x18, 0x0a, 0xa9,
0xe6, 0xf9, 0xee, 0x87, 0xc6, 0x3f, 0xca, 0xb0, 0x76, 0x9f, 0x2e, 0x3e, 0xb0, 0x3d, 0xe7, 0x89,
0xff, 0x7c, 0x80, 0x87, 0xd3, 0xd0, 0x25, 0x87, 0x9b, 0xbe, 0x47, 0xf0, 0x73, 0x82, 0xb6, 0x61,
0xc9, 0x93, 0xb2, 0x58, 0xd2, 0xbc, 0x74, 0xf5, 0xc6, 0x46, 0x27, 0xb6, 0x59, 0x4a, 0x5a, 0xb3,
0xed, 0xe9, 0x80, 0x08, 0x7d, 0x90, 0xec, 0x5d, 0x32, 0x29, 0x33, 0x26, 0x2b, 0x31, 0x93, 0xc1,
0x36, 0x93, 0x43, 0xb0, 0x90, 0x3a, 0x91, 0x0c, 0xce, 0x01, 0x3d, 0x07, 0x96, 0x1d, 0x59, 0xd3,
0x08, 0x87, 0x6c, 0x17, 0x15, 0xb3, 0x1e, 0x4e, 0xbd, 0x5e, 0xf4, 0x38, 0xc2, 0x21, 0x3b, 0x18,
0x42, 0xd1, 0x56, 0xe8, 0xfb, 0x64, 0x2f, 0x92, 0xca, 0x95, 0x60, 0x93, 0x41, 0xd1, 0xff, 0xc1,
0xa9, 0x68, 0x1a, 0x04, 0x63, 0x3c, 0xc1, 0x1e, 0xb1, 0xc7, 0xd6, 0x28, 0xf4, 0xa7, 0x41, 0xd4,
0x99, 0x5b, 0xaf, 0x5c, 0xa9, 0x98, 0x48, 0x45, 0x7d, 0xc2, 0x30, 0xe8, 0x1c, 0x40, 0x10, 0xba,
0x07, 0xee, 0x18, 0x8f, 0xb0, 0xd3, 0xa9, 0x32, 0xa6, 0x0a, 0xc4, 0xf8, 0x6d, 0x09, 0x4e, 0x33,
0xc9, 0x77, 0x7d, 0x47, 0x28, 0x51, 0x1c, 0xa3, 0xd7, 0xa1, 0x39, 0x64, 0xec, 0xad, 0xc0, 0x0e,
0xb1, 0x47, 0x84, 0x3f, 0x2d, 0x70, 0xe0, 0x2e, 0x83, 0xa1, 0x87, 0xd0, 0x8e, 0x84, 0xce, 0xad,
0x21, 0x57, 0xba, 0x50, 0xcd, 0xc5, 0x58, 0x35, 0x47, 0x18, 0xc8, 0x5c, 0x8c, 0x74, 0x80, 0x11,
0x02, 0x4a, 0x24, 0x79, 0x80, 0x89, 0xed, 0xd8, 0xc4, 0x46, 0x08, 0x66, 0x59, 0x4c, 0xe1, 0x22,
0xb0, 0x6f, 0xd4, 0x86, 0xca, 0x54, 0x38, 0x4b, 0xdd, 0xa4, 0x9f, 0xe8, 0x35, 0xa8, 0xc7, 0xa6,
0x13, 0x81, 0x25, 0x01, 0xd0, 0x03, 0x6e, 0x13, 0x82, 0x27, 0x01, 0x61, 0xba, 0x6d, 0x9a, 0x72,
0x68, 0xfc, 0x7d, 0x16, 0xda, 0x99, 0xed, 0xdf, 0x82, 0xda, 0x44, 0x2c, 0x2f, 0x3c, 0x66, 0x2d,
0x39, 0xe5, 0x19, 0x09, 0xcd, 0x98, 0x98, 0x1e, 0x22, 0xea, 0x9e, 0x4a, 0x0c, 0x8c, 0xc7, 0x54,
0xa7, 0x63, 0x7f, 0x64, 0x39, 0x6e, 0x88, 0x87, 0xc4, 0x0f, 0x0f, 0x85, 0x94, 0x0b, 0x63, 0x7f,
0xb4, 0x25, 0x61, 0xe8, 0x26, 0x80, 0xe3, 0x45, 0x54, 0x9d, 0x7b, 0xee, 0x88, 0xc9, 0xda, 0xd8,
0x40, 0xf1, 0xda, 0x71, 0x9c, 0x33, 0xeb, 0x8e, 0x17, 0x09, 0x61, 0xdf, 0x85, 0x26, 0x8d, 0x1b,
0xd6, 0x84, 0x87, 0x28, 0xee, 0x10, 0x8d, 0x8d, 0x65, 0x45, 0xe2, 0x38, 0x7e, 0x99, 0x0b, 0x41,
0x32, 0x88, 0xd0, 0x1d, 0xa8, 0xb2, 0x73, 0x1b, 0x75, 0xaa, 0x6c, 0xce, 0xa5, 0x9c, 0x5d, 0xf2,
0x55, 0xae, 0xdf, 0x67, 0x74, 0xdb, 0x1e, 0x09, 0x0f, 0x4d, 0x31, 0x09, 0xdd, 0x87, 0x86, 0xed,
0x79, 0x3e, 0xb1, 0xf9, 0xb1, 0x98, 0x67, 0x3c, 0xae, 0x15, 0xf3, 0xe8, 0x25, 0xc4, 0x9c, 0x91,
0x3a, 0x1d, 0xfd, 0x04, 0xe6, 0xd8, 0xb9, 0xe9, 0xd4, 0xd8, 0xae, 0xcf, 0xe9, 0x3e, 0x94, 0x66,
0x66, 0x72, 0xe2, 0xee, 0xbb, 0xd0, 0x50, 0x44, 0xa3, 0x8e, 0xf1, 0x0c, 0x1f, 0x0a, 0x5f, 0xa1,
0x9f, 0x68, 0x19, 0xe6, 0x0e, 0xec, 0xf1, 0x54, 0xda, 0x83, 0x0f, 0x6e, 0x97, 0x7f, 0x56, 0xea,
0xde, 0x85, 0x76, 0x5a, 0xa2, 0x93, 0xcc, 0x37, 0x76, 0x60, 0xd9, 0x9c, 0x7a, 0x89, 0x60, 0xf2,
0x52, 0xbd, 0x09, 0x55, 0x61, 0x3f, 0xee, 0x3b, 0x67, 0x0a, 0x35, 0x62, 0x0a, 0x42, 0xe3, 0x0e,
0x9c, 0x4e, 0xb1, 0x12, 0x57, 0xee, 0x45, 0x68, 0x05, 0xbe, 0x63, 0x45, 0x1c, 0x6c, 0xb9, 0x8e,
0x3c, 0x89, 0x41, 0x4c, 0xbb, 0xe3, 0xd0, 0xe9, 0x03, 0xe2, 0x07, 0x59, 0x51, 0x8e, 0x37, 0xbd,
0x03, 0x2b, 0xe9, 0xe9, 0x7c, 0x79, 0xe3, 0x03, 0x58, 0x35, 0xf1, 0xc4, 0x3f, 0xc0, 0x2f, 0xcb,
0xba, 0x0b, 0x9d, 0x2c, 0x83, 0x84, 0x79, 0x02, 0x1d, 0x10, 0x9b, 0x4c, 0xa3, 0x93, 0x31, 0xbf,
0xaa, 0x32, 0x10, 0x97, 0x09, 0xe7, 0x83, 0x5a, 0x50, 0x76, 0x03, 0x31, 0xa9, 0xec, 0x06, 0xc6,
0x97, 0x50, 0xef, 0xab, 0xd1, 0x40, 0xbd, 0x8d, 0xea, 0xa6, 0x1c, 0xa2, 0x8d, 0x24, 0x11, 0x28,
0xbf, 0xe0, 0xa6, 0x88, 0x53, 0x84, 0x7b, 0x99, 0x20, 0x2a, 0x64, 0xd8, 0x00, 0x88, 0x23, 0x90,
0xbc, 0x79, 0x50, 0x96, 0x9f, 0xa9, 0x50, 0x19, 0x7f, 0xd4, 0xc2, 0x91, 0xb2, 0x19, 0x27, 0xde,
0x8c, 0xa3, 0x85, 0xa7, 0xf2, 0x49, 0xc2, 0xd3, 0x75, 0x98, 0x8b, 0x88, 0x4d, 0x78, 0x80, 0x6c,
0x29, 0x9b, 0xd3, 0x97, 0xc4, 0x26, 0x27, 0x43, 0x67, 0x01, 0x86, 0x21, 0xb6, 0x09, 0x76, 0x2c,
0x9b, 0x47, 0xce, 0x8a, 0x59, 0x17, 0x90, 0x1e, 0x41, 0xb7, 0x13, 0x3d, 0xce, 0x31, 0x31, 0xd6,
0x73, 0x18, 0x6a, 0x76, 0x49, 0x34, 0x1d, 0x9f, 0xf6, 0xea, 0xd1, 0xa7, 0x5d, 0xcc, 0xe3, 0xc4,
0x4a, 0xc0, 0x9a, 0x2f, 0x0c, 0x58, 0x7c, 0xc6, 0x71, 0x02, 0x56, 0xad, 0x30, 0x60, 0x09, 0x1e,
0x47, 0x06, 0xac, 0x1f, 0x33, 0xf4, 0x3c, 0x80, 0x4e, 0xf6, 0xe8, 0x88, 0x90, 0x71, 0x13, 0xaa,
0x11, 0x83, 0x1c, 0x11, 0x7e, 0xc4, 0x14, 0x41, 0x68, 0xfc, 0xa7, 0xa4, 0x7a, 0xdd, 0xc7, 0xee,
0x98, 0xe0, 0x30, 0xe3, 0x75, 0xb1, 0xf3, 0x94, 0x8f, 0xe7, 0x3c, 0x03, 0x68, 0x31, 0xb5, 0x5b,
0x11, 0x1e, 0xb3, 0xdb, 0x8d, 0xe5, 0xd6, 0x8d, 0x8d, 0xb7, 0x72, 0x26, 0xf2, 0x25, 0xb9, 0xcd,
0x06, 0x82, 0x9c, 0x6b, 0xbc, 0x39, 0x56, 0x61, 0xdd, 0x0f, 0x01, 0x65, 0x89, 0x4e, 0xa4, 0xba,
0x4f, 0xe9, 0x71, 0xa5, 0xa9, 0x75, 0x4e, 0xd8, 0xde, 0x63, 0x62, 0x1c, 0xa1, 0x37, 0x2e, 0xa7,
0x29, 0x08, 0x8d, 0xdf, 0x57, 0x00, 0x12, 0xe4, 0x2b, 0x7b, 0x4e, 0x6f, 0xc5, 0xa7, 0x86, 0xa7,
0x06, 0xe7, 0x73, 0xf8, 0xe5, 0x9e, 0x97, 0x8f, 0xf5, 0xf3, 0xc2, 0x93, 0x84, 0x8b, 0x79, 0xb3,
0x5f, 0xd9, 0x93, 0xb2, 0x09, 0x2b, 0x69, 0x73, 0x8b, 0x73, 0x72, 0x15, 0xe6, 0x5c, 0x82, 0x27,
0xbc, 0x50, 0x6c, 0x6c, 0x9c, 0xca, 0xd9, 0x96, 0xc9, 0x29, 0x8c, 0x0b, 0x50, 0xdf, 0x99, 0xd8,
0x23, 0x3c, 0x08, 0xf0, 0x90, 0xae, 0xe5, 0xd2, 0x81, 0x58, 0x9f, 0x0f, 0x8c, 0x0d, 0xa8, 0xdd,
0xc3, 0x87, 0x9f, 0xd3, 0x75, 0x8f, 0x2b, 0x9f, 0xf1, 0xcf, 0x12, 0xac, 0xb2, 0x70, 0xb7, 0x29,
0xcb, 0x34, 0x13, 0x47, 0xfe, 0x34, 0x1c, 0xe2, 0x88, 0x99, 0x34, 0x98, 0x5a, 0x01, 0x0e, 0x5d,
0x9f, 0xfb, 0x14, 0x35, 0x69, 0x30, 0xdd, 0x65, 0x00, 0x5a, 0xca, 0x51, 0xf4, 0xd7, 0x53, 0x5f,
0xf8, 0x56, 0xc5, 0xac, 0x0d, 0x83, 0xe9, 0x67, 0x74, 0x2c, 0xe7, 0x46, 0xfb, 0x76, 0x88, 0x23,
0x59, 0x70, 0x0c, 0x83, 0xe9, 0x80, 0x01, 0xd0, 0x4d, 0x38, 0x3d, 0xc1, 0x13, 0x3f, 0x3c, 0xb4,
0xc6, 0xee, 0xc4, 0x25, 0x96, 0xeb, 0x59, 0x4f, 0x0e, 0x09, 0x8e, 0x84, 0xe3, 0x20, 0x8e, 0xbc,
0x4f, 0x71, 0x3b, 0xde, 0x47, 0x14, 0x83, 0x0c, 0x68, 0xfa, 0xfe, 0xc4, 0x8a, 0x86, 0x7e, 0x88,
0x2d, 0xdb, 0x79, 0xca, 0xe2, 0x7d, 0xc5, 0x6c, 0xf8, 0xfe, 0x64, 0x40, 0x61, 0x3d, 0xe7, 0xa9,
0x61, 0x43, 0x53, 0x2b, 0x84, 0x68, 0xe2, 0xce, 0x2a, 0x1e, 0x91, 0xb8, 0xd3, 0x6f, 0x0a, 0x0b,
0xfd, 0xb1, 0xd4, 0x03, 0xfb, 0xa6, 0x30, 0x72, 0x18, 0xc8, 0xac, 0x9d, 0x7d, 0x53, 0x85, 0x8d,
0xf1, 0x81, 0xa8, 0x33, 0xeb, 0x26, 0x1f, 0x18, 0x0e, 0xc0, 0xa6, 0x1d, 0xd8, 0x4f, 0xdc, 0xb1,
0x4b, 0x0e, 0xd1, 0x55, 0x68, 0xdb, 0x8e, 0x63, 0x0d, 0x25, 0xc4, 0xc5, 0xb2, 0xe8, 0x5f, 0xb4,
0x1d, 0x67, 0x53, 0x01, 0xa3, 0x37, 0x61, 0xc9, 0x09, 0xfd, 0x40, 0xa7, 0xe5, 0x5d, 0x80, 0x36,
0x45, 0xa8, 0xc4, 0xc6, 0x1f, 0x2a, 0x70, 0x56, 0x37, 0x4b, 0xba, 0xb4, 0xbc, 0x05, 0x0b, 0xa9,
0x55, 0x4b, 0x9a, 0x07, 0x25, 0x42, 0x9a, 0x1a, 0x61, 0xaa, 0x22, 0x2b, 0xa7, 0x2b, 0xb2, 0xfc,
0x9a, 0xb5, 0xf2, 0x43, 0xd4, 0xac, 0xb3, 0xdf, 0xa7, 0x66, 0x9d, 0x4b, 0xd7, 0xac, 0x97, 0x59,
0x33, 0x47, 0xe2, 0x59, 0xb9, 0x53, 0xe5, 0x1d, 0x87, 0x98, 0xc6, 0x93, 0x4d, 0x9f, 0x54, 0x6d,
0x3b, 0x7f, 0x92, 0xda, 0xb6, 0x56, 0x54, 0xdb, 0x1a, 0x7f, 0x2a, 0xc1, 0xb2, 0x6e, 0x24, 0x51,
0x0e, 0xdd, 0x85, 0x7a, 0x28, 0x4f, 0x91, 0x30, 0xcc, 0xba, 0x9e, 0x5c, 0x64, 0x4f, 0x9b, 0x99,
0x4c, 0x41, 0x9f, 0x15, 0x56, 0xb5, 0x97, 0x0b, 0xd8, 0xbc, 0xb0, 0xae, 0xed, 0xc1, 0x52, 0x4c,
0x7c, 0x64, 0x59, 0xab, 0x94, 0xa9, 0x65, 0xbd, 0x4c, 0xf5, 0xa0, 0xba, 0x85, 0x0f, 0xdc, 0x21,
0xfe, 0x41, 0x7a, 0x3d, 0xeb, 0xd0, 0x08, 0x70, 0x38, 0x71, 0xa3, 0x28, 0x76, 0xb0, 0xba, 0xa9,
0x82, 0x8c, 0x7f, 0xcf, 0xc1, 0x62, 0x5a, 0xb3, 0xef, 0x64, 0xaa, 0xe2, 0x6e, 0xe2, 0xf1, 0xe9,
0xfd, 0x29, 0xb7, 0xd9, 0x15, 0x19, 0x30, 0xcb, 0xa9, 0x14, 0x38, 0x8e, 0xa9, 0x22, 0x88, 0xd2,
0xfd, 0x0f, 0xfd, 0xc9, 0xc4, 0xf6, 0x1c, 0xd9, 0x87, 0x13, 0x43, 0xaa, 0x2d, 0x3b, 0x1c, 0x51,
0x37, 0xa6, 0x60, 0xf6, 0x8d, 0xce, 0x43, 0x83, 0xa6, 0x92, 0xae, 0xc7, 0x8a, 0x6a, 0xe6, 0xa4,
0x75, 0x13, 0x04, 0x68, 0xcb, 0x0d, 0xd1, 0x25, 0x98, 0xc5, 0xde, 0x81, 0xbc, 0xb7, 0x92, 0x46,
0x9d, 0x0c, 0xd4, 0x26, 0x43, 0xa3, 0xcb, 0x50, 0x9d, 0xf8, 0x53, 0x8f, 0xc8, 0xa4, 0xb2, 0x15,
0x13, 0xb2, 0xee, 0x9a, 0x29, 0xb0, 0xe8, 0x2a, 0xcc, 0x3b, 0xcc, 0x06, 0x32, 0x73, 0x5c, 0x4c,
0x0a, 0x73, 0x06, 0x37, 0x25, 0x1e, 0xbd, 0x1f, 0xdf, 0xb8, 0xf5, 0xd4, 0x9d, 0x99, 0x52, 0x6a,
0xee, 0xb5, 0x7b, 0x4f, 0xbf, 0x76, 0x81, 0xb1, 0xb8, 0x5a, 0xc8, 0xe2, 0xe8, 0xb2, 0xfa, 0x0c,
0xd4, 0xc6, 0xfe, 0x88, 0xfb, 0x41, 0x83, 0x57, 0x3b, 0x63, 0x7f, 0xc4, 0xdc, 0x60, 0x99, 0xa6,
0x19, 0x8e, 0xeb, 0x75, 0x16, 0xd8, 0x99, 0xe4, 0x03, 0x7a, 0x7b, 0xb0, 0x0f, 0xcb, 0xf7, 0x86,
0xb8, 0xd3, 0x64, 0xa8, 0x3a, 0x83, 0x3c, 0xf4, 0x86, 0xec, 0x72, 0x23, 0xe4, 0xb0, 0xd3, 0x62,
0x70, 0xfa, 0x89, 0xfe, 0x5f, 0xa6, 0xf2, 0x8b, 0xcc, 0xbe, 0x67, 0x0b, 0x8e, 0xc9, 0x2b, 0x53,
0xb7, 0xff, 0xb5, 0x04, 0x2b, 0x9b, 0x2c, 0x39, 0x52, 0x22, 0xc1, 0x09, 0xea, 0x4e, 0x74, 0x23,
0x2e, 0xf0, 0xd3, 0x45, 0x62, 0x7a, 0xb3, 0x82, 0x0e, 0x7d, 0x08, 0x2d, 0xc9, 0x53, 0xcc, 0xac,
0xbc, 0xa8, 0x35, 0xd0, 0x8c, 0xd4, 0xa1, 0xf1, 0x3e, 0xac, 0x66, 0x64, 0x16, 0x89, 0xcc, 0x05,
0x58, 0x48, 0x22, 0x42, 0x2c, 0x72, 0x23, 0x86, 0xed, 0x38, 0xc6, 0x6d, 0x38, 0x3d, 0x20, 0x76,
0x48, 0x32, 0x1b, 0x3e, 0xc6, 0x5c, 0xd6, 0x1d, 0xd0, 0xe7, 0x8a, 0x02, 0x7e, 0x00, 0xcb, 0x03,
0xe2, 0x07, 0x2f, 0xc1, 0x94, 0x9e, 0x74, 0xba, 0x6d, 0x7f, 0x4a, 0x44, 0xf6, 0x22, 0x87, 0xc6,
0x2a, 0xef, 0x65, 0x64, 0x57, 0x7b, 0x0f, 0x56, 0x78, 0x2b, 0xe1, 0x65, 0x36, 0x71, 0x46, 0x36,
0x32, 0xb2, 0x7c, 0x7f, 0x53, 0x56, 0x42, 0x5d, 0x41, 0xed, 0xf3, 0xb6, 0x5e, 0xfb, 0xac, 0x66,
0x0d, 0xae, 0xe5, 0xe3, 0x59, 0x37, 0xaa, 0xe4, 0xb8, 0x91, 0x99, 0x29, 0x90, 0x66, 0xd9, 0x49,
0x7f, 0x33, 0xcb, 0xfd, 0x7f, 0x58, 0x1f, 0xed, 0xf0, 0xfa, 0x28, 0x5e, 0x3a, 0xee, 0xc9, 0xdc,
0x48, 0xd5, 0x47, 0x9d, 0x22, 0x31, 0xe3, 0xf2, 0xe8, 0xd7, 0xb3, 0x50, 0x8f, 0x71, 0x19, 0x9d,
0x66, 0x95, 0x54, 0xce, 0x51, 0x92, 0x7a, 0xe9, 0x54, 0x5e, 0xe6, 0xd2, 0x99, 0x7d, 0xd1, 0xa5,
0xb3, 0x06, 0x75, 0xf6, 0x61, 0x85, 0x78, 0x4f, 0x5c, 0x22, 0x35, 0x06, 0x30, 0xf1, 0x5e, 0x62,
0xf8, 0xea, 0xb1, 0x0c, 0xaf, 0x17, 0x62, 0xf3, 0xe9, 0x42, 0xec, 0x9d, 0xf8, 0x5a, 0xe0, 0x17,
0xc8, 0xb9, 0x2c, 0xbb, 0xdc, 0x0b, 0x61, 0x5b, 0xbf, 0x10, 0xf8, 0x9d, 0xf2, 0x7a, 0xce, 0xe4,
0x57, 0xb6, 0x0c, 0xbb, 0xcf, 0xcb, 0x30, 0xd5, 0xab, 0x44, 0xf4, 0xda, 0x00, 0x88, 0x0f, 0xaa,
0xac, 0xc5, 0x50, 0x76, 0x6b, 0xa6, 0x42, 0x45, 0x43, 0x81, 0xa6, 0xff, 0xa4, 0x71, 0x78, 0x8c,
0x50, 0xf0, 0x17, 0x35, 0xb5, 0x29, 0xe8, 0xb0, 0xbd, 0x93, 0xa9, 0xdc, 0x8f, 0xe7, 0x75, 0x6f,
0xeb, 0x85, 0xfb, 0xc9, 0xdc, 0x25, 0x53, 0xb7, 0xb3, 0x9b, 0xd8, 0x0e, 0x05, 0x5a, 0x24, 0xe1,
0x02, 0xd2, 0x23, 0x34, 0xff, 0xd9, 0x73, 0x3d, 0x37, 0xda, 0xe7, 0xf8, 0x2a, 0xc3, 0x83, 0x04,
0xf5, 0xd8, 0x6f, 0x45, 0xfc, 0xdc, 0x25, 0xd6, 0xd0, 0x77, 0x30, 0x73, 0xc6, 0x39, 0xb3, 0x46,
0x01, 0x9b, 0xbe, 0x83, 0x93, 0x03, 0x52, 0x3b, 0xd1, 0x01, 0xa9, 0xa7, 0x0e, 0xc8, 0x0a, 0x54,
0x43, 0x6c, 0x47, 0xbe, 0xd7, 0x01, 0xfe, 0x73, 0x92, 0x8f, 0x68, 0x80, 0x9f, 0xe0, 0x28, 0xa2,
0x0b, 0x88, 0xac, 0x43, 0x0c, 0x95, 0xdc, 0x68, 0xa1, 0x28, 0x37, 0x3a, 0xa2, 0x85, 0x97, 0xca,
0x8d, 0x9a, 0x45, 0xb9, 0xd1, 0x71, 0x3a, 0x78, 0x4a, 0xe6, 0xd7, 0x3a, 0x2a, 0xf3, 0xfb, 0x31,
0x0f, 0xce, 0x3d, 0x58, 0xcd, 0xb8, 0xba, 0x38, 0x39, 0x37, 0x52, 0x8d, 0xbe, 0x4e, 0x91, 0x16,
0xe2, 0x3e, 0xdf, 0x2f, 0x61, 0x71, 0xfb, 0x39, 0x1e, 0x0e, 0x0e, 0xbd, 0xe1, 0x09, 0xee, 0xea,
0x36, 0x54, 0x86, 0x13, 0x47, 0x94, 0xcb, 0xf4, 0x53, 0xbd, 0xbd, 0x2b, 0xfa, 0xed, 0x6d, 0x41,
0x3b, 0x59, 0x41, 0xc8, 0xb9, 0x42, 0xe5, 0x74, 0x28, 0x31, 0x65, 0xbe, 0x60, 0x8a, 0x91, 0x80,
0xe3, 0x30, 0x64, 0xbb, 0xe6, 0x70, 0x1c, 0x86, 0xba, 0xdb, 0x56, 0x74, 0xb7, 0x35, 0x9e, 0x42,
0x83, 0x2e, 0xf0, 0xbd, 0xc4, 0x17, 0x29, 0x6c, 0x25, 0x49, 0x61, 0xe3, 0x4c, 0x78, 0x56, 0xc9,
0x84, 0x8d, 0x75, 0x58, 0xe0, 0x6b, 0x89, 0x8d, 0xb4, 0xa1, 0x32, 0x0d, 0xc7, 0xd2, 0x6e, 0xd3,
0x70, 0x6c, 0xfc, 0x02, 0x9a, 0x3d, 0x42, 0xec, 0xe1, 0xfe, 0x09, 0xe4, 0x89, 0xd7, 0x2a, 0xab,
0x59, 0x77, 0x46, 0x26, 0xc3, 0x80, 0x96, 0xe4, 0x5d, 0xb8, 0x7e, 0x1f, 0xd0, 0xae, 0x1f, 0x92,
0x8f, 0xfd, 0xf0, 0x1b, 0x3b, 0x74, 0x4e, 0x96, 0xc5, 0x22, 0x98, 0x15, 0x2f, 0x12, 0x2a, 0x57,
0xe6, 0x4c, 0xf6, 0x6d, 0xbc, 0x01, 0xa7, 0x34, 0x7e, 0x85, 0x0b, 0xdf, 0x82, 0x06, 0x8b, 0x13,
0x22, 0x5f, 0xba, 0xa2, 0xf6, 0xc4, 0x8e, 0x0a, 0x26, 0xb4, 0x16, 0xa6, 0x17, 0x01, 0x83, 0xc7,
0x51, 0xfb, 0xad, 0x54, 0x6a, 0xb1, 0xac, 0xcf, 0x4f, 0xa5, 0x15, 0xdf, 0x96, 0x60, 0x8e, 0xc1,
0x33, 0x61, 0x7b, 0x8d, 0xd6, 0xfe, 0x81, 0x6f, 0x11, 0x7b, 0x14, 0x3f, 0xf2, 0xa0, 0x80, 0x47,
0xf6, 0x28, 0x62, 0x6f, 0x54, 0x28, 0xd2, 0x71, 0x47, 0x38, 0x22, 0xf2, 0xa5, 0x47, 0x83, 0xc2,
0xb6, 0x38, 0x88, 0xaa, 0x24, 0x72, 0x7f, 0xc5, 0x73, 0x86, 0x59, 0x93, 0x7d, 0xcb, 0x5f, 0xcd,
0x3c, 0xfa, 0xb2, 0x5f, 0xcd, 0x5d, 0xa8, 0xa5, 0xba, 0x1e, 0xf1, 0xd8, 0x78, 0x1f, 0x90, 0xba,
0x3d, 0xa1, 0xbf, 0xcb, 0x50, 0x65, 0xbb, 0x97, 0xf7, 0x5b, 0x4b, 0xdf, 0x9f, 0x29, 0xb0, 0xc6,
0x5d, 0x40, 0x5c, 0x61, 0xda, 0x9d, 0x76, 0x7c, 0xe5, 0xbe, 0x07, 0xa7, 0xb4, 0xf9, 0xf1, 0x4f,
0x44, 0x8d, 0x41, 0x7a, 0x75, 0x31, 0xf9, 0x5f, 0x25, 0x80, 0xde, 0x94, 0xec, 0x8b, 0x6a, 0x5f,
0xdd, 0x65, 0x49, 0xdf, 0x25, 0xc5, 0x05, 0x76, 0x14, 0x7d, 0xe3, 0x87, 0x32, 0x69, 0x8b, 0xc7,
0xac, 0x52, 0x9f, 0x92, 0x7d, 0xd9, 0xcd, 0xa3, 0xdf, 0xe8, 0x12, 0xb4, 0xf8, 0x33, 0x1c, 0xcb,
0x76, 0x9c, 0x10, 0x47, 0x91, 0x68, 0xeb, 0x35, 0x39, 0xb4, 0xc7, 0x81, 0x94, 0xcc, 0x75, 0xb0,
0x47, 0x5c, 0x72, 0x68, 0x11, 0xff, 0x19, 0xf6, 0x44, 0x3a, 0xd6, 0x94, 0xd0, 0x47, 0x14, 0x48,
0xc9, 0x42, 0x3c, 0x72, 0x23, 0x12, 0x4a, 0x32, 0xd9, 0x7b, 0x12, 0x50, 0x46, 0x66, 0x7c, 0x57,
0x82, 0xf6, 0xee, 0x74, 0x3c, 0xe6, 0x9b, 0x3c, 0xa9, 0x2e, 0xd1, 0x1b, 0x62, 0x1f, 0xe5, 0x54,
0x6f, 0x2f, 0x51, 0x91, 0xd8, 0xdc, 0xf7, 0xaf, 0xed, 0x6e, 0xc0, 0x92, 0x22, 0xa8, 0x30, 0x9a,
0x76, 0xeb, 0x96, 0xf4, 0x5b, 0x97, 0x3a, 0x0a, 0x2f, 0x67, 0x5e, 0x6e, 0x73, 0xc6, 0x69, 0x38,
0xa5, 0xcd, 0x17, 0xa5, 0xd0, 0x35, 0x68, 0x8a, 0xdf, 0x75, 0xc2, 0x09, 0xce, 0x40, 0x8d, 0x46,
0x92, 0xa1, 0xeb, 0xc8, 0x36, 0xee, 0x7c, 0xe0, 0x3b, 0x9b, 0xae, 0x13, 0x1a, 0x7d, 0x68, 0x9a,
0x9c, 0xbd, 0xa0, 0xbd, 0x03, 0x2d, 0xf1, 0x73, 0xcf, 0xd2, 0x7e, 0x7f, 0x27, 0x3d, 0x47, 0x8d,
0xb7, 0xd9, 0xf4, 0xd4, 0xa1, 0xf1, 0x15, 0x74, 0x1f, 0x07, 0x0e, 0x4d, 0x8e, 0x54, 0xae, 0x72,
0x6b, 0x77, 0x40, 0x3e, 0x13, 0x2b, 0x62, 0xae, 0x4f, 0x6b, 0x86, 0xea, 0xd0, 0x38, 0x0b, 0x6b,
0xb9, 0xcc, 0xc5, 0xbe, 0x03, 0x68, 0x27, 0x08, 0xc7, 0x95, 0xdd, 0x6b, 0xd6, 0x95, 0x2e, 0x29,
0x5d, 0xe9, 0x95, 0xf8, 0xc6, 0xe5, 0xb1, 0x5b, 0x8c, 0x94, 0x24, 0xa8, 0x52, 0x94, 0x04, 0xcd,
0x6a, 0x49, 0x90, 0xf1, 0x69, 0xac, 0x3d, 0x91, 0x81, 0xbe, 0xcb, 0xd2, 0x60, 0xbe, 0xb6, 0x0c,
0x13, 0x67, 0x72, 0x36, 0xc7, 0x29, 0x4c, 0x85, 0xd8, 0x58, 0x84, 0xa6, 0x16, 0x30, 0x8c, 0x0f,
0xa1, 0x95, 0x8a, 0x00, 0xd7, 0x53, 0xa9, 0x42, 0x46, 0x6d, 0x7a, 0xa2, 0x70, 0xed, 0x35, 0xa8,
0xc9, 0xd7, 0x6c, 0x68, 0x1e, 0x2a, 0x8f, 0x36, 0x77, 0xdb, 0x33, 0xf4, 0xe3, 0xf1, 0xd6, 0x6e,
0xbb, 0x74, 0xed, 0x36, 0x2c, 0xa6, 0x7e, 0x44, 0xa1, 0x25, 0x68, 0x0e, 0x7a, 0xfd, 0xad, 0x8f,
0x1e, 0x7e, 0x61, 0x99, 0xdb, 0xbd, 0xad, 0x2f, 0xdb, 0x33, 0x68, 0x19, 0xda, 0x12, 0xd4, 0x7f,
0xf8, 0x88, 0x43, 0x4b, 0xd7, 0x9e, 0x41, 0x4b, 0xcf, 0x85, 0xd1, 0x69, 0x58, 0xda, 0x7c, 0xd8,
0x7f, 0xd4, 0xdb, 0xe9, 0x6f, 0x9b, 0xd6, 0xa6, 0xb9, 0xdd, 0x7b, 0xb4, 0xbd, 0xd5, 0x9e, 0xd1,
0xc1, 0xe6, 0xe3, 0x7e, 0x7f, 0xa7, 0xff, 0x49, 0xbb, 0x44, 0xb9, 0x26, 0xe0, 0xed, 0x2f, 0x76,
0x28, 0x71, 0x59, 0x27, 0x7e, 0xdc, 0xbf, 0xd7, 0x7f, 0xf8, 0xf3, 0x7e, 0xbb, 0xb2, 0xf1, 0xe7,
0x06, 0xb4, 0xe4, 0x06, 0x71, 0xc8, 0xda, 0xa7, 0x77, 0x61, 0x5e, 0x3e, 0x34, 0x4c, 0xb2, 0x73,
0xfd, 0x55, 0x64, 0xb7, 0x93, 0x45, 0x08, 0x47, 0x99, 0x41, 0xbb, 0xcc, 0x70, 0xca, 0x4f, 0xbf,
0xb3, 0xaa, 0x2a, 0x33, 0x7f, 0x15, 0xbb, 0xe7, 0x8a, 0xd0, 0x31, 0xc7, 0x01, 0xb5, 0x96, 0xfa,
0xfa, 0x02, 0x25, 0x73, 0x72, 0x5f, 0x75, 0x74, 0xcf, 0x17, 0xe2, 0x63, 0xa6, 0x5f, 0x42, 0x3b,
0xfd, 0xee, 0x02, 0x25, 0x6d, 0xf0, 0x82, 0x37, 0x1d, 0xdd, 0x0b, 0x47, 0x50, 0xa8, 0xac, 0x33,
0x2f, 0x14, 0xd6, 0x8b, 0xff, 0x31, 0x67, 0x58, 0x17, 0xfd, 0xb8, 0xe6, 0xaa, 0xd0, 0x7f, 0xd6,
0x21, 0xf5, 0x5d, 0x40, 0xce, 0x4f, 0x5b, 0x45, 0x15, 0xf9, 0x7f, 0xf9, 0x8c, 0x19, 0xf4, 0x39,
0x2c, 0xa6, 0x3a, 0x67, 0x28, 0x99, 0x95, 0xdf, 0x07, 0xec, 0xae, 0x17, 0x13, 0xe8, 0x76, 0x53,
0xfb, 0x62, 0x9a, 0xdd, 0x72, 0x9a, 0x6d, 0x9a, 0xdd, 0x72, 0x1b, 0x6a, 0xcc, 0xbd, 0xb4, 0xee,
0x97, 0xe2, 0x5e, 0x79, 0xad, 0xb6, 0xee, 0xb9, 0x22, 0xb4, 0xba, 0xfd, 0x54, 0xe7, 0x4b, 0xd9,
0x7e, 0x7e, 0x43, 0xad, 0xbb, 0x5e, 0x4c, 0x90, 0xb6, 0x55, 0x52, 0xd1, 0xa7, 0x6c, 0x95, 0x69,
0x20, 0xa5, 0x6c, 0x95, 0x6d, 0x05, 0x08, 0x5b, 0xa5, 0x4a, 0xf3, 0xf3, 0x85, 0x55, 0x4d, 0xd6,
0x56, 0xf9, 0x85, 0x92, 0x31, 0x83, 0x7a, 0x50, 0x93, 0x65, 0x09, 0x4a, 0x4e, 0x77, 0xaa, 0x16,
0xea, 0x9e, 0xc9, 0xc1, 0xc4, 0x2c, 0x7e, 0x0a, 0xb3, 0x14, 0x8a, 0x96, 0x35, 0x22, 0x39, 0xf5,
0x74, 0x0a, 0x1a, 0x4f, 0x7b, 0x0f, 0xaa, 0x3c, 0x8b, 0x47, 0x49, 0xcc, 0xd5, 0x4a, 0x86, 0xee,
0x6a, 0x06, 0x1e, 0x4f, 0xfe, 0x94, 0x3f, 0x3e, 0x16, 0xe9, 0x38, 0x5a, 0xd3, 0x9e, 0xf4, 0xe9,
0x49, 0x7f, 0xf7, 0xb5, 0x7c, 0x64, 0xcc, 0xeb, 0x09, 0x9c, 0xca, 0xb9, 0x02, 0x51, 0xd2, 0x45,
0x2a, 0xbe, 0x7d, 0xbb, 0x17, 0x8f, 0x26, 0x52, 0x37, 0x2b, 0xac, 0xb6, 0xa2, 0xba, 0xba, 0x62,
0xac, 0xd5, 0x0c, 0x5c, 0x4e, 0xde, 0xf8, 0x5b, 0x19, 0x16, 0x78, 0xa2, 0x22, 0x42, 0xf5, 0x27,
0x00, 0x49, 0x2e, 0x8d, 0xba, 0x9a, 0xf7, 0x68, 0xf5, 0x43, 0x77, 0x2d, 0x17, 0xa7, 0xaa, 0x51,
0x49, 0x8b, 0x15, 0x35, 0x66, 0x93, 0x6d, 0x45, 0x8d, 0x39, 0x99, 0xb4, 0x31, 0x83, 0xb6, 0xa0,
0x1e, 0xe7, 0x6a, 0x48, 0x49, 0xf1, 0x52, 0x89, 0x66, 0xb7, 0x9b, 0x87, 0x52, 0x25, 0x52, 0xf2,
0x2f, 0x45, 0xa2, 0x6c, 0x56, 0xa7, 0x48, 0x94, 0x97, 0xb2, 0xcd, 0xfc, 0x37, 0x00, 0x00, 0xff,
0xff, 0xf6, 0x41, 0x28, 0x8c, 0xea, 0x2f, 0x00, 0x00,
}

View File

@ -421,9 +421,8 @@ message ListPodSandboxResponse {
}
// ImageSpec is an internal representation of an image. Currently, it wraps the
// value of a Container's Image field (e.g. imageName, imageName:tag, or
// imageName:digest), but in the future it will include more detailed
// information about the different image types.
// value of a Container's Image field (e.g. imageID or imageDigest), but in the
// future it will include more detailed information about the different image types.
message ImageSpec {
optional string image = 1;
}
@ -878,7 +877,11 @@ message PullImageRequest {
optional PodSandboxConfig sandbox_config = 3;
}
message PullImageResponse {}
message PullImageResponse {
// Reference to the image in use. For most runtimes, this should be an
// image ID or digest.
optional string image_ref = 1;
}
message RemoveImageRequest {
// Spec of the image to remove.

View File

@ -146,10 +146,11 @@ type IndirectStreamingRuntime interface {
type ImageService interface {
// PullImage pulls an image from the network to local storage using the supplied
// secrets if necessary.
PullImage(image ImageSpec, pullSecrets []v1.Secret) error
// IsImagePresent checks whether the container image is already in the local storage.
IsImagePresent(image ImageSpec) (bool, error)
// secrets if necessary. It returns a reference (digest or ID) to the pulled image.
PullImage(image ImageSpec, pullSecrets []v1.Secret) (string, error)
// GetImageRef gets the reference (digest or ID) of the image which has already been in
// the local storage. It returns ("", nil) if the image isn't in the local storage.
GetImageRef(image ImageSpec) (string, error)
// Gets all images currently on the machine.
ListImages() ([]Image, error)
// Removes the specified image.

View File

@ -348,25 +348,25 @@ func (f *FakeRuntime) GetContainerLogs(pod *v1.Pod, containerID ContainerID, log
return f.Err
}
func (f *FakeRuntime) PullImage(image ImageSpec, pullSecrets []v1.Secret) error {
func (f *FakeRuntime) PullImage(image ImageSpec, pullSecrets []v1.Secret) (string, error) {
f.Lock()
defer f.Unlock()
f.CalledFunctions = append(f.CalledFunctions, "PullImage")
return f.Err
return image.Image, f.Err
}
func (f *FakeRuntime) IsImagePresent(image ImageSpec) (bool, error) {
func (f *FakeRuntime) GetImageRef(image ImageSpec) (string, error) {
f.Lock()
defer f.Unlock()
f.CalledFunctions = append(f.CalledFunctions, "IsImagePresent")
f.CalledFunctions = append(f.CalledFunctions, "GetImageRef")
for _, i := range f.ImageList {
if i.ID == image.Image {
return true, nil
return i.ID, nil
}
}
return false, f.InspectErr
return "", f.InspectErr
}
func (f *FakeRuntime) ListImages() ([]Image, error) {

View File

@ -105,14 +105,14 @@ func (r *Mock) GetContainerLogs(pod *v1.Pod, containerID ContainerID, logOptions
return args.Error(0)
}
func (r *Mock) PullImage(image ImageSpec, pullSecrets []v1.Secret) error {
func (r *Mock) PullImage(image ImageSpec, pullSecrets []v1.Secret) (string, error) {
args := r.Called(image, pullSecrets)
return args.Error(0)
return image.Image, args.Error(0)
}
func (r *Mock) IsImagePresent(image ImageSpec) (bool, error) {
func (r *Mock) GetImageRef(image ImageSpec) (string, error) {
args := r.Called(image)
return args.Get(0).(bool), args.Error(1)
return args.Get(0).(string), args.Error(1)
}
func (r *Mock) ListImages() ([]Image, error) {

View File

@ -364,10 +364,14 @@ func (ds *dockerService) ContainerStatus(containerID string) (*runtimeapi.Contai
}
labels, annotations := extractLabels(r.Config.Labels)
imageName := r.Config.Image
if len(ir.RepoTags) > 0 {
imageName = ir.RepoTags[0]
}
return &runtimeapi.ContainerStatus{
Id: &r.ID,
Metadata: metadata,
Image: &runtimeapi.ImageSpec{Image: &r.Config.Image},
Image: &runtimeapi.ImageSpec{Image: &imageName},
ImageRef: &imageID,
Mounts: mounts,
ExitCode: &exitCode,

View File

@ -63,8 +63,8 @@ func (ds *dockerService) ImageStatus(image *runtimeapi.ImageSpec) (*runtimeapi.I
}
// PullImage pulls an image with authentication config.
func (ds *dockerService) PullImage(image *runtimeapi.ImageSpec, auth *runtimeapi.AuthConfig) error {
return ds.client.PullImage(image.GetImage(),
func (ds *dockerService) PullImage(image *runtimeapi.ImageSpec, auth *runtimeapi.AuthConfig) (string, error) {
err := ds.client.PullImage(image.GetImage(),
dockertypes.AuthConfig{
Username: auth.GetUsername(),
Password: auth.GetPassword(),
@ -74,6 +74,11 @@ func (ds *dockerService) PullImage(image *runtimeapi.ImageSpec, auth *runtimeapi
},
dockertypes.ImagePullOptions{},
)
if err != nil {
return "", err
}
return dockertools.GetImageRef(ds.client, image.GetImage())
}
// RemoveImage removes the image.

View File

@ -200,11 +200,11 @@ func (d *dockerService) ImageStatus(ctx context.Context, r *runtimeapi.ImageStat
}
func (d *dockerService) PullImage(ctx context.Context, r *runtimeapi.PullImageRequest) (*runtimeapi.PullImageResponse, error) {
err := d.imageService.PullImage(r.GetImage(), r.GetAuth())
image, err := d.imageService.PullImage(r.GetImage(), r.GetAuth())
if err != nil {
return nil, err
}
return &runtimeapi.PullImageResponse{}, nil
return &runtimeapi.PullImageResponse{ImageRef: &image}, nil
}
func (d *dockerService) RemoveImage(ctx context.Context, r *runtimeapi.RemoveImageRequest) (*runtimeapi.RemoveImageResponse, error) {

View File

@ -94,7 +94,7 @@ func SetContainerNamePrefix(prefix string) {
// DockerPuller is an abstract interface for testability. It abstracts image pull operations.
type DockerPuller interface {
Pull(image string, secrets []v1.Secret) error
IsImagePresent(image string) (bool, error)
GetImageRef(image string) (string, error)
}
// dockerPuller is the default implementation of DockerPuller.
@ -241,11 +241,11 @@ func (p dockerPuller) Pull(image string, secrets []v1.Secret) error {
err := p.client.PullImage(image, dockertypes.AuthConfig{}, opts)
if err == nil {
// Sometimes PullImage failed with no error returned.
exist, ierr := p.IsImagePresent(image)
imageRef, ierr := p.GetImageRef(image)
if ierr != nil {
glog.Warningf("Failed to inspect image %s: %v", image, ierr)
}
if !exist {
if imageRef == "" {
return fmt.Errorf("image pull failed for unknown error")
}
return nil
@ -277,15 +277,23 @@ func (p dockerPuller) Pull(image string, secrets []v1.Secret) error {
return utilerrors.NewAggregate(pullErrs)
}
func (p dockerPuller) IsImagePresent(image string) (bool, error) {
_, err := p.client.InspectImageByRef(image)
func (p dockerPuller) GetImageRef(image string) (string, error) {
resp, err := p.client.InspectImageByRef(image)
if err == nil {
return true, nil
if resp == nil {
return "", nil
}
imageRef := resp.ID
if len(resp.RepoDigests) > 0 {
imageRef = resp.RepoDigests[0]
}
return imageRef, nil
}
if _, ok := err.(imageNotFoundError); ok {
return false, nil
return "", nil
}
return false, err
return "", err
}
// Creates a name which can be reversed to identify both full pod name and container name.

View File

@ -430,10 +430,14 @@ func (dm *DockerManager) inspectContainer(id string, podName, podNamespace strin
}
}
imageName := iResult.Config.Image
if len(imgInspectResult.RepoTags) > 0 {
imageName = imgInspectResult.RepoTags[0]
}
status := kubecontainer.ContainerStatus{
Name: containerName,
RestartCount: containerInfo.RestartCount,
Image: iResult.Config.Image,
Image: imageName,
ImageID: imageID,
ID: kubecontainer.DockerID(id).ContainerID(),
ExitCode: iResult.State.ExitCode,
@ -590,6 +594,7 @@ func (dm *DockerManager) runContainer(
container *v1.Container,
opts *kubecontainer.RunContainerOptions,
ref *v1.ObjectReference,
imageRef string,
netMode string,
ipcMode string,
utsMode string,
@ -765,7 +770,7 @@ func (dm *DockerManager) runContainer(
Name: containerName,
Config: &dockercontainer.Config{
Env: makeEnvList(opts.Envs),
Image: container.Image,
Image: imageRef,
WorkingDir: container.WorkingDir,
Labels: labels,
// Interactive containers:
@ -958,14 +963,39 @@ func (dm *DockerManager) ListImages() ([]kubecontainer.Image, error) {
return images, nil
}
// PullImage pulls an image from network to local storage.
func (dm *DockerManager) PullImage(image kubecontainer.ImageSpec, secrets []v1.Secret) error {
return dm.dockerPuller.Pull(image.Image, secrets)
// GetImageRef returns the image digest if exists, or else returns the image ID.
// It is exported for reusing in dockershim.
func GetImageRef(client DockerInterface, image string) (string, error) {
img, err := client.InspectImageByRef(image)
if err != nil {
return "", err
}
if img == nil {
return "", fmt.Errorf("unable to inspect image %s", image)
}
// Returns the digest if it exist.
if len(img.RepoDigests) > 0 {
return img.RepoDigests[0], nil
}
return img.ID, nil
}
// IsImagePresent checks whether the container image is already in the local storage.
func (dm *DockerManager) IsImagePresent(image kubecontainer.ImageSpec) (bool, error) {
return dm.dockerPuller.IsImagePresent(image.Image)
// PullImage pulls an image from network to local storage.
func (dm *DockerManager) PullImage(image kubecontainer.ImageSpec, secrets []v1.Secret) (string, error) {
err := dm.dockerPuller.Pull(image.Image, secrets)
if err != nil {
return "", err
}
return GetImageRef(dm.client, image.Image)
}
// GetImageRef gets the reference (digest or ID) of the image which has already been in
// the local storage. It returns ("", nil) if the image isn't in the local storage.
func (dm *DockerManager) GetImageRef(image kubecontainer.ImageSpec) (string, error) {
return dm.dockerPuller.GetImageRef(image.Image)
}
// Removes the specified image.
@ -1683,7 +1713,7 @@ func (dm *DockerManager) applyOOMScoreAdj(pod *v1.Pod, container *v1.Container,
// Run a single container from a pod. Returns the docker container ID
// If do not need to pass labels, just pass nil.
func (dm *DockerManager) runContainerInPod(pod *v1.Pod, container *v1.Container, netMode, ipcMode, pidMode, podIP string, restartCount int) (kubecontainer.ContainerID, error) {
func (dm *DockerManager) runContainerInPod(pod *v1.Pod, container *v1.Container, netMode, ipcMode, pidMode, podIP, imageRef string, restartCount int) (kubecontainer.ContainerID, error) {
start := time.Now()
defer func() {
metrics.ContainerManagerLatency.WithLabelValues("runContainerInPod").Observe(metrics.SinceInMicroseconds(start))
@ -1708,7 +1738,7 @@ func (dm *DockerManager) runContainerInPod(pod *v1.Pod, container *v1.Container,
oomScoreAdj := dm.calculateOomScoreAdj(pod, container)
id, err := dm.runContainer(pod, container, opts, ref, netMode, ipcMode, utsMode, pidMode, restartCount, oomScoreAdj)
id, err := dm.runContainer(pod, container, opts, ref, imageRef, netMode, ipcMode, utsMode, pidMode, restartCount, oomScoreAdj)
if err != nil {
return kubecontainer.ContainerID{}, fmt.Errorf("runContainer: %v", err)
}
@ -1888,12 +1918,13 @@ func (dm *DockerManager) createPodInfraContainer(pod *v1.Pod) (kubecontainer.Doc
// No pod secrets for the infra container.
// The message isn't needed for the Infra container
if err, msg := dm.imagePuller.EnsureImageExists(pod, container, nil); err != nil {
imageRef, msg, err := dm.imagePuller.EnsureImageExists(pod, container, nil)
if err != nil {
return "", err, msg
}
// Currently we don't care about restart count of infra container, just set it to 0.
id, err := dm.runContainerInPod(pod, container, netNamespace, getIPCMode(pod), getPidMode(pod), "", 0)
id, err := dm.runContainerInPod(pod, container, netNamespace, getIPCMode(pod), getPidMode(pod), "", imageRef, 0)
if err != nil {
return "", kubecontainer.ErrRunContainer, err.Error()
}
@ -2305,7 +2336,7 @@ func (dm *DockerManager) SyncPod(pod *v1.Pod, _ v1.PodStatus, podStatus *kubecon
// tryContainerStart attempts to pull and start the container, returning an error and a reason string if the start
// was not successful.
func (dm *DockerManager) tryContainerStart(container *v1.Container, pod *v1.Pod, podStatus *kubecontainer.PodStatus, pullSecrets []v1.Secret, namespaceMode, pidMode, podIP string) (err error, reason string) {
err, msg := dm.imagePuller.EnsureImageExists(pod, container, pullSecrets)
imageRef, msg, err := dm.imagePuller.EnsureImageExists(pod, container, pullSecrets)
if err != nil {
return err, msg
}
@ -2331,7 +2362,7 @@ func (dm *DockerManager) tryContainerStart(container *v1.Container, pod *v1.Pod,
netMode = namespaceMode
}
_, err = dm.runContainerInPod(pod, container, netMode, namespaceMode, pidMode, podIP, restartCount)
_, err = dm.runContainerInPod(pod, container, netMode, namespaceMode, pidMode, podIP, imageRef, restartCount)
if err != nil {
// TODO(bburns) : Perhaps blacklist a container after N failures?
return kubecontainer.ErrRunContainer, err.Error()

View File

@ -112,8 +112,8 @@ func newFakeImageManager() images.ImageManager {
return &fakeImageManager{}
}
func (m *fakeImageManager) EnsureImageExists(pod *v1.Pod, container *v1.Container, pullSecrets []v1.Secret) (error, string) {
return nil, ""
func (m *fakeImageManager) EnsureImageExists(pod *v1.Pod, container *v1.Container, pullSecrets []v1.Secret) (string, string, error) {
return container.Image, "", nil
}
func createTestDockerManager(fakeHTTPClient *fakeHTTP, fakeDocker *FakeDockerClient) (*DockerManager, *FakeDockerClient) {
@ -647,9 +647,9 @@ func TestSyncPodCreatesNetAndContainerPullsImage(t *testing.T) {
verifyCalls(t, fakeDocker, []string{
// Create pod infra container.
"create", "start", "inspect_container", "inspect_container",
"inspect_image", "create", "start", "inspect_container", "inspect_container",
// Create container.
"create", "start", "inspect_container",
"inspect_image", "create", "start", "inspect_container",
})
fakeDocker.Lock()

View File

@ -705,12 +705,12 @@ func (f *imageTrackingDockerClient) InspectImageByRef(name string) (image *docke
return
}
func TestIsImagePresent(t *testing.T) {
func TestGetImageRef(t *testing.T) {
cl := &imageTrackingDockerClient{NewFakeDockerClient(), ""}
puller := &dockerPuller{
client: cl,
}
_, _ = puller.IsImagePresent("abc:123")
_, _ = puller.GetImageRef("abc:123")
if cl.imageName != "abc:123" {
t.Errorf("expected inspection of image abc:123, instead inspected image %v", cl.imageName)
}

View File

@ -478,6 +478,10 @@ func (f *FakeDockerClient) PullImage(image string, auth dockertypes.AuthConfig,
err := f.popError("pull")
if err == nil {
authJson, _ := json.Marshal(auth)
f.Image = &dockertypes.ImageInspect{
ID: image,
RepoTags: []string{image},
}
f.pulled = append(f.pulled, fmt.Sprintf("%s using %s", image, string(authJson)))
}
return err
@ -592,18 +596,18 @@ func (f *FakeDockerPuller) Pull(image string, secrets []v1.Secret) (err error) {
return err
}
func (f *FakeDockerPuller) IsImagePresent(name string) (bool, error) {
func (f *FakeDockerPuller) GetImageRef(name string) (string, error) {
f.Lock()
defer f.Unlock()
if f.HasImages == nil {
return true, nil
return name, nil
}
for _, s := range f.HasImages {
if s == name {
return true, nil
return s, nil
}
}
return false, nil
return "", nil
}
func (f *FakeDockerClient) ImageHistory(id string) ([]dockertypes.ImageHistory, error) {
f.Lock()

View File

@ -42,9 +42,9 @@ type throttledImageService struct {
limiter flowcontrol.RateLimiter
}
func (ts throttledImageService) PullImage(image kubecontainer.ImageSpec, secrets []v1.Secret) error {
func (ts throttledImageService) PullImage(image kubecontainer.ImageSpec, secrets []v1.Secret) (string, error) {
if ts.limiter.TryAccept() {
return ts.ImageService.PullImage(image, secrets)
}
return fmt.Errorf("pull QPS exceeded.")
return "", fmt.Errorf("pull QPS exceeded.")
}

View File

@ -81,8 +81,9 @@ func (m *imageManager) logIt(ref *v1.ObjectReference, eventtype, event, prefix,
}
}
// EnsureImageExists pulls the image for the specified pod and container.
func (m *imageManager) EnsureImageExists(pod *v1.Pod, container *v1.Container, pullSecrets []v1.Secret) (error, string) {
// EnsureImageExists pulls the image for the specified pod and container, and returns
// (imageRef, error message, error).
func (m *imageManager) EnsureImageExists(pod *v1.Pod, container *v1.Container, pullSecrets []v1.Secret) (string, string, error) {
logPrefix := fmt.Sprintf("%s/%s", pod.Name, container.Image)
ref, err := kubecontainer.GenerateContainerRef(pod, container)
if err != nil {
@ -94,26 +95,27 @@ func (m *imageManager) EnsureImageExists(pod *v1.Pod, container *v1.Container, p
if err != nil {
msg := fmt.Sprintf("Failed to apply default image tag %q: %v", container.Image, err)
m.logIt(ref, v1.EventTypeWarning, events.FailedToInspectImage, logPrefix, msg, glog.Warning)
return ErrInvalidImageName, msg
return "", msg, ErrInvalidImageName
}
spec := kubecontainer.ImageSpec{Image: image}
present, err := m.imageService.IsImagePresent(spec)
imageRef, err := m.imageService.GetImageRef(spec)
if err != nil {
msg := fmt.Sprintf("Failed to inspect image %q: %v", container.Image, err)
m.logIt(ref, v1.EventTypeWarning, events.FailedToInspectImage, logPrefix, msg, glog.Warning)
return ErrImageInspect, msg
return "", msg, ErrImageInspect
}
present := imageRef != ""
if !shouldPullImage(container, present) {
if present {
msg := fmt.Sprintf("Container image %q already present on machine", container.Image)
m.logIt(ref, v1.EventTypeNormal, events.PulledImage, logPrefix, msg, glog.Info)
return nil, ""
return imageRef, "", nil
} else {
msg := fmt.Sprintf("Container image %q is not present with pull policy of Never", container.Image)
m.logIt(ref, v1.EventTypeWarning, events.ErrImageNeverPullPolicy, logPrefix, msg, glog.Warning)
return ErrImageNeverPull, msg
return "", msg, ErrImageNeverPull
}
}
@ -121,24 +123,25 @@ func (m *imageManager) EnsureImageExists(pod *v1.Pod, container *v1.Container, p
if m.backOff.IsInBackOffSinceUpdate(backOffKey, m.backOff.Clock.Now()) {
msg := fmt.Sprintf("Back-off pulling image %q", container.Image)
m.logIt(ref, v1.EventTypeNormal, events.BackOffPullImage, logPrefix, msg, glog.Info)
return ErrImagePullBackOff, msg
return "", msg, ErrImagePullBackOff
}
m.logIt(ref, v1.EventTypeNormal, events.PullingImage, logPrefix, fmt.Sprintf("pulling image %q", container.Image), glog.Info)
errChan := make(chan error)
m.puller.pullImage(spec, pullSecrets, errChan)
if err := <-errChan; err != nil {
m.logIt(ref, v1.EventTypeWarning, events.FailedToPullImage, logPrefix, fmt.Sprintf("Failed to pull image %q: %v", container.Image, err), glog.Warning)
pullChan := make(chan pullResult)
m.puller.pullImage(spec, pullSecrets, pullChan)
imagePullResult := <-pullChan
if imagePullResult.err != nil {
m.logIt(ref, v1.EventTypeWarning, events.FailedToPullImage, logPrefix, fmt.Sprintf("Failed to pull image %q: %v", container.Image, imagePullResult.err), glog.Warning)
m.backOff.Next(backOffKey, m.backOff.Clock.Now())
if err == RegistryUnavailable {
if imagePullResult.err == RegistryUnavailable {
msg := fmt.Sprintf("image pull failed for %s because the registry is unavailable.", container.Image)
return err, msg
} else {
return ErrImagePull, err.Error()
return "", msg, imagePullResult.err
}
return "", imagePullResult.err.Error(), ErrImagePull
}
m.logIt(ref, v1.EventTypeNormal, events.PulledImage, logPrefix, fmt.Sprintf("Successfully pulled image %q", container.Image), glog.Info)
m.backOff.GC()
return nil, ""
return imagePullResult.imageRef, "", nil
}
// applyDefaultImageTag parses a docker image string, if it doesn't contain any tag or digest,

View File

@ -44,7 +44,7 @@ func pullerTestCases() []pullerTestCase {
{ // pull missing image
containerImage: "missing_image",
policy: v1.PullIfNotPresent,
calledFunctions: []string{"IsImagePresent", "PullImage"},
calledFunctions: []string{"GetImageRef", "PullImage"},
inspectErr: nil,
pullerErr: nil,
expectedErr: []error{nil}},
@ -52,35 +52,35 @@ func pullerTestCases() []pullerTestCase {
{ // image present, don't pull
containerImage: "present_image",
policy: v1.PullIfNotPresent,
calledFunctions: []string{"IsImagePresent"},
calledFunctions: []string{"GetImageRef"},
inspectErr: nil,
pullerErr: nil,
expectedErr: []error{nil, nil, nil}},
// image present, pull it
{containerImage: "present_image",
policy: v1.PullAlways,
calledFunctions: []string{"IsImagePresent", "PullImage"},
calledFunctions: []string{"GetImageRef", "PullImage"},
inspectErr: nil,
pullerErr: nil,
expectedErr: []error{nil, nil, nil}},
// missing image, error PullNever
{containerImage: "missing_image",
policy: v1.PullNever,
calledFunctions: []string{"IsImagePresent"},
calledFunctions: []string{"GetImageRef"},
inspectErr: nil,
pullerErr: nil,
expectedErr: []error{ErrImageNeverPull, ErrImageNeverPull, ErrImageNeverPull}},
// missing image, unable to inspect
{containerImage: "missing_image",
policy: v1.PullIfNotPresent,
calledFunctions: []string{"IsImagePresent"},
calledFunctions: []string{"GetImageRef"},
inspectErr: errors.New("unknown inspectError"),
pullerErr: nil,
expectedErr: []error{ErrImageInspect, ErrImageInspect, ErrImageInspect}},
// missing image, unable to fetch
{containerImage: "typo_image",
policy: v1.PullIfNotPresent,
calledFunctions: []string{"IsImagePresent", "PullImage"},
calledFunctions: []string{"GetImageRef", "PullImage"},
inspectErr: nil,
pullerErr: errors.New("404"),
expectedErr: []error{ErrImagePull, ErrImagePull, ErrImagePullBackOff, ErrImagePull, ErrImagePullBackOff, ErrImagePullBackOff}},
@ -126,7 +126,7 @@ func TestParallelPuller(t *testing.T) {
for tick, expected := range c.expectedErr {
fakeClock.Step(time.Second)
err, _ := puller.EnsureImageExists(pod, container, nil)
_, _, err := puller.EnsureImageExists(pod, container, nil)
fakeRuntime.AssertCalls(c.calledFunctions)
assert.Equal(t, expected, err, "in test %d tick=%d", i, tick)
}
@ -150,7 +150,7 @@ func TestSerializedPuller(t *testing.T) {
for tick, expected := range c.expectedErr {
fakeClock.Step(time.Second)
err, _ := puller.EnsureImageExists(pod, container, nil)
_, _, err := puller.EnsureImageExists(pod, container, nil)
fakeRuntime.AssertCalls(c.calledFunctions)
assert.Equal(t, expected, err, "in test %d tick=%d", i, tick)
}

View File

@ -24,8 +24,13 @@ import (
"k8s.io/kubernetes/pkg/util/wait"
)
type pullResult struct {
imageRef string
err error
}
type imagePuller interface {
pullImage(kubecontainer.ImageSpec, []v1.Secret, chan<- error)
pullImage(kubecontainer.ImageSpec, []v1.Secret, chan<- pullResult)
}
var _, _ imagePuller = &parallelImagePuller{}, &serialImagePuller{}
@ -38,9 +43,13 @@ func newParallelImagePuller(imageService kubecontainer.ImageService) imagePuller
return &parallelImagePuller{imageService}
}
func (pip *parallelImagePuller) pullImage(spec kubecontainer.ImageSpec, pullSecrets []v1.Secret, errChan chan<- error) {
func (pip *parallelImagePuller) pullImage(spec kubecontainer.ImageSpec, pullSecrets []v1.Secret, pullChan chan<- pullResult) {
go func() {
errChan <- pip.imageService.PullImage(spec, pullSecrets)
imageRef, err := pip.imageService.PullImage(spec, pullSecrets)
pullChan <- pullResult{
imageRef: imageRef,
err: err,
}
}()
}
@ -61,19 +70,23 @@ func newSerialImagePuller(imageService kubecontainer.ImageService) imagePuller {
type imagePullRequest struct {
spec kubecontainer.ImageSpec
pullSecrets []v1.Secret
errChan chan<- error
pullChan chan<- pullResult
}
func (sip *serialImagePuller) pullImage(spec kubecontainer.ImageSpec, pullSecrets []v1.Secret, errChan chan<- error) {
func (sip *serialImagePuller) pullImage(spec kubecontainer.ImageSpec, pullSecrets []v1.Secret, pullChan chan<- pullResult) {
sip.pullRequests <- &imagePullRequest{
spec: spec,
pullSecrets: pullSecrets,
errChan: errChan,
pullChan: pullChan,
}
}
func (sip *serialImagePuller) processImagePullRequests() {
for pullRequest := range sip.pullRequests {
pullRequest.errChan <- sip.imageService.PullImage(pullRequest.spec, pullRequest.pullSecrets)
imageRef, err := sip.imageService.PullImage(pullRequest.spec, pullRequest.pullSecrets)
pullRequest.pullChan <- pullResult{
imageRef: imageRef,
err: err,
}
}
}

View File

@ -49,7 +49,7 @@ var (
// Implementations are expected to be thread safe.
type ImageManager interface {
// EnsureImageExists ensures that image specified in `container` exists.
EnsureImageExists(pod *v1.Pod, container *v1.Container, pullSecrets []v1.Secret) (error, string)
EnsureImageExists(pod *v1.Pod, container *v1.Container, pullSecrets []v1.Secret) (string, string, error)
// TODO(ronl): consolidating image managing and deleting operation in this interface
}

View File

@ -239,13 +239,13 @@ func (in instrumentedImageManagerService) ImageStatus(image *runtimeapi.ImageSpe
return out, err
}
func (in instrumentedImageManagerService) PullImage(image *runtimeapi.ImageSpec, auth *runtimeapi.AuthConfig) error {
func (in instrumentedImageManagerService) PullImage(image *runtimeapi.ImageSpec, auth *runtimeapi.AuthConfig) (string, error) {
const operation = "pull_image"
defer recordOperation(operation, time.Now())
err := in.service.PullImage(image, auth)
imageRef, err := in.service.PullImage(image, auth)
recordError(operation, err)
return err
return imageRef, err
}
func (in instrumentedImageManagerService) RemoveImage(image *runtimeapi.ImageSpec) error {

View File

@ -51,7 +51,7 @@ import (
// * run the post start lifecycle hooks (if applicable)
func (m *kubeGenericRuntimeManager) startContainer(podSandboxID string, podSandboxConfig *runtimeapi.PodSandboxConfig, container *v1.Container, pod *v1.Pod, podStatus *kubecontainer.PodStatus, pullSecrets []v1.Secret, podIP string) (string, error) {
// Step 1: pull the image.
err, msg := m.imagePuller.EnsureImageExists(pod, container, pullSecrets)
imageRef, msg, err := m.imagePuller.EnsureImageExists(pod, container, pullSecrets)
if err != nil {
return msg, err
}
@ -70,7 +70,7 @@ func (m *kubeGenericRuntimeManager) startContainer(podSandboxID string, podSandb
restartCount = containerStatus.RestartCount + 1
}
containerConfig, err := m.generateContainerConfig(container, pod, restartCount, podIP)
containerConfig, err := m.generateContainerConfig(container, pod, restartCount, podIP, imageRef)
if err != nil {
m.recorder.Eventf(ref, v1.EventTypeWarning, events.FailedToCreateContainer, "Failed to create container with error: %v", err)
return "Generate Container Config Failed", err
@ -129,7 +129,7 @@ func (m *kubeGenericRuntimeManager) startContainer(podSandboxID string, podSandb
}
// generateContainerConfig generates container config for kubelet runtime v1.
func (m *kubeGenericRuntimeManager) generateContainerConfig(container *v1.Container, pod *v1.Pod, restartCount int, podIP string) (*runtimeapi.ContainerConfig, error) {
func (m *kubeGenericRuntimeManager) generateContainerConfig(container *v1.Container, pod *v1.Pod, restartCount int, podIP, imageRef string) (*runtimeapi.ContainerConfig, error) {
opts, err := m.runtimeHelper.GenerateRunContainerOptions(pod, container, podIP)
if err != nil {
return nil, err
@ -156,7 +156,7 @@ func (m *kubeGenericRuntimeManager) generateContainerConfig(container *v1.Contai
Name: &container.Name,
Attempt: &restartCountUint32,
},
Image: &runtimeapi.ImageSpec{Image: &container.Image},
Image: &runtimeapi.ImageSpec{Image: &imageRef},
Command: command,
Args: args,
WorkingDir: &container.WorkingDir,

View File

@ -28,16 +28,16 @@ import (
// PullImage pulls an image from the network to local storage using the supplied
// secrets if necessary.
func (m *kubeGenericRuntimeManager) PullImage(image kubecontainer.ImageSpec, pullSecrets []v1.Secret) error {
func (m *kubeGenericRuntimeManager) PullImage(image kubecontainer.ImageSpec, pullSecrets []v1.Secret) (string, error) {
img := image.Image
repoToPull, _, _, err := parsers.ParseImageName(img)
if err != nil {
return err
return "", err
}
keyring, err := credentialprovider.MakeDockerKeyring(pullSecrets, m.keyring)
if err != nil {
return err
return "", err
}
imgSpec := &runtimeapi.ImageSpec{Image: &img}
@ -45,13 +45,13 @@ func (m *kubeGenericRuntimeManager) PullImage(image kubecontainer.ImageSpec, pul
if !withCredentials {
glog.V(3).Infof("Pulling image %q without credentials", img)
err = m.imageService.PullImage(imgSpec, nil)
imageRef, err := m.imageService.PullImage(imgSpec, nil)
if err != nil {
glog.Errorf("Pull image %q failed: %v", img, err)
return err
return "", err
}
return nil
return imageRef, nil
}
var pullErrs []error
@ -66,26 +66,35 @@ func (m *kubeGenericRuntimeManager) PullImage(image kubecontainer.ImageSpec, pul
RegistryToken: &authConfig.RegistryToken,
}
err = m.imageService.PullImage(imgSpec, auth)
imageRef, err := m.imageService.PullImage(imgSpec, auth)
// If there was no error, return success
if err == nil {
return nil
return imageRef, nil
}
pullErrs = append(pullErrs, err)
}
return utilerrors.NewAggregate(pullErrs)
return "", utilerrors.NewAggregate(pullErrs)
}
// IsImagePresent checks whether the container image is already in the local storage.
func (m *kubeGenericRuntimeManager) IsImagePresent(image kubecontainer.ImageSpec) (bool, error) {
// GetImageRef gets the reference (digest or ID) of the image which has already been in
// the local storage. It returns ("", nil) if the image isn't in the local storage.
func (m *kubeGenericRuntimeManager) GetImageRef(image kubecontainer.ImageSpec) (string, error) {
status, err := m.imageService.ImageStatus(&runtimeapi.ImageSpec{Image: &image.Image})
if err != nil {
glog.Errorf("ImageStatus for image %q failed: %v", image, err)
return false, err
return "", err
}
return status != nil, nil
if status == nil {
return "", nil
}
imageRef := status.GetId()
if len(status.RepoDigests) > 0 {
imageRef = status.RepoDigests[0]
}
return imageRef, nil
}
// ListImages gets all images currently on the machine.

View File

@ -28,8 +28,9 @@ func TestPullImage(t *testing.T) {
_, _, fakeManager, err := createTestRuntimeManager()
assert.NoError(t, err)
err = fakeManager.PullImage(kubecontainer.ImageSpec{Image: "busybox"}, nil)
imageRef, err := fakeManager.PullImage(kubecontainer.ImageSpec{Image: "busybox"}, nil)
assert.NoError(t, err)
assert.Equal(t, "busybox", imageRef)
images, err := fakeManager.ListImages()
assert.NoError(t, err)
@ -55,22 +56,22 @@ func TestListImages(t *testing.T) {
assert.Equal(t, expected.List(), actual.List())
}
func TestIsImagePresent(t *testing.T) {
func TestGetImageRef(t *testing.T) {
_, fakeImageService, fakeManager, err := createTestRuntimeManager()
assert.NoError(t, err)
image := "busybox"
fakeImageService.SetFakeImages([]string{image})
present, err := fakeManager.IsImagePresent(kubecontainer.ImageSpec{Image: image})
imageRef, err := fakeManager.GetImageRef(kubecontainer.ImageSpec{Image: image})
assert.NoError(t, err)
assert.Equal(t, true, present)
assert.Equal(t, image, imageRef)
}
func TestRemoveImage(t *testing.T) {
_, fakeImageService, fakeManager, err := createTestRuntimeManager()
assert.NoError(t, err)
err = fakeManager.PullImage(kubecontainer.ImageSpec{Image: "busybox"}, nil)
_, err = fakeManager.PullImage(kubecontainer.ImageSpec{Image: "busybox"}, nil)
assert.NoError(t, err)
assert.Equal(t, 1, len(fakeImageService.Images))

View File

@ -145,7 +145,7 @@ func makeFakeContainer(t *testing.T, m *kubeGenericRuntimeManager, template cont
sandboxConfig, err := m.generatePodSandboxConfig(template.pod, template.sandboxAttempt)
assert.NoError(t, err, "generatePodSandboxConfig for container template %+v", template)
containerConfig, err := m.generateContainerConfig(template.container, template.pod, template.attempt, "")
containerConfig, err := m.generateContainerConfig(template.container, template.pod, template.attempt, "", template.container.Image)
assert.NoError(t, err, "generateContainerConfig for container template %+v", template)
podSandboxID := apitest.BuildSandboxName(sandboxConfig.Metadata)

View File

@ -79,20 +79,20 @@ func (r *RemoteImageService) ImageStatus(image *runtimeapi.ImageSpec) (*runtimea
}
// PullImage pulls an image with authentication config.
func (r *RemoteImageService) PullImage(image *runtimeapi.ImageSpec, auth *runtimeapi.AuthConfig) error {
func (r *RemoteImageService) PullImage(image *runtimeapi.ImageSpec, auth *runtimeapi.AuthConfig) (string, error) {
ctx, cancel := getContextWithTimeout(r.timeout)
defer cancel()
_, err := r.imageClient.PullImage(ctx, &runtimeapi.PullImageRequest{
resp, err := r.imageClient.PullImage(ctx, &runtimeapi.PullImageRequest{
Image: image,
Auth: auth,
})
if err != nil {
glog.Errorf("PullImage %q from image service failed: %v", image.GetImage(), err)
return err
return "", err
}
return nil
return resp.GetImageRef(), nil
}
// RemoveImage removes the image.

View File

@ -45,18 +45,18 @@ import (
//
// http://issue.k8s.io/7203
//
func (r *Runtime) PullImage(image kubecontainer.ImageSpec, pullSecrets []v1.Secret) error {
func (r *Runtime) PullImage(image kubecontainer.ImageSpec, pullSecrets []v1.Secret) (string, error) {
img := image.Image
// TODO(yifan): The credential operation is a copy from dockertools package,
// Need to resolve the code duplication.
repoToPull, _, _, err := parsers.ParseImageName(img)
if err != nil {
return err
return "", err
}
keyring, err := credentialprovider.MakeDockerKeyring(pullSecrets, r.dockerKeyring)
if err != nil {
return err
return "", err
}
creds, ok := keyring.Lookup(repoToPull)
@ -66,7 +66,7 @@ func (r *Runtime) PullImage(image kubecontainer.ImageSpec, pullSecrets []v1.Secr
userConfigDir, err := ioutil.TempDir("", "rktnetes-user-config-dir-")
if err != nil {
return fmt.Errorf("rkt: Cannot create a temporary user-config directory: %v", err)
return "", fmt.Errorf("rkt: Cannot create a temporary user-config directory: %v", err)
}
defer os.RemoveAll(userConfigDir)
@ -74,7 +74,7 @@ func (r *Runtime) PullImage(image kubecontainer.ImageSpec, pullSecrets []v1.Secr
config.UserConfigDir = userConfigDir
if err := r.writeDockerAuthConfig(img, creds, userConfigDir); err != nil {
return err
return "", err
}
// Today, `--no-store` will fetch the remote image regardless of whether the content of the image
@ -82,14 +82,20 @@ func (r *Runtime) PullImage(image kubecontainer.ImageSpec, pullSecrets []v1.Secr
// the image pull policy is 'always'. The issue is tracked in https://github.com/coreos/rkt/issues/2937.
if _, err := r.cli.RunCommand(&config, "fetch", "--no-store", dockerPrefix+img); err != nil {
glog.Errorf("Failed to fetch: %v", err)
return err
return "", err
}
return nil
return r.getImageID(img)
}
func (r *Runtime) IsImagePresent(image kubecontainer.ImageSpec) (bool, error) {
func (r *Runtime) GetImageRef(image kubecontainer.ImageSpec) (string, error) {
images, err := r.listImages(image.Image, false)
return len(images) > 0, err
if err != nil {
return "", err
}
if len(images) == 0 {
return "", nil
}
return images[0].Id, nil
}
// ListImages lists all the available appc images on the machine by invoking 'rkt image list'.

View File

@ -782,8 +782,9 @@ func (r *Runtime) newAppcRuntimeApp(pod *v1.Pod, podIP string, c v1.Container, r
if requiresPrivileged && !securitycontext.HasPrivilegedRequest(&c) {
return fmt.Errorf("cannot make %q: running a custom stage1 requires a privileged security context", format.Pod(pod))
}
if err, _ := r.imagePuller.EnsureImageExists(pod, &c, pullSecrets); err != nil {
return nil
imageRef, _, err := r.imagePuller.EnsureImageExists(pod, &c, pullSecrets)
if err != nil {
return err
}
imgManifest, err := r.getImageManifest(c.Image)
if err != nil {
@ -794,11 +795,7 @@ func (r *Runtime) newAppcRuntimeApp(pod *v1.Pod, podIP string, c v1.Container, r
imgManifest.App = new(appctypes.App)
}
imageID, err := r.getImageID(c.Image)
if err != nil {
return err
}
hash, err := appctypes.NewHash(imageID)
hash, err := appctypes.NewHash(imageRef)
if err != nil {
return err
}