diff --git a/client/apis/volumegroupsnapshot/v1alpha1/types.go b/client/apis/volumegroupsnapshot/v1alpha1/types.go index 4110c2929..6684cbac7 100644 --- a/client/apis/volumegroupsnapshot/v1alpha1/types.go +++ b/client/apis/volumegroupsnapshot/v1alpha1/types.go @@ -109,11 +109,20 @@ type VolumeGroupSnapshotStatus struct { // +optional Error *snapshotv1.VolumeSnapshotError `json:"error,omitempty" protobuf:"bytes,4,opt,name=error,casttype=VolumeSnapshotError"` - // VolumeSnapshotRefList is the list of volume snapshot references for this - // group snapshot. + // VolumeSnapshotRefList is the list of PVC and VolumeSnapshot pairs that + // is part of this group snapshot. // The maximum number of allowed snapshots in the group is 100. // +optional - VolumeSnapshotRefList []core_v1.ObjectReference `json:"volumeSnapshotRefList,omitempty" protobuf:"bytes,5,opt,name=volumeSnapshotRefList"` + PVCVolumeSnapshotRefList []PVCVolumeSnapshotPair `json:"pvcVolumeSnapshotRefList,omitempty" protobuf:"bytes,5,opt,name=pvcVolumeSnapshotRefList"` +} + +// PVCVolumeSnapshotPair defines a pair of a PVC reference and a Volume Snapshot Reference +type PVCVolumeSnapshotPair struct { + // PersistentVolumeClaimRef is a reference to the PVC this pair is referring to + PersistentVolumeClaimRef core_v1.LocalObjectReference `json:"persistentVolumeClaimRef,omitempty" protobuf:"bytes,1,opt,name=persistentVolumeClaimRef"` + + // VolumeSnapshotRef is a reference to the VolumeSnapshot this pair is referring to + VolumeSnapshotRef core_v1.LocalObjectReference `json:"volumeSnapshotRef,omitempty" protobuf:"bytes,2,opt,name=volumeSnapshotRef"` } //+genclient @@ -345,11 +354,21 @@ type VolumeGroupSnapshotContentStatus struct { // +optional Error *snapshotv1.VolumeSnapshotError `json:"error,omitempty" protobuf:"bytes,4,opt,name=error,casttype=VolumeSnapshotError"` - // VolumeSnapshotContentRefList is the list of volume snapshot content references - // for this group snapshot. + // PVVolumeSnapshotContentList is the list of pairs of PV and + // VolumeSnapshotContent for this group snapshot // The maximum number of allowed snapshots in the group is 100. // +optional - VolumeSnapshotContentRefList []core_v1.ObjectReference `json:"volumeSnapshotContentRefList,omitempty" protobuf:"bytes,5,opt,name=volumeSnapshotContentRefList"` + PVVolumeSnapshotContentList []PVVolumeSnapshotContentPair `json:"pvVolumeSnapshotContentList,omitempty" protobuf:"bytes,5,opt,name=pvVolumeSnapshotContentRefList"` +} + +// PVVolumeSnapshotContentPair represent a pair of PV names and +// VolumeSnapshotContent names +type PVVolumeSnapshotContentPair struct { + // PersistentVolumeRef is a reference to the persistent volume resource + PersistentVolumeRef core_v1.LocalObjectReference `json:"persistentVolumeRef,omitempty" protobuf:"bytes,1,opt,name=persistentVolumeRef"` + + // VolumeSnapshotContentRef is a reference to the volume snapshot content resource + VolumeSnapshotContentRef core_v1.LocalObjectReference `json:"volumeSnapshotContentRef,omitempty" protobuf:"bytes,2,opt,name=volumeSnapshotContentRef"` } // VolumeGroupSnapshotContentSource represents the CSI source of a group snapshot. diff --git a/client/apis/volumegroupsnapshot/v1alpha1/zz_generated.deepcopy.go b/client/apis/volumegroupsnapshot/v1alpha1/zz_generated.deepcopy.go index 820cbb91a..81bdf47cd 100644 --- a/client/apis/volumegroupsnapshot/v1alpha1/zz_generated.deepcopy.go +++ b/client/apis/volumegroupsnapshot/v1alpha1/zz_generated.deepcopy.go @@ -23,7 +23,6 @@ package v1alpha1 import ( v1 "github.com/kubernetes-csi/external-snapshotter/client/v7/apis/volumesnapshot/v1" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -49,6 +48,42 @@ func (in *GroupSnapshotHandles) DeepCopy() *GroupSnapshotHandles { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PVCVolumeSnapshotPair) DeepCopyInto(out *PVCVolumeSnapshotPair) { + *out = *in + out.PersistentVolumeClaimRef = in.PersistentVolumeClaimRef + out.VolumeSnapshotRef = in.VolumeSnapshotRef + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PVCVolumeSnapshotPair. +func (in *PVCVolumeSnapshotPair) DeepCopy() *PVCVolumeSnapshotPair { + if in == nil { + return nil + } + out := new(PVCVolumeSnapshotPair) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PVVolumeSnapshotContentPair) DeepCopyInto(out *PVVolumeSnapshotContentPair) { + *out = *in + out.PersistentVolumeRef = in.PersistentVolumeRef + out.VolumeSnapshotContentRef = in.VolumeSnapshotContentRef + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PVVolumeSnapshotContentPair. +func (in *PVVolumeSnapshotContentPair) DeepCopy() *PVVolumeSnapshotContentPair { + if in == nil { + return nil + } + out := new(PVVolumeSnapshotContentPair) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VolumeGroupSnapshot) DeepCopyInto(out *VolumeGroupSnapshot) { *out = *in @@ -284,9 +319,9 @@ func (in *VolumeGroupSnapshotContentStatus) DeepCopyInto(out *VolumeGroupSnapsho *out = new(v1.VolumeSnapshotError) (*in).DeepCopyInto(*out) } - if in.VolumeSnapshotContentRefList != nil { - in, out := &in.VolumeSnapshotContentRefList, &out.VolumeSnapshotContentRefList - *out = make([]corev1.ObjectReference, len(*in)) + if in.PVVolumeSnapshotContentList != nil { + in, out := &in.PVVolumeSnapshotContentList, &out.PVVolumeSnapshotContentList + *out = make([]PVVolumeSnapshotContentPair, len(*in)) copy(*out, *in) } return @@ -405,9 +440,9 @@ func (in *VolumeGroupSnapshotStatus) DeepCopyInto(out *VolumeGroupSnapshotStatus *out = new(v1.VolumeSnapshotError) (*in).DeepCopyInto(*out) } - if in.VolumeSnapshotRefList != nil { - in, out := &in.VolumeSnapshotRefList, &out.VolumeSnapshotRefList - *out = make([]corev1.ObjectReference, len(*in)) + if in.PVCVolumeSnapshotRefList != nil { + in, out := &in.PVCVolumeSnapshotRefList, &out.PVCVolumeSnapshotRefList + *out = make([]PVCVolumeSnapshotPair, len(*in)) copy(*out, *in) } return diff --git a/client/config/crd/groupsnapshot.storage.k8s.io_volumegroupsnapshotcontents.yaml b/client/config/crd/groupsnapshot.storage.k8s.io_volumegroupsnapshotcontents.yaml index 62bf3df68..28584e56b 100644 --- a/client/config/crd/groupsnapshot.storage.k8s.io_volumegroupsnapshotcontents.yaml +++ b/client/config/crd/groupsnapshot.storage.k8s.io_volumegroupsnapshotcontents.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/971" + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/1068" controller-gen.kubebuilder.io/version: v0.15.0 name: volumegroupsnapshotcontents.groupsnapshot.storage.k8s.io spec: @@ -276,6 +276,42 @@ spec: format: date-time type: string type: object + pvVolumeSnapshotContentList: + description: |- + PVVolumeSnapshotContentList is the list of pairs of PV and + VolumeSnapshotContent for this group snapshot + The maximum number of allowed snapshots in the group is 100. + items: + description: |- + PVVolumeSnapshotContentPair represent a pair of PV names and + VolumeSnapshotContent names + properties: + persistentVolumeRef: + description: PersistentVolumeRef is a reference to the persistent + volume resource + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + volumeSnapshotContentRef: + description: VolumeSnapshotContentRef is a reference to the + volume snapshot content resource + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + type: object + type: array readyToUse: description: |- ReadyToUse indicates if all the individual snapshots in the group are ready to be @@ -289,73 +325,6 @@ spec: If a storage system does not provide such an id, the CSI driver can choose to return the VolumeGroupSnapshot name. type: string - volumeSnapshotContentRefList: - description: |- - VolumeSnapshotContentRefList is the list of volume snapshot content references - for this group snapshot. - The maximum number of allowed snapshots in the group is 100. - items: - description: |- - ObjectReference contains enough information to let you inspect or modify the referred object. - --- - New uses of this type are discouraged because of difficulty describing its usage when embedded in APIs. - 1. Ignored fields. It includes many fields which are not generally honored. For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage. - 2. Invalid usage help. It is impossible to add specific help for individual usage. In most embedded usages, there are particular - restrictions like, "must refer only to types A and B" or "UID not honored" or "name must be restricted". - Those cannot be well described when embedded. - 3. Inconsistent validation. Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen. - 4. The fields are both imprecise and overly precise. Kind is not a precise mapping to a URL. This can produce ambiguity - during interpretation and require a REST mapping. In most cases, the dependency is on the group,resource tuple - and the version of the actual struct is irrelevant. - 5. We cannot easily change it. Because this type is embedded in many locations, updates to this type - will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control. - - - Instead of using this type, create a locally provided and used type that is well-focused on your reference. - For example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 . - properties: - apiVersion: - description: API version of the referent. - type: string - fieldPath: - description: |- - If referring to a piece of an object instead of an entire object, this string - should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. - For example, if the object reference is to a container within a pod, this would take on a value like: - "spec.containers{name}" (where "name" refers to the name of the container that triggered - the event) or if no container name is specified "spec.containers[2]" (container with - index 2 in this pod). This syntax is chosen only to have some well-defined way of - referencing a part of an object. - TODO: this design is not final and this field is subject to change in the future. - type: string - kind: - description: |- - Kind of the referent. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - namespace: - description: |- - Namespace of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ - type: string - resourceVersion: - description: |- - Specific resourceVersion to which this reference is made, if any. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency - type: string - uid: - description: |- - UID of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids - type: string - type: object - x-kubernetes-map-type: atomic - type: array type: object required: - spec diff --git a/client/config/crd/groupsnapshot.storage.k8s.io_volumegroupsnapshots.yaml b/client/config/crd/groupsnapshot.storage.k8s.io_volumegroupsnapshots.yaml index 63808011e..3d9a771de 100644 --- a/client/config/crd/groupsnapshot.storage.k8s.io_volumegroupsnapshots.yaml +++ b/client/config/crd/groupsnapshot.storage.k8s.io_volumegroupsnapshots.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/995" + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/1068" controller-gen.kubebuilder.io/version: v0.15.0 name: volumegroupsnapshots.groupsnapshot.storage.k8s.io spec: @@ -221,6 +221,41 @@ spec: format: date-time type: string type: object + pvcVolumeSnapshotRefList: + description: |- + VolumeSnapshotRefList is the list of PVC and VolumeSnapshot pairs that + is part of this group snapshot. + The maximum number of allowed snapshots in the group is 100. + items: + description: PVCVolumeSnapshotPair defines a pair of a PVC reference + and a Volume Snapshot Reference + properties: + persistentVolumeClaimRef: + description: PersistentVolumeClaimRef is a reference to the + PVC this pair is referring to + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + volumeSnapshotRef: + description: VolumeSnapshotRef is a reference to the VolumeSnapshot + this pair is referring to + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + type: object + type: array readyToUse: description: |- ReadyToUse indicates if all the individual snapshots in the group are ready @@ -228,73 +263,6 @@ spec: ReadyToUse becomes true when ReadyToUse of all individual snapshots become true. If not specified, it means the readiness of a group snapshot is unknown. type: boolean - volumeSnapshotRefList: - description: |- - VolumeSnapshotRefList is the list of volume snapshot references for this - group snapshot. - The maximum number of allowed snapshots in the group is 100. - items: - description: |- - ObjectReference contains enough information to let you inspect or modify the referred object. - --- - New uses of this type are discouraged because of difficulty describing its usage when embedded in APIs. - 1. Ignored fields. It includes many fields which are not generally honored. For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage. - 2. Invalid usage help. It is impossible to add specific help for individual usage. In most embedded usages, there are particular - restrictions like, "must refer only to types A and B" or "UID not honored" or "name must be restricted". - Those cannot be well described when embedded. - 3. Inconsistent validation. Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen. - 4. The fields are both imprecise and overly precise. Kind is not a precise mapping to a URL. This can produce ambiguity - during interpretation and require a REST mapping. In most cases, the dependency is on the group,resource tuple - and the version of the actual struct is irrelevant. - 5. We cannot easily change it. Because this type is embedded in many locations, updates to this type - will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control. - - - Instead of using this type, create a locally provided and used type that is well-focused on your reference. - For example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 . - properties: - apiVersion: - description: API version of the referent. - type: string - fieldPath: - description: |- - If referring to a piece of an object instead of an entire object, this string - should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. - For example, if the object reference is to a container within a pod, this would take on a value like: - "spec.containers{name}" (where "name" refers to the name of the container that triggered - the event) or if no container name is specified "spec.containers[2]" (container with - index 2 in this pod). This syntax is chosen only to have some well-defined way of - referencing a part of an object. - TODO: this design is not final and this field is subject to change in the future. - type: string - kind: - description: |- - Kind of the referent. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - namespace: - description: |- - Namespace of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ - type: string - resourceVersion: - description: |- - Specific resourceVersion to which this reference is made, if any. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency - type: string - uid: - description: |- - UID of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids - type: string - type: object - x-kubernetes-map-type: atomic - type: array type: object required: - spec diff --git a/pkg/common-controller/groupsnapshot_controller_helper.go b/pkg/common-controller/groupsnapshot_controller_helper.go index 81e56fc0e..c66ff4814 100644 --- a/pkg/common-controller/groupsnapshot_controller_helper.go +++ b/pkg/common-controller/groupsnapshot_controller_helper.go @@ -315,7 +315,7 @@ func (ctrl *csiSnapshotCommonController) syncGroupSnapshot(groupSnapshot *crdv1a // 2) groupSnapshot.Status.ReadyToUse is false // 3) groupSnapshot.Status.IsBoundVolumeGroupSnapshotContentNameSet is not set // 4) groupSnapshot.Status.IsVolumeSnapshotRefListSet is not set - if !utils.IsGroupSnapshotReady(groupSnapshot) || !utils.IsBoundVolumeGroupSnapshotContentNameSet(groupSnapshot) || !utils.IsVolumeSnapshotRefListSet(groupSnapshot) { + if !utils.IsGroupSnapshotReady(groupSnapshot) || !utils.IsBoundVolumeGroupSnapshotContentNameSet(groupSnapshot) || !utils.IsPVCVolumeSnapshotRefListSet(groupSnapshot) { return ctrl.syncUnreadyGroupSnapshot(groupSnapshot) } return ctrl.syncReadyGroupSnapshot(groupSnapshot) @@ -564,14 +564,18 @@ func (ctrl *csiSnapshotCommonController) updateGroupSnapshotStatus(groupSnapshot volumeSnapshotErr = groupSnapshotContent.Status.Error.DeepCopy() } - var volumeSnapshotRefList []v1.ObjectReference - if groupSnapshotContent.Status != nil && len(groupSnapshotContent.Status.VolumeSnapshotContentRefList) != 0 { - for _, contentRef := range groupSnapshotContent.Status.VolumeSnapshotContentRefList { - groupSnapshotContent, err := ctrl.contentLister.Get(contentRef.Name) + var pvcVolumeSnapshotRefList []crdv1alpha1.PVCVolumeSnapshotPair + if groupSnapshotContent.Status != nil && len(groupSnapshotContent.Status.PVVolumeSnapshotContentList) != 0 { + for _, contentRef := range groupSnapshotContent.Status.PVVolumeSnapshotContentList { + groupSnapshotContent, err := ctrl.contentLister.Get(contentRef.VolumeSnapshotContentRef.Name) if err != nil { - return nil, fmt.Errorf("failed to get group snapshot content %s from group snapshot content store: %v", contentRef.Name, err) + return nil, fmt.Errorf("failed to get group snapshot content %s from group snapshot content store: %v", contentRef.VolumeSnapshotContentRef.Name, err) } - volumeSnapshotRefList = append(volumeSnapshotRefList, groupSnapshotContent.Spec.VolumeSnapshotRef) + pvcVolumeSnapshotRefList = append(pvcVolumeSnapshotRefList, crdv1alpha1.PVCVolumeSnapshotPair{ + VolumeSnapshotRef: v1.LocalObjectReference{ + Name: groupSnapshotContent.Spec.VolumeSnapshotRef.Name, + }, + }) } } @@ -595,8 +599,8 @@ func (ctrl *csiSnapshotCommonController) updateGroupSnapshotStatus(groupSnapshot if volumeSnapshotErr != nil { newStatus.Error = volumeSnapshotErr } - if len(volumeSnapshotRefList) == 0 { - newStatus.VolumeSnapshotRefList = volumeSnapshotRefList + if len(pvcVolumeSnapshotRefList) == 0 { + newStatus.PVCVolumeSnapshotRefList = pvcVolumeSnapshotRefList } updated = true @@ -621,8 +625,8 @@ func (ctrl *csiSnapshotCommonController) updateGroupSnapshotStatus(groupSnapshot newStatus.Error = volumeSnapshotErr updated = true } - if len(newStatus.VolumeSnapshotRefList) == 0 { - newStatus.VolumeSnapshotRefList = volumeSnapshotRefList + if len(newStatus.PVCVolumeSnapshotRefList) == 0 { + newStatus.PVCVolumeSnapshotRefList = pvcVolumeSnapshotRefList updated = true } } @@ -1137,8 +1141,8 @@ func (ctrl *csiSnapshotCommonController) processGroupSnapshotWithDeletionTimesta // check if an individual snapshot belonging to the group snapshot is being // used for restore a PVC // If yes, do nothing and wait until PVC restoration finishes - for _, snapshotRef := range groupSnapshot.Status.VolumeSnapshotRefList { - snapshot, err := ctrl.snapshotLister.VolumeSnapshots(snapshotRef.Namespace).Get(snapshotRef.Name) + for _, snapshotRef := range groupSnapshot.Status.PVCVolumeSnapshotRefList { + snapshot, err := ctrl.snapshotLister.VolumeSnapshots(groupSnapshot.Namespace).Get(snapshotRef.VolumeSnapshotRef.Name) if err != nil { if apierrs.IsNotFound(err) { continue @@ -1185,10 +1189,10 @@ func (ctrl *csiSnapshotCommonController) processGroupSnapshotWithDeletionTimesta klog.V(5).Infof("processGroupSnapshotWithDeletionTimestamp[%s]: Delete individual snapshots that are part of the group snapshot", utils.GroupSnapshotKey(groupSnapshot)) // Delete the individual snapshots part of the group snapshot - for _, snapshot := range groupSnapshot.Status.VolumeSnapshotRefList { - err := ctrl.clientset.SnapshotV1().VolumeSnapshots(snapshot.Namespace).Delete(context.TODO(), snapshot.Name, metav1.DeleteOptions{}) + for _, snapshot := range groupSnapshot.Status.PVCVolumeSnapshotRefList { + err := ctrl.clientset.SnapshotV1().VolumeSnapshots(groupSnapshot.Namespace).Delete(context.TODO(), snapshot.VolumeSnapshotRef.Name, metav1.DeleteOptions{}) if err != nil && !apierrs.IsNotFound(err) { - msg := fmt.Sprintf("failed to delete snapshot API object %s/%s part of group snapshot %s: %v", snapshot.Namespace, snapshot.Name, utils.GroupSnapshotKey(groupSnapshot), err) + msg := fmt.Sprintf("failed to delete snapshot API object %s/%s part of group snapshot %s: %v", groupSnapshot.Namespace, snapshot.VolumeSnapshotRef.Name, utils.GroupSnapshotKey(groupSnapshot), err) klog.Error(msg) ctrl.eventRecorder.Event(groupSnapshot, v1.EventTypeWarning, "SnapshotDeleteError", msg) return fmt.Errorf(msg) diff --git a/pkg/sidecar-controller/groupsnapshot_helper.go b/pkg/sidecar-controller/groupsnapshot_helper.go index 0414de902..c50bb13e6 100644 --- a/pkg/sidecar-controller/groupsnapshot_helper.go +++ b/pkg/sidecar-controller/groupsnapshot_helper.go @@ -240,11 +240,11 @@ func (ctrl *csiSnapshotSideCarController) deleteCSIGroupSnapshotOperation(groupS } var snapshotIDs []string - if groupSnapshotContent.Status != nil && len(groupSnapshotContent.Status.VolumeSnapshotContentRefList) != 0 { - for _, contentRef := range groupSnapshotContent.Status.VolumeSnapshotContentRefList { - snapshotContent, err := ctrl.contentLister.Get(contentRef.Name) + if groupSnapshotContent.Status != nil && len(groupSnapshotContent.Status.PVVolumeSnapshotContentList) != 0 { + for _, contentRef := range groupSnapshotContent.Status.PVVolumeSnapshotContentList { + snapshotContent, err := ctrl.contentLister.Get(contentRef.VolumeSnapshotContentRef.Name) if err != nil { - return fmt.Errorf("failed to get snapshot content %s from snapshot content store: %v", contentRef.Name, err) + return fmt.Errorf("failed to get snapshot content %s from snapshot content store: %v", contentRef.VolumeSnapshotContentRef.Name, err) } snapshotIDs = append(snapshotIDs, *snapshotContent.Status.SnapshotHandle) } @@ -283,7 +283,7 @@ func (ctrl *csiSnapshotSideCarController) clearGroupSnapshotContentStatus( groupSnapshotContent.Status.ReadyToUse = nil groupSnapshotContent.Status.CreationTime = nil groupSnapshotContent.Status.Error = nil - groupSnapshotContent.Status.VolumeSnapshotContentRefList = nil + groupSnapshotContent.Status.PVVolumeSnapshotContentList = nil } newContent, err := ctrl.clientset.GroupsnapshotV1alpha1().VolumeGroupSnapshotContents().UpdateStatus(context.TODO(), groupSnapshotContent, metav1.UpdateOptions{}) if err != nil { @@ -650,9 +650,10 @@ func (ctrl *csiSnapshotSideCarController) updateGroupSnapshotContentStatus( CreationTime: &createdAt, } for _, name := range snapshotContentNames { - newStatus.VolumeSnapshotContentRefList = append(newStatus.VolumeSnapshotContentRefList, v1.ObjectReference{ - Kind: "VolumeSnapshotContent", - Name: name, + newStatus.PVVolumeSnapshotContentList = append(newStatus.PVVolumeSnapshotContentList, crdv1alpha1.PVVolumeSnapshotContentPair{ + VolumeSnapshotContentRef: v1.LocalObjectReference{ + Name: name, + }, }) } updated = true @@ -673,11 +674,12 @@ func (ctrl *csiSnapshotSideCarController) updateGroupSnapshotContentStatus( newStatus.CreationTime = &createdAt updated = true } - if len(newStatus.VolumeSnapshotContentRefList) == 0 { + if len(newStatus.PVVolumeSnapshotContentList) == 0 { for _, name := range snapshotContentNames { - newStatus.VolumeSnapshotContentRefList = append(newStatus.VolumeSnapshotContentRefList, v1.ObjectReference{ - Kind: "VolumeSnapshotContent", - Name: name, + newStatus.PVVolumeSnapshotContentList = append(newStatus.PVVolumeSnapshotContentList, crdv1alpha1.PVVolumeSnapshotContentPair{ + VolumeSnapshotContentRef: v1.LocalObjectReference{ + Name: name, + }, }) } updated = true diff --git a/pkg/utils/util.go b/pkg/utils/util.go index bea90871e..d893ec983 100644 --- a/pkg/utils/util.go +++ b/pkg/utils/util.go @@ -638,8 +638,8 @@ func IsBoundVolumeGroupSnapshotContentNameSet(groupSnapshot *crdv1alpha1.VolumeG return true } -func IsVolumeSnapshotRefListSet(groupSnapshot *crdv1alpha1.VolumeGroupSnapshot) bool { - if groupSnapshot.Status == nil || len(groupSnapshot.Status.VolumeSnapshotRefList) == 0 { +func IsPVCVolumeSnapshotRefListSet(groupSnapshot *crdv1alpha1.VolumeGroupSnapshot) bool { + if groupSnapshot.Status == nil || len(groupSnapshot.Status.PVCVolumeSnapshotRefList) == 0 { return false } return true diff --git a/vendor/github.com/kubernetes-csi/external-snapshotter/client/v7/apis/volumegroupsnapshot/v1alpha1/types.go b/vendor/github.com/kubernetes-csi/external-snapshotter/client/v7/apis/volumegroupsnapshot/v1alpha1/types.go index 4110c2929..6684cbac7 100644 --- a/vendor/github.com/kubernetes-csi/external-snapshotter/client/v7/apis/volumegroupsnapshot/v1alpha1/types.go +++ b/vendor/github.com/kubernetes-csi/external-snapshotter/client/v7/apis/volumegroupsnapshot/v1alpha1/types.go @@ -109,11 +109,20 @@ type VolumeGroupSnapshotStatus struct { // +optional Error *snapshotv1.VolumeSnapshotError `json:"error,omitempty" protobuf:"bytes,4,opt,name=error,casttype=VolumeSnapshotError"` - // VolumeSnapshotRefList is the list of volume snapshot references for this - // group snapshot. + // VolumeSnapshotRefList is the list of PVC and VolumeSnapshot pairs that + // is part of this group snapshot. // The maximum number of allowed snapshots in the group is 100. // +optional - VolumeSnapshotRefList []core_v1.ObjectReference `json:"volumeSnapshotRefList,omitempty" protobuf:"bytes,5,opt,name=volumeSnapshotRefList"` + PVCVolumeSnapshotRefList []PVCVolumeSnapshotPair `json:"pvcVolumeSnapshotRefList,omitempty" protobuf:"bytes,5,opt,name=pvcVolumeSnapshotRefList"` +} + +// PVCVolumeSnapshotPair defines a pair of a PVC reference and a Volume Snapshot Reference +type PVCVolumeSnapshotPair struct { + // PersistentVolumeClaimRef is a reference to the PVC this pair is referring to + PersistentVolumeClaimRef core_v1.LocalObjectReference `json:"persistentVolumeClaimRef,omitempty" protobuf:"bytes,1,opt,name=persistentVolumeClaimRef"` + + // VolumeSnapshotRef is a reference to the VolumeSnapshot this pair is referring to + VolumeSnapshotRef core_v1.LocalObjectReference `json:"volumeSnapshotRef,omitempty" protobuf:"bytes,2,opt,name=volumeSnapshotRef"` } //+genclient @@ -345,11 +354,21 @@ type VolumeGroupSnapshotContentStatus struct { // +optional Error *snapshotv1.VolumeSnapshotError `json:"error,omitempty" protobuf:"bytes,4,opt,name=error,casttype=VolumeSnapshotError"` - // VolumeSnapshotContentRefList is the list of volume snapshot content references - // for this group snapshot. + // PVVolumeSnapshotContentList is the list of pairs of PV and + // VolumeSnapshotContent for this group snapshot // The maximum number of allowed snapshots in the group is 100. // +optional - VolumeSnapshotContentRefList []core_v1.ObjectReference `json:"volumeSnapshotContentRefList,omitempty" protobuf:"bytes,5,opt,name=volumeSnapshotContentRefList"` + PVVolumeSnapshotContentList []PVVolumeSnapshotContentPair `json:"pvVolumeSnapshotContentList,omitempty" protobuf:"bytes,5,opt,name=pvVolumeSnapshotContentRefList"` +} + +// PVVolumeSnapshotContentPair represent a pair of PV names and +// VolumeSnapshotContent names +type PVVolumeSnapshotContentPair struct { + // PersistentVolumeRef is a reference to the persistent volume resource + PersistentVolumeRef core_v1.LocalObjectReference `json:"persistentVolumeRef,omitempty" protobuf:"bytes,1,opt,name=persistentVolumeRef"` + + // VolumeSnapshotContentRef is a reference to the volume snapshot content resource + VolumeSnapshotContentRef core_v1.LocalObjectReference `json:"volumeSnapshotContentRef,omitempty" protobuf:"bytes,2,opt,name=volumeSnapshotContentRef"` } // VolumeGroupSnapshotContentSource represents the CSI source of a group snapshot. diff --git a/vendor/github.com/kubernetes-csi/external-snapshotter/client/v7/apis/volumegroupsnapshot/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/kubernetes-csi/external-snapshotter/client/v7/apis/volumegroupsnapshot/v1alpha1/zz_generated.deepcopy.go index 820cbb91a..81bdf47cd 100644 --- a/vendor/github.com/kubernetes-csi/external-snapshotter/client/v7/apis/volumegroupsnapshot/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/github.com/kubernetes-csi/external-snapshotter/client/v7/apis/volumegroupsnapshot/v1alpha1/zz_generated.deepcopy.go @@ -23,7 +23,6 @@ package v1alpha1 import ( v1 "github.com/kubernetes-csi/external-snapshotter/client/v7/apis/volumesnapshot/v1" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -49,6 +48,42 @@ func (in *GroupSnapshotHandles) DeepCopy() *GroupSnapshotHandles { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PVCVolumeSnapshotPair) DeepCopyInto(out *PVCVolumeSnapshotPair) { + *out = *in + out.PersistentVolumeClaimRef = in.PersistentVolumeClaimRef + out.VolumeSnapshotRef = in.VolumeSnapshotRef + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PVCVolumeSnapshotPair. +func (in *PVCVolumeSnapshotPair) DeepCopy() *PVCVolumeSnapshotPair { + if in == nil { + return nil + } + out := new(PVCVolumeSnapshotPair) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PVVolumeSnapshotContentPair) DeepCopyInto(out *PVVolumeSnapshotContentPair) { + *out = *in + out.PersistentVolumeRef = in.PersistentVolumeRef + out.VolumeSnapshotContentRef = in.VolumeSnapshotContentRef + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PVVolumeSnapshotContentPair. +func (in *PVVolumeSnapshotContentPair) DeepCopy() *PVVolumeSnapshotContentPair { + if in == nil { + return nil + } + out := new(PVVolumeSnapshotContentPair) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VolumeGroupSnapshot) DeepCopyInto(out *VolumeGroupSnapshot) { *out = *in @@ -284,9 +319,9 @@ func (in *VolumeGroupSnapshotContentStatus) DeepCopyInto(out *VolumeGroupSnapsho *out = new(v1.VolumeSnapshotError) (*in).DeepCopyInto(*out) } - if in.VolumeSnapshotContentRefList != nil { - in, out := &in.VolumeSnapshotContentRefList, &out.VolumeSnapshotContentRefList - *out = make([]corev1.ObjectReference, len(*in)) + if in.PVVolumeSnapshotContentList != nil { + in, out := &in.PVVolumeSnapshotContentList, &out.PVVolumeSnapshotContentList + *out = make([]PVVolumeSnapshotContentPair, len(*in)) copy(*out, *in) } return @@ -405,9 +440,9 @@ func (in *VolumeGroupSnapshotStatus) DeepCopyInto(out *VolumeGroupSnapshotStatus *out = new(v1.VolumeSnapshotError) (*in).DeepCopyInto(*out) } - if in.VolumeSnapshotRefList != nil { - in, out := &in.VolumeSnapshotRefList, &out.VolumeSnapshotRefList - *out = make([]corev1.ObjectReference, len(*in)) + if in.PVCVolumeSnapshotRefList != nil { + in, out := &in.PVCVolumeSnapshotRefList, &out.PVCVolumeSnapshotRefList + *out = make([]PVCVolumeSnapshotPair, len(*in)) copy(*out, *in) } return