Skip to content

Commit 500e055

Browse files
jingxu97xing-yang
authored andcommitted
Add volumesnapshot content deletion policy
This PR adds DeletionPolicy which describes a policy for end-of-life maintenance of volume snapshot contents. There are two types of policies, delete and retain. By default, the policy is delete. In this case, when volume snaphsot is deleted, the volume snapshot content for it should be deleted, as well as the physical snapshot. If the policy is set the retain, the volume snapshot content will remain even if the volume snapshot it binds to is deleted.
1 parent e3604f7 commit 500e055

File tree

11 files changed

+213
-62
lines changed

11 files changed

+213
-62
lines changed

pkg/apis/volumesnapshot/v1alpha1/types.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,11 @@ type VolumeSnapshotClass struct {
132132
// to the snapshotter.
133133
// +optional
134134
Parameters map[string]string `json:"parameters,omitempty" protobuf:"bytes,3,rep,name=parameters"`
135+
136+
// Optional: what happens to a snapshot content when released from its snapshot.
137+
// The default policy is Delete if not specified.
138+
// +optional
139+
DeletionPolicy *DeletionPolicy `json:"deletionPolicy,omitempty" protobuf:"bytes,4,opt,name=deletionPolicy"`
135140
}
136141

137142
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
@@ -195,6 +200,11 @@ type VolumeSnapshotContentSpec struct {
195200
// be used if it is available.
196201
// +optional
197202
VolumeSnapshotClassName *string `json:"snapshotClassName" protobuf:"bytes,4,opt,name=snapshotClassName"`
203+
204+
// Optional: what happens to a snapshot content when released from its snapshot. It will be set to Delete by default
205+
// if not specified
206+
// +optional
207+
DeletionPolicy *DeletionPolicy `json:"deletionPolicy" protobuf:"bytes,5,opt,name=deletionPolicy"`
198208
}
199209

200210
// VolumeSnapshotSource represents the actual location and type of the snapshot. Only one of its members may be specified.
@@ -232,3 +242,15 @@ type CSIVolumeSnapshotSource struct {
232242
// +optional
233243
RestoreSize *int64 `json:"restoreSize,omitempty" protobuf:"bytes,4,opt,name=restoreSize"`
234244
}
245+
246+
// DeletionPolicy describes a policy for end-of-life maintenance of volume snapshot contents
247+
type DeletionPolicy string
248+
249+
const (
250+
// VolumeSnapshotContentDelete means the snapshot content will be deleted from Kubernetes on release from its volume snapshot.
251+
VolumeSnapshotContentDelete DeletionPolicy = "Delete"
252+
253+
// VolumeSnapshotContentRetain means the snapshot will be left in its current state on release from its volume snapshot.
254+
// The default policy is Retain if not specified.
255+
VolumeSnapshotContentRetain DeletionPolicy = "Retain"
256+
)

pkg/client/clientset/versioned/typed/volumesnapshot/v1alpha1/volumesnapshot.go

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/client/clientset/versioned/typed/volumesnapshot/v1alpha1/volumesnapshotclass.go

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/client/clientset/versioned/typed/volumesnapshot/v1alpha1/volumesnapshotcontent.go

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/controller/csi_handler.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ func (handler *csiHandler) DeleteSnapshot(content *crdv1.VolumeSnapshotContent,
7777

7878
err := handler.csiConnection.DeleteSnapshot(ctx, content.Spec.CSI.SnapshotHandle, snapshotterCredentials)
7979
if err != nil {
80-
return fmt.Errorf("failed to delete snapshot data %s: %q", content.Name, err)
80+
return fmt.Errorf("failed to delete snapshot content %s: %q", content.Name, err)
8181
}
8282

8383
return nil
@@ -92,7 +92,7 @@ func (handler *csiHandler) GetSnapshotStatus(content *crdv1.VolumeSnapshotConten
9292

9393
csiSnapshotStatus, timestamp, size, err := handler.csiConnection.GetSnapshotStatus(ctx, content.Spec.CSI.SnapshotHandle)
9494
if err != nil {
95-
return false, 0, 0, fmt.Errorf("failed to list snapshot data %s: %q", content.Name, err)
95+
return false, 0, 0, fmt.Errorf("failed to list snapshot content %s: %q", content.Name, err)
9696
}
9797
return csiSnapshotStatus, timestamp, size, nil
9898

pkg/controller/framework_test.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,7 @@ func newTestController(kubeClient kubernetes.Interface, clientset clientset.Inte
744744
}
745745

746746
// newContent returns a new content with given attributes
747-
func newContent(name, className, snapshotHandle, volumeUID, volumeName, boundToSnapshotUID, boundToSnapshotName string, size *int64, creationTime *int64) *crdv1.VolumeSnapshotContent {
747+
func newContent(name, className, snapshotHandle, volumeUID, volumeName, boundToSnapshotUID, boundToSnapshotName string, deletionPolicy *crdv1.DeletionPolicy, size *int64, creationTime *int64) *crdv1.VolumeSnapshotContent {
748748
content := crdv1.VolumeSnapshotContent{
749749
ObjectMeta: metav1.ObjectMeta{
750750
Name: name,
@@ -766,6 +766,7 @@ func newContent(name, className, snapshotHandle, volumeUID, volumeName, boundToS
766766
UID: types.UID(volumeUID),
767767
Name: volumeName,
768768
},
769+
DeletionPolicy: deletionPolicy,
769770
},
770771
}
771772
if boundToSnapshotName != "" {
@@ -781,14 +782,14 @@ func newContent(name, className, snapshotHandle, volumeUID, volumeName, boundToS
781782
return &content
782783
}
783784

784-
func newContentArray(name, className, snapshotHandle, volumeUID, volumeName, boundToSnapshotUID, boundToSnapshotName string, size *int64, creationTime *int64) []*crdv1.VolumeSnapshotContent {
785+
func newContentArray(name, className, snapshotHandle, volumeUID, volumeName, boundToSnapshotUID, boundToSnapshotName string, deletionPolicy *crdv1.DeletionPolicy, size *int64, creationTime *int64) []*crdv1.VolumeSnapshotContent {
785786
return []*crdv1.VolumeSnapshotContent{
786-
newContent(name, className, snapshotHandle, volumeUID, volumeName, boundToSnapshotUID, boundToSnapshotName, size, creationTime),
787+
newContent(name, className, snapshotHandle, volumeUID, volumeName, boundToSnapshotUID, boundToSnapshotName, deletionPolicy, size, creationTime),
787788
}
788789
}
789790

790-
func newContentWithUnmatchDriverArray(name, className, snapshotHandle, volumeUID, volumeName, boundToSnapshotUID, boundToSnapshotName string, size *int64, creationTime *int64) []*crdv1.VolumeSnapshotContent {
791-
content := newContent(name, className, snapshotHandle, volumeUID, volumeName, boundToSnapshotUID, boundToSnapshotName, size, creationTime)
791+
func newContentWithUnmatchDriverArray(name, className, snapshotHandle, volumeUID, volumeName, boundToSnapshotUID, boundToSnapshotName string, deletionPolicy *crdv1.DeletionPolicy, size *int64, creationTime *int64) []*crdv1.VolumeSnapshotContent {
792+
content := newContent(name, className, snapshotHandle, volumeUID, volumeName, boundToSnapshotUID, boundToSnapshotName, deletionPolicy, size, creationTime)
792793
content.Spec.VolumeSnapshotSource.CSI.Driver = "fake"
793794
return []*crdv1.VolumeSnapshotContent{
794795
content,

pkg/controller/snapshot_controller.go

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,24 @@ func (ctrl *csiSnapshotController) syncContent(content *crdv1.VolumeSnapshotCont
125125
snapshot = nil
126126
}
127127
if snapshot == nil {
128-
ctrl.deleteSnapshotContent(content)
129-
}
128+
if content.Spec.DeletionPolicy != nil {
129+
switch *content.Spec.DeletionPolicy {
130+
case crdv1.VolumeSnapshotContentRetain:
131+
glog.V(4).Infof("VolumeSnapshotContent[%s]: policy is Retain, nothing to do", content.Name)
132+
133+
case crdv1.VolumeSnapshotContentDelete:
134+
glog.V(4).Infof("VolumeSnapshotContent[%s]: policy is Delete", content.Name)
135+
ctrl.deleteSnapshotContent(content)
136+
default:
137+
// Unknown VolumeSnapshotDeletionolicy
138+
ctrl.eventRecorder.Event(content, v1.EventTypeWarning, "SnapshotUnknownDeletionPolicy", "Volume Snapshot Content has unrecognized deletion policy")
139+
}
140+
return nil
141+
}
142+
// By default, we use Retain policy if it is not set by users
143+
glog.V(4).Infof("VolumeSnapshotContent[%s]: by default the policy is Retain", content.Name)
130144

145+
}
131146
return nil
132147
}
133148

@@ -538,6 +553,10 @@ func (ctrl *csiSnapshotController) createSnapshotOperation(snapshot *crdv1.Volum
538553
return nil, err
539554
}
540555

556+
if class.DeletionPolicy == nil {
557+
class.DeletionPolicy = new(crdv1.DeletionPolicy)
558+
*class.DeletionPolicy = crdv1.VolumeSnapshotContentDelete
559+
}
541560
snapshotContent := &crdv1.VolumeSnapshotContent{
542561
ObjectMeta: metav1.ObjectMeta{
543562
Name: contentName,
@@ -554,8 +573,10 @@ func (ctrl *csiSnapshotController) createSnapshotOperation(snapshot *crdv1.Volum
554573
},
555574
},
556575
VolumeSnapshotClassName: &(class.Name),
576+
DeletionPolicy: class.DeletionPolicy,
557577
},
558578
}
579+
glog.V(3).Infof("volume snapshot content %v", snapshotContent)
559580
// Try to create the VolumeSnapshotContent object several times
560581
for i := 0; i < ctrl.createSnapshotContentRetryCount; i++ {
561582
glog.V(5).Infof("createSnapshot [%s]: trying to save volume snapshot content %s", snapshotKey(snapshot), snapshotContent.Name)
@@ -565,7 +586,7 @@ func (ctrl *csiSnapshotController) createSnapshotOperation(snapshot *crdv1.Volum
565586
glog.V(3).Infof("volume snapshot content %q for snapshot %q already exists, reusing", snapshotContent.Name, snapshotKey(snapshot))
566587
err = nil
567588
} else {
568-
glog.V(3).Infof("volume snapshot content %q for snapshot %q saved", snapshotContent.Name, snapshotKey(snapshot))
589+
glog.V(3).Infof("volume snapshot content %q for snapshot %q saved, %v", snapshotContent.Name, snapshotKey(snapshot), snapshotContent)
569590
}
570591
break
571592
}

pkg/controller/snapshot_controller_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import (
2323
)
2424

2525
func storeVersion(t *testing.T, prefix string, c cache.Store, version string, expectedReturn bool) {
26-
content := newContent("contentName", classEmpty, "sid1-1", "vuid1-1", "volume1-1", "snapuid1-1", "snap1-1", nil, nil)
26+
content := newContent("contentName", classEmpty, "sid1-1", "vuid1-1", "volume1-1", "snapuid1-1", "snap1-1", nil, nil, nil)
2727
content.ResourceVersion = version
2828
ret, err := storeObjectUpdate(c, content, "content")
2929
if err != nil {
@@ -82,7 +82,7 @@ func TestControllerCacheParsingError(t *testing.T) {
8282
// There must be something in the cache to compare with
8383
storeVersion(t, "Step1", c, "1", true)
8484

85-
content := newContent("contentName", classEmpty, "sid1-1", "vuid1-1", "volume1-1", "snapuid1-1", "snap1-1", nil, nil)
85+
content := newContent("contentName", classEmpty, "sid1-1", "vuid1-1", "volume1-1", "snapuid1-1", "snap1-1", nil, nil, nil)
8686
content.ResourceVersion = "xxx"
8787
_, err := storeObjectUpdate(c, content, "content")
8888
if err == nil {

0 commit comments

Comments
 (0)