Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PWX-35626: Add a last 4 digit UID string from volumesnapshotschedule to volumesnapshot name to avoid name collision. #1686

Merged
merged 1 commit into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions pkg/snapshot/controllers/snapshotschedule.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,12 +290,15 @@ func (s *SnapshotScheduleController) shouldStartVolumeSnapshot(snapshotSchedule
}

func (s *SnapshotScheduleController) formatVolumeSnapshotName(snapshotSchedule *stork_api.VolumeSnapshotSchedule, policyType stork_api.SchedulePolicyType) string {
snapSuffix := strings.Join([]string{strings.ToLower(string(policyType)), time.Now().Format(nameTimeSuffixFormat)}, "-")
// get a random 4 character suffix from the snapshotschedule's UID
randSuffix := string(snapshotSchedule.UID)[len(snapshotSchedule.UID)-4:]

snapSuffix := strings.Join([]string{strings.ToLower(string(policyType)), randSuffix, time.Now().Format(nameTimeSuffixFormat)}, "-")
scheduleName := snapshotSchedule.Name
if len(scheduleName) >= validation.LabelValueMaxLength-len(snapSuffix) {
scheduleName = scheduleName[:validation.LabelValueMaxLength-len(snapSuffix)-1]
}
return strings.Join([]string{scheduleName, strings.ToLower(string(policyType)), time.Now().Format(nameTimeSuffixFormat)}, "-")
return strings.Join([]string{scheduleName, snapSuffix}, "-")
}

func (s *SnapshotScheduleController) startVolumeSnapshot(inputSnapshotSchedule *stork_api.VolumeSnapshotSchedule, policyType stork_api.SchedulePolicyType) error {
Expand Down
101 changes: 101 additions & 0 deletions test/integration_test/snapshot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ func snapshotScheduleTests(t *testing.T) {
err := setMockTime(nil)
require.NoError(t, err, "Error resetting mock time")
t.Run("intervalTest", intervalSnapshotScheduleTest)
t.Run("intervalSnapshotScheduleWithSimilarLongNamesTest", intervalSnapshotScheduleWithSimilarLongNamesTest)
t.Run("dailyTest", dailySnapshotScheduleTest)
t.Run("weeklyTest", weeklySnapshotScheduleTest)
t.Run("monthlyTest", monthlySnapshotScheduleTest)
Expand Down Expand Up @@ -579,6 +580,106 @@ func intervalSnapshotScheduleTest(t *testing.T) {
logrus.Infof("Test status at end of %s test: %s", t.Name(), testResult)
}

func intervalSnapshotScheduleWithSimilarLongNamesTest(t *testing.T) {
var testrailID, testResult = 297239, testResultFail
runID := testrailSetupForTest(testrailID, &testResult)
defer updateTestRail(&testResult, testrailID, runID)
defer updateDashStats(t.Name(), &testResult)

ctxs, err := schedulerDriver.Schedule(generateInstanceID(t, "scheduletest"),
scheduler.ScheduleOptions{AppKeys: []string{"elasticsearch"}})
require.NoError(t, err, "Error scheduling task")
require.Equal(t, 1, len(ctxs), "Only one task should have started")

err = schedulerDriver.WaitForRunning(ctxs[0], defaultWaitTimeout, defaultWaitInterval)
require.NoError(t, err, "Error waiting for elasticsearch statefulset to get to running state")

policyName := "intervalpolicy"
retain := 1
interval := 2
schedPolicy := &storkv1.SchedulePolicy{
ObjectMeta: metav1.ObjectMeta{
Name: policyName,
},
Policy: storkv1.SchedulePolicyItem{
Interval: &storkv1.IntervalPolicy{
Retain: storkv1.Retain(retain),
IntervalMinutes: interval,
},
}}

if authTokenConfigMap != "" {
err := addSecurityAnnotation(schedPolicy)
require.NoError(t, err, "Error adding annotations to interval schedule policy")
}

_, err = storkops.Instance().CreateSchedulePolicy(schedPolicy)
require.NoError(t, err, "Error creating interval schedule policy")
logrus.Infof("Created schedulepolicy %v with %v minute interval and retain at %v", policyName, interval, retain)

namespace := ctxs[0].GetID()
pvcList, err := core.Instance().GetPersistentVolumeClaims(namespace, nil)
require.NoError(t, err, fmt.Sprintf("Error getting pvcs in namespace %s interval schedule policy", namespace))
logrus.Infof("Found %v pvcs in namespace %s", len(pvcList.Items), namespace)

sleepTime := time.Duration((retain+1)*interval) * time.Minute
scheduleNames := make([]string, 0)
for _, pvc := range pvcList.Items {
scheduleName := fmt.Sprintf("intervalscheduletest-%s", pvc.Name)
scheduleNames = append(scheduleNames, scheduleName)
snapSched := &storkv1.VolumeSnapshotSchedule{
ObjectMeta: metav1.ObjectMeta{
Name: scheduleName,
Namespace: namespace,
},
Spec: storkv1.VolumeSnapshotScheduleSpec{
Template: storkv1.VolumeSnapshotTemplateSpec{
Spec: crdv1.VolumeSnapshotSpec{
PersistentVolumeClaimName: pvc.Name},
},
SchedulePolicyName: policyName,
},
}

if authTokenConfigMap != "" {
err := addSecurityAnnotation(snapSched)
require.NoError(t, err, "Error adding annotations to interval schedule policy")
}

_, err = storkops.Instance().CreateSnapshotSchedule(snapSched)
require.NoError(t, err, "Error creating interval snapshot schedule")
sleepTime := time.Duration((retain+1)*interval) * time.Minute
logrus.Infof("Created snapshotschedule %v in namespace %v, sleeping for %v for schedule to trigger",
scheduleName, namespace, sleepTime)
}

time.Sleep(sleepTime)

for _, scheduleName := range scheduleNames {
snapStatuses, err := storkops.Instance().ValidateSnapshotSchedule(scheduleName,
namespace,
snapshotScheduleRetryTimeout,
snapshotScheduleRetryInterval)
require.NoError(t, err, "Error validating interval snapshot schedule")
require.Equal(t, 1, len(snapStatuses), "Should have snapshots for only one policy type")
require.Equal(t, retain, len(snapStatuses[storkv1.SchedulePolicyTypeInterval]), fmt.Sprintf("Should have only %v snapshot for interval policy", retain))
logrus.Infof("Validated snapshotschedule %v", scheduleName)
}

for _, scheduleName := range scheduleNames {
err = storkops.Instance().DeleteSnapshotSchedule(scheduleName, namespace)
require.NoError(t, err, fmt.Sprintf("Error deleting snapshot schedule %v from namespace %v", scheduleName, namespace))
}
err = storkops.Instance().DeleteSchedulePolicy(policyName)
require.NoError(t, err, fmt.Sprintf("Error deleting schedule policy %v", policyName))

destroyAndWait(t, ctxs)

// If we are here then the test has passed
testResult = testResultPass
logrus.Infof("Test status at end of %s test: %s", t.Name(), testResult)
}

func dailySnapshotScheduleTest(t *testing.T) {
var testrailID, testResult = 86219, testResultFail
runID := testrailSetupForTest(testrailID, &testResult)
Expand Down