diff --git a/pkg/kubelet/api/services.go b/pkg/kubelet/api/services.go index a1672cccc4f..f3febd1ebac 100644 --- a/pkg/kubelet/api/services.go +++ b/pkg/kubelet/api/services.go @@ -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 } diff --git a/pkg/kubelet/api/testing/fake_image_service.go b/pkg/kubelet/api/testing/fake_image_service.go index 22eb9e4fa2f..6bd243afb46 100644 --- a/pkg/kubelet/api/testing/fake_image_service.go +++ b/pkg/kubelet/api/testing/fake_image_service.go @@ -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 { diff --git a/pkg/kubelet/api/v1alpha1/runtime/api.pb.go b/pkg/kubelet/api/v1alpha1/runtime/api.pb.go index a22ed9949f0..b5d3e67bacc 100644 --- a/pkg/kubelet/api/v1alpha1/runtime/api.pb.go +++ b/pkg/kubelet/api/v1alpha1/runtime/api.pb.go @@ -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, } diff --git a/pkg/kubelet/api/v1alpha1/runtime/api.proto b/pkg/kubelet/api/v1alpha1/runtime/api.proto index c294e38845b..ecd56311656 100644 --- a/pkg/kubelet/api/v1alpha1/runtime/api.proto +++ b/pkg/kubelet/api/v1alpha1/runtime/api.proto @@ -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. diff --git a/pkg/kubelet/container/runtime.go b/pkg/kubelet/container/runtime.go index 85dc81f15ff..47d3d88dce4 100644 --- a/pkg/kubelet/container/runtime.go +++ b/pkg/kubelet/container/runtime.go @@ -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. diff --git a/pkg/kubelet/container/testing/fake_runtime.go b/pkg/kubelet/container/testing/fake_runtime.go index 87fff6be757..c19404f7f78 100644 --- a/pkg/kubelet/container/testing/fake_runtime.go +++ b/pkg/kubelet/container/testing/fake_runtime.go @@ -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) { diff --git a/pkg/kubelet/container/testing/runtime_mock.go b/pkg/kubelet/container/testing/runtime_mock.go index 6fb4acea64c..aff6dedcdd7 100644 --- a/pkg/kubelet/container/testing/runtime_mock.go +++ b/pkg/kubelet/container/testing/runtime_mock.go @@ -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) { diff --git a/pkg/kubelet/dockershim/docker_container.go b/pkg/kubelet/dockershim/docker_container.go index 0e8f80814f9..51379b9c66f 100644 --- a/pkg/kubelet/dockershim/docker_container.go +++ b/pkg/kubelet/dockershim/docker_container.go @@ -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, diff --git a/pkg/kubelet/dockershim/docker_image.go b/pkg/kubelet/dockershim/docker_image.go index e0239737fa9..15aa7d95410 100644 --- a/pkg/kubelet/dockershim/docker_image.go +++ b/pkg/kubelet/dockershim/docker_image.go @@ -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. diff --git a/pkg/kubelet/dockershim/remote/docker_service.go b/pkg/kubelet/dockershim/remote/docker_service.go index 15abc8399e2..8274d83315d 100644 --- a/pkg/kubelet/dockershim/remote/docker_service.go +++ b/pkg/kubelet/dockershim/remote/docker_service.go @@ -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) { diff --git a/pkg/kubelet/dockertools/docker.go b/pkg/kubelet/dockertools/docker.go index f3bc5ebacd5..f774cd34d00 100644 --- a/pkg/kubelet/dockertools/docker.go +++ b/pkg/kubelet/dockertools/docker.go @@ -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. diff --git a/pkg/kubelet/dockertools/docker_manager.go b/pkg/kubelet/dockertools/docker_manager.go index f515db814fc..cb8211fc72e 100644 --- a/pkg/kubelet/dockertools/docker_manager.go +++ b/pkg/kubelet/dockertools/docker_manager.go @@ -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() diff --git a/pkg/kubelet/dockertools/docker_manager_test.go b/pkg/kubelet/dockertools/docker_manager_test.go index eee5f102348..2f22a76bc34 100644 --- a/pkg/kubelet/dockertools/docker_manager_test.go +++ b/pkg/kubelet/dockertools/docker_manager_test.go @@ -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() diff --git a/pkg/kubelet/dockertools/docker_test.go b/pkg/kubelet/dockertools/docker_test.go index 7af13252226..28da5977794 100644 --- a/pkg/kubelet/dockertools/docker_test.go +++ b/pkg/kubelet/dockertools/docker_test.go @@ -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) } diff --git a/pkg/kubelet/dockertools/fake_docker_client.go b/pkg/kubelet/dockertools/fake_docker_client.go index e26b4c2a084..d5e612a18e2 100644 --- a/pkg/kubelet/dockertools/fake_docker_client.go +++ b/pkg/kubelet/dockertools/fake_docker_client.go @@ -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() diff --git a/pkg/kubelet/images/helpers.go b/pkg/kubelet/images/helpers.go index 67a8da94ff3..f7329fba15e 100644 --- a/pkg/kubelet/images/helpers.go +++ b/pkg/kubelet/images/helpers.go @@ -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.") } diff --git a/pkg/kubelet/images/image_manager.go b/pkg/kubelet/images/image_manager.go index b2809f1353a..4c62b0d8c45 100644 --- a/pkg/kubelet/images/image_manager.go +++ b/pkg/kubelet/images/image_manager.go @@ -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, diff --git a/pkg/kubelet/images/image_manager_test.go b/pkg/kubelet/images/image_manager_test.go index e339a7dec59..86ea4577ca9 100644 --- a/pkg/kubelet/images/image_manager_test.go +++ b/pkg/kubelet/images/image_manager_test.go @@ -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) } diff --git a/pkg/kubelet/images/puller.go b/pkg/kubelet/images/puller.go index 5698e4c2664..6beaa1e6b00 100644 --- a/pkg/kubelet/images/puller.go +++ b/pkg/kubelet/images/puller.go @@ -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 = ¶llelImagePuller{}, &serialImagePuller{} @@ -38,9 +43,13 @@ func newParallelImagePuller(imageService kubecontainer.ImageService) imagePuller return ¶llelImagePuller{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, + } } } diff --git a/pkg/kubelet/images/types.go b/pkg/kubelet/images/types.go index 9870088f948..8eaef304afd 100644 --- a/pkg/kubelet/images/types.go +++ b/pkg/kubelet/images/types.go @@ -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 } diff --git a/pkg/kubelet/kuberuntime/instrumented_services.go b/pkg/kubelet/kuberuntime/instrumented_services.go index 2ba2583f666..1a76b0a4d52 100644 --- a/pkg/kubelet/kuberuntime/instrumented_services.go +++ b/pkg/kubelet/kuberuntime/instrumented_services.go @@ -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 { diff --git a/pkg/kubelet/kuberuntime/kuberuntime_container.go b/pkg/kubelet/kuberuntime/kuberuntime_container.go index 73070c113d0..7f9517a1ee7 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_container.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_container.go @@ -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, diff --git a/pkg/kubelet/kuberuntime/kuberuntime_image.go b/pkg/kubelet/kuberuntime/kuberuntime_image.go index 672ac108dc8..51f29dffdd1 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_image.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_image.go @@ -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. diff --git a/pkg/kubelet/kuberuntime/kuberuntime_image_test.go b/pkg/kubelet/kuberuntime/kuberuntime_image_test.go index 9124de9cc9b..b758caeb248 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_image_test.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_image_test.go @@ -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)) diff --git a/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go b/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go index f5c6f75c224..a4837718054 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go @@ -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) diff --git a/pkg/kubelet/remote/remote_image.go b/pkg/kubelet/remote/remote_image.go index b7667dc41bc..31faac8e1d8 100644 --- a/pkg/kubelet/remote/remote_image.go +++ b/pkg/kubelet/remote/remote_image.go @@ -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. diff --git a/pkg/kubelet/rkt/image.go b/pkg/kubelet/rkt/image.go index b16f53bcc05..3a1687b4294 100644 --- a/pkg/kubelet/rkt/image.go +++ b/pkg/kubelet/rkt/image.go @@ -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'. diff --git a/pkg/kubelet/rkt/rkt.go b/pkg/kubelet/rkt/rkt.go index ce797fed97d..3e9c89fde5d 100644 --- a/pkg/kubelet/rkt/rkt.go +++ b/pkg/kubelet/rkt/rkt.go @@ -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 }