Skip to content

Commit d1f1c8f

Browse files
committed
pb-4669: Adding support for partial success backups
- A backup involving multiple PVC, if one of the PVC backup fails, backup will mark that PVC as Failed and proceed to next PVCs rather than failing the entire backup - For the failed PVC, corresponding resources are not backed up. - New status called PartialSuccess is introduced to signify the same
1 parent c041411 commit d1f1c8f

File tree

4 files changed

+152
-38
lines changed

4 files changed

+152
-38
lines changed

drivers/volume/portworx/portworx.go

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3343,14 +3343,20 @@ func (p *portworx) StartBackup(backup *storkapi.ApplicationBackup,
33433343
}
33443344
return true, nil
33453345
})
3346-
33473346
if err != nil || cloudBackupCreateErr != nil {
33483347
if isCloudBackupServerBusyError(cloudBackupCreateErr) {
3349-
return volumeInfos, &storkvolume.ErrStorageProviderBusy{Reason: cloudBackupCreateErr.Error()}
3348+
volumeInfo.Status = storkapi.ApplicationBackupStatusFailed
3349+
volumeInfo.Reason = cloudBackupCreateErr.Error()
3350+
volumeInfos = append(volumeInfos, volumeInfo)
3351+
continue
33503352
}
33513353
if _, ok := cloudBackupCreateErr.(*ost_errors.ErrExists); !ok {
3352-
return nil, fmt.Errorf("failed to start backup for %v (%v/%v): %v",
3354+
volumeInfo.Status = storkapi.ApplicationBackupStatusFailed
3355+
volumeInfo.Reason = fmt.Sprintf("%v", cloudBackupCreateErr)
3356+
volumeInfos = append(volumeInfos, volumeInfo)
3357+
logrus.Infof("failed to start backup for %v (%v/%v): %v",
33533358
volume, pvc.Namespace, pvc.Name, cloudBackupCreateErr)
3359+
continue
33543360
}
33553361
} else if err == nil {
33563362
// Only add volumeInfos if this was a successful backup
@@ -3371,31 +3377,53 @@ func (p *portworx) GetBackupStatus(backup *storkapi.ApplicationBackup) ([]*stork
33713377
volumeInfos := make([]*storkapi.ApplicationBackupVolumeInfo, 0)
33723378
for _, vInfo := range backup.Status.Volumes {
33733379
if vInfo.DriverName != storkvolume.PortworxDriverName {
3380+
volumeInfos = append(volumeInfos, vInfo)
3381+
continue
3382+
}
3383+
// Skip for volumes which are in failed state as there is no need to proceed
3384+
// further and we have to return the orginal volInfo back to caller
3385+
if vInfo.Status == storkapi.ApplicationBackupStatusFailed {
3386+
volumeInfos = append(volumeInfos, vInfo)
33743387
continue
33753388
}
33763389
token, err := p.getUserToken(vInfo.Options, vInfo.Namespace)
33773390
if err != nil {
3378-
return nil, fmt.Errorf("failed to fetch portworx user token: %v", err)
3391+
logrus.Errorf("failed to fetch portworx user token: %v", err)
3392+
vInfo.Reason = fmt.Sprintf("failed to fetch portworx user token: %v", err)
3393+
vInfo.Status = storkapi.ApplicationBackupStatusFailed
3394+
volumeInfos = append(volumeInfos, vInfo)
3395+
continue
33793396
}
33803397
volDriver, ok := driverMap[token]
33813398
if !ok {
33823399
volDriver, _, err = p.getUserVolDriverFromToken(token)
33833400
if err != nil {
3384-
return nil, err
3401+
vInfo.Status = storkapi.ApplicationBackupStatusFailed
3402+
vInfo.Reason = fmt.Sprintf("%v", err)
3403+
logrus.Errorf("%v", err)
3404+
volumeInfos = append(volumeInfos, vInfo)
3405+
continue
33853406
}
33863407
driverMap[token] = volDriver
33873408
}
33883409

33893410
cloudBackupClient, err := p.getCloudBackupClient()
33903411
if err != nil {
3391-
return nil, err
3412+
vInfo.Status = storkapi.ApplicationBackupStatusFailed
3413+
vInfo.Reason = fmt.Sprintf("%v", err)
3414+
volumeInfos = append(volumeInfos, vInfo)
3415+
logrus.Errorf("%v", err)
33923416
}
33933417
ctx, cancel := context.WithTimeout(context.Background(), cloudBackupTimeout)
33943418
defer cancel()
33953419
if len(token) > 0 {
33963420
ctx, err = p.addTokenToContext(ctx, token)
33973421
if err != nil {
3398-
return nil, err
3422+
vInfo.Status = storkapi.ApplicationBackupStatusFailed
3423+
vInfo.Reason = fmt.Sprintf("%v", err)
3424+
volumeInfos = append(volumeInfos, vInfo)
3425+
logrus.Errorf("%v", err)
3426+
33993427
}
34003428
}
34013429

pkg/apis/stork/v1alpha1/applicationbackup.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ type ApplicationBackupStatus struct {
7171
TotalSize uint64 `json:"totalSize"`
7272
ResourceCount int `json:"resourceCount"`
7373
LargeResourceEnabled bool `json:"largeResourceEnabled"`
74+
FailedVolCount int `json:"failedVolCount"`
7475
}
7576

7677
// ObjectInfo contains info about an object being backed up or restored
@@ -83,6 +84,8 @@ type ObjectInfo struct {
8384
// ApplicationBackupResourceInfo is the info for the backup of a resource
8485
type ApplicationBackupResourceInfo struct {
8586
ObjectInfo `json:",inline"`
87+
Status ApplicationBackupStatusType `json:"status"`
88+
Reason string `json:"reason"`
8689
}
8790

8891
// ApplicationBackupVolumeInfo is the info for the backup of a volume
@@ -120,6 +123,8 @@ const (
120123
ApplicationBackupStatusPartialSuccess ApplicationBackupStatusType = "PartialSuccess"
121124
// ApplicationBackupStatusSuccessful for when backup has completed successfully
122125
ApplicationBackupStatusSuccessful ApplicationBackupStatusType = "Successful"
126+
// ApplicationBackupStatusSkip for when backup has been skipped
127+
ApplicationBackupStatusSkip ApplicationBackupStatusType = "Skipped"
123128
)
124129

125130
// ApplicationBackupStageType is the stage of the backup

0 commit comments

Comments
 (0)