Merge pull request #8989 from dmcgowan/add-image-delete-target

Add image delete target
This commit is contained in:
Akihiro Suda 2023-10-05 10:53:57 -07:00 committed by GitHub
commit 66aab638da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 221 additions and 94 deletions

View File

@ -4253,6 +4253,19 @@ file {
type: TYPE_BOOL type: TYPE_BOOL
json_name: "sync" json_name: "sync"
} }
field {
name: "target"
number: 3
label: LABEL_OPTIONAL
type: TYPE_MESSAGE
type_name: ".containerd.types.Descriptor"
oneof_index: 0
json_name: "target"
proto3_optional: true
}
oneof_decl {
name: "_target"
}
} }
service { service {
name: "Images" name: "Images"

View File

@ -555,6 +555,11 @@ type DeleteImageRequest struct {
// //
// Default is false // Default is false
Sync bool `protobuf:"varint,2,opt,name=sync,proto3" json:"sync,omitempty"` Sync bool `protobuf:"varint,2,opt,name=sync,proto3" json:"sync,omitempty"`
// Target value for image to be deleted
//
// If image descriptor does not match the same digest,
// the delete operation will return "not found" error.
Target *types.Descriptor `protobuf:"bytes,3,opt,name=target,proto3,oneof" json:"target,omitempty"`
} }
func (x *DeleteImageRequest) Reset() { func (x *DeleteImageRequest) Reset() {
@ -603,6 +608,13 @@ func (x *DeleteImageRequest) GetSync() bool {
return false return false
} }
func (x *DeleteImageRequest) GetTarget() *types.Descriptor {
if x != nil {
return x.Target
}
return nil
}
var File_github_com_containerd_containerd_api_services_images_v1_images_proto protoreflect.FileDescriptor var File_github_com_containerd_containerd_api_services_images_v1_images_proto protoreflect.FileDescriptor
var file_github_com_containerd_containerd_api_services_images_v1_images_proto_rawDesc = []byte{ var file_github_com_containerd_containerd_api_services_images_v1_images_proto_rawDesc = []byte{
@ -692,49 +704,53 @@ var file_github_com_containerd_containerd_api_services_images_v1_images_proto_ra
0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x69, 0x6d, 0x61, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x69, 0x6d, 0x61,
0x67, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x06, 0x69, 0x6d, 0x67, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x06, 0x69, 0x6d,
0x61, 0x67, 0x65, 0x73, 0x22, 0x3c, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x22, 0x82, 0x01, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49,
0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e,
0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
0x0a, 0x04, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x73, 0x79, 0x12, 0x0a, 0x04, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x73,
0x6e, 0x63, 0x32, 0x94, 0x04, 0x0a, 0x06, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x12, 0x66, 0x0a, 0x79, 0x6e, 0x63, 0x12, 0x39, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20,
0x03, 0x47, 0x65, 0x74, 0x12, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64,
0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f,
0x72, 0x48, 0x00, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x88, 0x01, 0x01, 0x42, 0x09,
0x0a, 0x07, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x32, 0x94, 0x04, 0x0a, 0x06, 0x49, 0x6d,
0x61, 0x67, 0x65, 0x73, 0x12, 0x66, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x2e, 0x2e, 0x63, 0x6f,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x73, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49,
0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x63, 0x6f,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x73, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49,
0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6b, 0x0a, 0x04,
0x4c, 0x69, 0x73, 0x74, 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65,
0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x52,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x69, 0x6d, 0x61,
0x67, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65,
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x06, 0x43, 0x72, 0x65,
0x61, 0x74, 0x65, 0x12, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64,
0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73,
0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x69, 0x6d, 0x61,
0x67, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x61,
0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x06, 0x55, 0x70,
0x64, 0x61, 0x74, 0x65, 0x12, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65,
0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6b, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x30, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69,
0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x69, 0x6d,
0x63, 0x65, 0x73, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6d,
0x73, 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x06, 0x44,
0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x69, 0x6d, 0x61, 0x67,
0x4c, 0x69, 0x73, 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6d, 0x61, 0x67,
0x73, 0x65, 0x12, 0x6f, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x31, 0x2e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
0x65, 0x73, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63,
0x61, 0x74, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69,
0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x2f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x69, 0x6d, 0x61, 0x67,
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x31, 0x2e,
0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x73, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70,
0x64, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65,
0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x76, 0x31,
0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x31,
0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76,
0x69, 0x63, 0x65, 0x73, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44,
0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74,
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x61, 0x70,
0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6d, 0x61, 0x67, 0x65,
0x73, 0x2f, 0x76, 0x31, 0x3b, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x33,
} }
var ( var (
@ -781,21 +797,22 @@ var file_github_com_containerd_containerd_api_services_images_v1_images_proto_de
12, // 10: containerd.services.images.v1.UpdateImageRequest.source_date_epoch:type_name -> google.protobuf.Timestamp 12, // 10: containerd.services.images.v1.UpdateImageRequest.source_date_epoch:type_name -> google.protobuf.Timestamp
0, // 11: containerd.services.images.v1.UpdateImageResponse.image:type_name -> containerd.services.images.v1.Image 0, // 11: containerd.services.images.v1.UpdateImageResponse.image:type_name -> containerd.services.images.v1.Image
0, // 12: containerd.services.images.v1.ListImagesResponse.images:type_name -> containerd.services.images.v1.Image 0, // 12: containerd.services.images.v1.ListImagesResponse.images:type_name -> containerd.services.images.v1.Image
1, // 13: containerd.services.images.v1.Images.Get:input_type -> containerd.services.images.v1.GetImageRequest 11, // 13: containerd.services.images.v1.DeleteImageRequest.target:type_name -> containerd.types.Descriptor
7, // 14: containerd.services.images.v1.Images.List:input_type -> containerd.services.images.v1.ListImagesRequest 1, // 14: containerd.services.images.v1.Images.Get:input_type -> containerd.services.images.v1.GetImageRequest
3, // 15: containerd.services.images.v1.Images.Create:input_type -> containerd.services.images.v1.CreateImageRequest 7, // 15: containerd.services.images.v1.Images.List:input_type -> containerd.services.images.v1.ListImagesRequest
5, // 16: containerd.services.images.v1.Images.Update:input_type -> containerd.services.images.v1.UpdateImageRequest 3, // 16: containerd.services.images.v1.Images.Create:input_type -> containerd.services.images.v1.CreateImageRequest
9, // 17: containerd.services.images.v1.Images.Delete:input_type -> containerd.services.images.v1.DeleteImageRequest 5, // 17: containerd.services.images.v1.Images.Update:input_type -> containerd.services.images.v1.UpdateImageRequest
2, // 18: containerd.services.images.v1.Images.Get:output_type -> containerd.services.images.v1.GetImageResponse 9, // 18: containerd.services.images.v1.Images.Delete:input_type -> containerd.services.images.v1.DeleteImageRequest
8, // 19: containerd.services.images.v1.Images.List:output_type -> containerd.services.images.v1.ListImagesResponse 2, // 19: containerd.services.images.v1.Images.Get:output_type -> containerd.services.images.v1.GetImageResponse
4, // 20: containerd.services.images.v1.Images.Create:output_type -> containerd.services.images.v1.CreateImageResponse 8, // 20: containerd.services.images.v1.Images.List:output_type -> containerd.services.images.v1.ListImagesResponse
6, // 21: containerd.services.images.v1.Images.Update:output_type -> containerd.services.images.v1.UpdateImageResponse 4, // 21: containerd.services.images.v1.Images.Create:output_type -> containerd.services.images.v1.CreateImageResponse
14, // 22: containerd.services.images.v1.Images.Delete:output_type -> google.protobuf.Empty 6, // 22: containerd.services.images.v1.Images.Update:output_type -> containerd.services.images.v1.UpdateImageResponse
18, // [18:23] is the sub-list for method output_type 14, // 23: containerd.services.images.v1.Images.Delete:output_type -> google.protobuf.Empty
13, // [13:18] is the sub-list for method input_type 19, // [19:24] is the sub-list for method output_type
13, // [13:13] is the sub-list for extension type_name 14, // [14:19] is the sub-list for method input_type
13, // [13:13] is the sub-list for extension extendee 14, // [14:14] is the sub-list for extension type_name
0, // [0:13] is the sub-list for field type_name 14, // [14:14] is the sub-list for extension extendee
0, // [0:14] is the sub-list for field type_name
} }
func init() { file_github_com_containerd_containerd_api_services_images_v1_images_proto_init() } func init() { file_github_com_containerd_containerd_api_services_images_v1_images_proto_init() }
@ -925,6 +942,7 @@ func file_github_com_containerd_containerd_api_services_images_v1_images_proto_i
} }
} }
} }
file_github_com_containerd_containerd_api_services_images_v1_images_proto_msgTypes[9].OneofWrappers = []interface{}{}
type x struct{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{

View File

@ -140,4 +140,10 @@ message DeleteImageRequest {
// //
// Default is false // Default is false
bool sync = 2; bool sync = 2;
// Target value for image to be deleted
//
// If image descriptor does not match the same digest,
// the delete operation will return "not found" error.
optional containerd.types.Descriptor target = 3;
} }

View File

@ -20,14 +20,12 @@ import (
"context" "context"
imagesapi "github.com/containerd/containerd/api/services/images/v1" imagesapi "github.com/containerd/containerd/api/services/images/v1"
"github.com/containerd/containerd/api/types"
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/images" "github.com/containerd/containerd/images"
"github.com/containerd/containerd/oci"
"github.com/containerd/containerd/pkg/epoch" "github.com/containerd/containerd/pkg/epoch"
"github.com/containerd/containerd/protobuf" "github.com/containerd/containerd/protobuf"
ptypes "github.com/containerd/containerd/protobuf/types" ptypes "github.com/containerd/containerd/protobuf/types"
"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"google.golang.org/protobuf/types/known/timestamppb" "google.golang.org/protobuf/types/known/timestamppb"
) )
@ -108,11 +106,14 @@ func (s *remoteImages) Delete(ctx context.Context, name string, opts ...images.D
return err return err
} }
} }
_, err := s.client.Delete(ctx, &imagesapi.DeleteImageRequest{ req := &imagesapi.DeleteImageRequest{
Name: name, Name: name,
Sync: do.Synchronous, Sync: do.Synchronous,
}) }
if do.Target != nil {
req.Target = oci.DescriptorToProto(*do.Target)
}
_, err := s.client.Delete(ctx, req)
return errdefs.FromGRPC(err) return errdefs.FromGRPC(err)
} }
@ -120,7 +121,7 @@ func imageToProto(image *images.Image) *imagesapi.Image {
return &imagesapi.Image{ return &imagesapi.Image{
Name: image.Name, Name: image.Name,
Labels: image.Labels, Labels: image.Labels,
Target: descToProto(&image.Target), Target: oci.DescriptorToProto(image.Target),
CreatedAt: protobuf.ToTimestamp(image.CreatedAt), CreatedAt: protobuf.ToTimestamp(image.CreatedAt),
UpdatedAt: protobuf.ToTimestamp(image.UpdatedAt), UpdatedAt: protobuf.ToTimestamp(image.UpdatedAt),
} }
@ -130,7 +131,7 @@ func imageFromProto(imagepb *imagesapi.Image) images.Image {
return images.Image{ return images.Image{
Name: imagepb.Name, Name: imagepb.Name,
Labels: imagepb.Labels, Labels: imagepb.Labels,
Target: descFromProto(imagepb.Target), Target: oci.DescriptorFromProto(imagepb.Target),
CreatedAt: protobuf.FromTimestamp(imagepb.CreatedAt), CreatedAt: protobuf.FromTimestamp(imagepb.CreatedAt),
UpdatedAt: protobuf.FromTimestamp(imagepb.UpdatedAt), UpdatedAt: protobuf.FromTimestamp(imagepb.UpdatedAt),
} }
@ -146,21 +147,3 @@ func imagesFromProto(imagespb []*imagesapi.Image) []images.Image {
return images return images
} }
func descFromProto(desc *types.Descriptor) ocispec.Descriptor {
return ocispec.Descriptor{
MediaType: desc.MediaType,
Size: desc.Size,
Digest: digest.Digest(desc.Digest),
Annotations: desc.Annotations,
}
}
func descToProto(desc *ocispec.Descriptor) *types.Descriptor {
return &types.Descriptor{
MediaType: desc.MediaType,
Size: desc.Size,
Digest: desc.Digest.String(),
Annotations: desc.Annotations,
}
}

View File

@ -58,6 +58,7 @@ type Image struct {
// DeleteOptions provide options on image delete // DeleteOptions provide options on image delete
type DeleteOptions struct { type DeleteOptions struct {
Synchronous bool Synchronous bool
Target *ocispec.Descriptor
} }
// DeleteOpt allows configuring a delete operation // DeleteOpt allows configuring a delete operation
@ -72,6 +73,16 @@ func SynchronousDelete() DeleteOpt {
} }
} }
// DeleteTarget is used to specify the target value an image is expected
// to have when deleting. If the image has a different target, then
// NotFound is returned.
func DeleteTarget(target *ocispec.Descriptor) DeleteOpt {
return func(ctx context.Context, o *DeleteOptions) error {
o.Target = target
return nil
}
}
// Store and interact with images // Store and interact with images
type Store interface { type Store interface {
Get(ctx context.Context, name string) (Image, error) Get(ctx context.Context, name string) (Image, error)

View File

@ -266,6 +266,13 @@ func (s *imageStore) Delete(ctx context.Context, name string, opts ...images.Del
return err return err
} }
var options images.DeleteOptions
for _, opt := range opts {
if err := opt(ctx, &options); err != nil {
return err
}
}
return update(ctx, s.db, func(tx *bolt.Tx) error { return update(ctx, s.db, func(tx *bolt.Tx) error {
bkt := getImagesBucket(tx, namespace) bkt := getImagesBucket(tx, namespace)
if bkt == nil { if bkt == nil {
@ -276,6 +283,22 @@ func (s *imageStore) Delete(ctx context.Context, name string, opts ...images.Del
return err return err
} }
if options.Target != nil && options.Target.Digest != "" {
ibkt := bkt.Bucket([]byte(name))
if ibkt == nil {
return fmt.Errorf("image %q: %w", name, errdefs.ErrNotFound)
}
var check images.Image
if err := readImage(&check, ibkt); err != nil {
return fmt.Errorf("image %q: %w", name, err)
}
if check.Target.Digest != options.Target.Digest {
return fmt.Errorf("image %q has target %v, not %v: %w", name, check.Target.Digest, options.Target.Digest, errdefs.ErrNotFound)
}
}
if err = bkt.DeleteBucket([]byte(name)); err != nil { if err = bkt.DeleteBucket([]byte(name)); err != nil {
if err == bolt.ErrBucketNotFound { if err == bolt.ErrBucketNotFound {
err = fmt.Errorf("image %q: %w", name, errdefs.ErrNotFound) err = fmt.Errorf("image %q: %w", name, errdefs.ErrNotFound)

View File

@ -154,10 +154,11 @@ func TestImagesCreateUpdateDelete(t *testing.T) {
name string name string
original images.Image original images.Image
createerr error createerr error
input images.Image input images.Image // Input target size determines target digest, base image uses 10
fieldpaths []string fieldpaths []string
expected images.Image expected images.Image
cause error cause error
deleteerr error
}{ }{
{ {
name: "Touch", name: "Touch",
@ -239,7 +240,7 @@ func TestImagesCreateUpdateDelete(t *testing.T) {
"boo": "boo", "boo": "boo",
}, },
Target: ocispec.Descriptor{ Target: ocispec.Descriptor{
Size: 20, // ignored Size: 10,
MediaType: "application/vnd.oci.blab+ignored", // make sure other stuff is ignored MediaType: "application/vnd.oci.blab+ignored", // make sure other stuff is ignored
Annotations: map[string]string{ Annotations: map[string]string{
"not": "bar", "not": "bar",
@ -272,7 +273,7 @@ func TestImagesCreateUpdateDelete(t *testing.T) {
"boo": "boo", "boo": "boo",
}, },
Target: ocispec.Descriptor{ Target: ocispec.Descriptor{
Size: 20, // ignored Size: 10,
MediaType: "application/vnd.oci.blab+ignored", // make sure other stuff is ignored MediaType: "application/vnd.oci.blab+ignored", // make sure other stuff is ignored
Annotations: map[string]string{ Annotations: map[string]string{
"foo": "boo", "foo": "boo",
@ -303,7 +304,7 @@ func TestImagesCreateUpdateDelete(t *testing.T) {
"baz": "bunk", "baz": "bunk",
}, },
Target: ocispec.Descriptor{ Target: ocispec.Descriptor{
Size: 20, // ignored Size: 10,
MediaType: "application/vnd.oci.blab+ignored", // make sure other stuff is ignored MediaType: "application/vnd.oci.blab+ignored", // make sure other stuff is ignored
Annotations: map[string]string{ Annotations: map[string]string{
"foo": "bar", "foo": "bar",
@ -335,7 +336,7 @@ func TestImagesCreateUpdateDelete(t *testing.T) {
"baz": "bunk", "baz": "bunk",
}, },
Target: ocispec.Descriptor{ Target: ocispec.Descriptor{
Size: 20, // ignored Size: 10,
MediaType: "application/vnd.oci.blab+ignored", // make sure other stuff is ignored MediaType: "application/vnd.oci.blab+ignored", // make sure other stuff is ignored
Annotations: map[string]string{ Annotations: map[string]string{
"foo": "baz", "foo": "baz",
@ -360,7 +361,7 @@ func TestImagesCreateUpdateDelete(t *testing.T) {
}, },
}, },
{ {
name: "ReplaceTarget", // target must be updated as a unit name: "ReplaceTargetTypeAndAnnotations", // target must be updated as a unit
original: imageBase(), original: imageBase(),
input: images.Image{ input: images.Image{
Target: ocispec.Descriptor{ Target: ocispec.Descriptor{
@ -386,6 +387,57 @@ func TestImagesCreateUpdateDelete(t *testing.T) {
}, },
}, },
}, },
{
name: "ReplaceTargetFieldpath", // target must be updated as a unit
original: imageBase(),
input: images.Image{
Target: ocispec.Descriptor{
Size: 20,
MediaType: "application/vnd.oci.blab+replaced",
Annotations: map[string]string{
"fox": "dog",
},
},
},
fieldpaths: []string{"target"},
expected: images.Image{
Labels: map[string]string{ // Labels not updated
"foo": "bar",
"baz": "boo",
},
Target: ocispec.Descriptor{
Size: 20,
MediaType: "application/vnd.oci.blab+replaced",
Annotations: map[string]string{
"fox": "dog",
},
},
},
deleteerr: errdefs.ErrNotFound,
},
{
name: "ReplaceTarget", // target must be updated as a unit
original: imageBase(),
input: images.Image{
Target: ocispec.Descriptor{
Size: 20,
MediaType: "application/vnd.oci.blab+replaced",
Annotations: map[string]string{
"fox": "dog",
},
},
},
expected: images.Image{
Target: ocispec.Descriptor{
Size: 20,
MediaType: "application/vnd.oci.blab+replaced",
Annotations: map[string]string{
"fox": "dog",
},
},
},
deleteerr: errdefs.ErrNotFound,
},
{ {
name: "EmptySize", name: "EmptySize",
original: imageBase(), original: imageBase(),
@ -487,11 +539,9 @@ func TestImagesCreateUpdateDelete(t *testing.T) {
} }
testcase.expected.Name = testcase.name testcase.expected.Name = testcase.name
if testcase.original.Target.Digest == "" { testcase.original.Target.Digest = digest.FromString(fmt.Sprintf("%s-%d", testcase.name, testcase.original.Target.Size))
testcase.original.Target.Digest = digest.FromString(testcase.name) testcase.input.Target.Digest = digest.FromString(fmt.Sprintf("%s-%d", testcase.name, testcase.input.Target.Size))
testcase.input.Target.Digest = testcase.original.Target.Digest testcase.expected.Target.Digest = testcase.input.Target.Digest
testcase.expected.Target.Digest = testcase.original.Target.Digest
}
// Create // Create
now := time.Now() now := time.Now()
@ -539,6 +589,22 @@ func TestImagesCreateUpdateDelete(t *testing.T) {
} }
checkImagesEqual(t, &result, &testcase.expected, "get after failed to get expected result") checkImagesEqual(t, &result, &testcase.expected, "get after failed to get expected result")
if testcase.original.Target.Digest != testcase.expected.Target.Digest {
t.Log("Delete should fail")
}
// Delete
err = store.Delete(ctx, testcase.original.Name, images.DeleteTarget(&testcase.original.Target))
if err != nil {
if testcase.deleteerr == nil {
t.Fatal(err)
}
if !errors.Is(err, testcase.deleteerr) {
t.Fatal("unexpected error", err, ", expected", testcase.deleteerr)
}
} else if testcase.deleteerr != nil {
t.Fatal("no error on deleted, expected", testcase.deleteerr)
}
}) })
} }
} }

View File

@ -176,7 +176,14 @@ func (l *local) Update(ctx context.Context, req *imagesapi.UpdateImageRequest, _
func (l *local) Delete(ctx context.Context, req *imagesapi.DeleteImageRequest, _ ...grpc.CallOption) (*ptypes.Empty, error) { func (l *local) Delete(ctx context.Context, req *imagesapi.DeleteImageRequest, _ ...grpc.CallOption) (*ptypes.Empty, error) {
log.G(ctx).WithField("name", req.Name).Debugf("delete image") log.G(ctx).WithField("name", req.Name).Debugf("delete image")
if err := l.store.Delete(ctx, req.Name); err != nil { var opts []images.DeleteOpt
if req.Target != nil {
desc := descFromProto(req.Target)
opts = append(opts, images.DeleteTarget(&desc))
}
// Sync option handled here after event is published
if err := l.store.Delete(ctx, req.Name, opts...); err != nil {
return nil, errdefs.ToGRPC(err) return nil, errdefs.ToGRPC(err)
} }