Skip to content

Commit

Permalink
Merge pull request #18 from jibudata/main
Browse files Browse the repository at this point in the history
support veleroexport cancel state
  • Loading branch information
hpjibu authored Feb 15, 2022
2 parents 01e9604 + afe24f2 commit 488e5ab
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 11 deletions.
43 changes: 42 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ make build-cli

## Usage

### CLI Example

#### 备份数据

```
Expand Down Expand Up @@ -81,4 +83,43 @@ Deleted pod stage-wordpress-589f976cd5-vbj5z-d4zg7
Deleted pod stage-wordpress-mysql-d9b8d8884-9g4r5-xzr8r
=== Step 5. Invoke velero to restore original namespace
Created velero restore plan generate-restore-tfqhz
```
```

### Use CR

Other backup solution can use CR for API level integration with data mover, below are CR details.

##### VeleroExport CR Spec

| Param | Type | Supported value | Description |
| ------------------ | ----------------------- | ------------------------- | ------------------------------------------------------------ |
| VeleroBackupRef | *corev1.ObjectReference | name: xxx, namespace: xxx | Object reference of Velero backup which backup the namespaces using snapshot copy method |
| IncludedNamespaces | []string | Any | Volumesnapshots in the namespaces will be exported |
| DataSourceMapping | map[string]string | Any | DataSourceMapping is a map of pvc names to volumesnapshot names to be exported. |
| Policy | ExportPolicy | Retention: xx | specify the veleroexport retention |

##### VeleroExport Status

| Status | Description |
| ----------------- | -------------------------------------------------- |
| StateInProgress | Data export is in progress |
| StateFailed | Data export is Failed |
| StateCompleted | Data export is Completed |
| StateVeleroFailed | Data export is Failed due to velero backup failure |

##### VeleroImport CR Spec

| Param | Type | Supported value | Description |
| ---------------- | ----------------------- | ------------------------- | ------------------------------------------------------------ |
| VeleroBackupRef | *corev1.ObjectReference | name: xxx, namespace: xxx | Object reference of Velero backup which backup the namespaces using snapshot copy method |
| NamespaceMapping | map[string]string | any | |

##### VeleroImport Status

| Status | Description |
| ----------------- | -------------------------------------------------- |
| StateInProgress | Data import is in progress |
| StateFailed | Data import is failed |
| StateCompleted | Data import is completed |
| StateVeleroFailed | Data import is failed due to velero backup failure |

1 change: 1 addition & 0 deletions api/v1alpha1/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ const (
StateFailed = "Failed"
StateCompleted = "Completed"
StateVeleroFailed = "VeleroFailed"
StateCanceled = "Canceled"
)

//Requeue Time Definition
Expand Down
50 changes: 41 additions & 9 deletions controllers/veleroexport_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type VeleroExportReconciler struct {
const (
requeueAfterFast = 5 * time.Second
requeueAfterSlow = 20 * time.Second
timeout = 30 * time.Minute
)

const (
Expand Down Expand Up @@ -117,7 +118,7 @@ func (r *VeleroExportReconciler) Reconcile(ctx context.Context, req ctrl.Request
return
}
veleroExport.Status.SetReconcileFailed(err)
err := r.Update(ctx, veleroExport)
err := r.Client.Status().Update(ctx, veleroExport)
if err != nil {
//r.Log.Error(err, "")
return
Expand All @@ -130,7 +131,35 @@ func (r *VeleroExportReconciler) Reconcile(ctx context.Context, req ctrl.Request
veleroNamespace := veleroExport.Spec.VeleroBackupRef.Namespace
opt := ops.NewOperation(r.Log, r.Client)

if veleroExport.Status.Phase == dmapi.PhaseCompleted {
if veleroExport.Status.State == dmapi.StateFailed {
now := time.Now()
if time.Duration(now.Sub(veleroExport.Status.StartTimestamp.Time)) >= timeout {
// bind volumesnapshot and volumesnapshot content in original namespaces
// err := r.updateSnapshotContentBack(veleroExport, opt, includedNamespaces)
// if err != nil {
// return ctrl.Result{}, err
// }

// clean up tempary namespaces
for _, namespace := range includedNamespaces {
tmpNamespace := config.TempNamespacePrefix + namespace
err = opt.AsyncDeleteNamespace(tmpNamespace)
if err != nil {
return ctrl.Result{}, err
}
}

r.Log.Info("Failed veleroexport got timeout", "veleroexport", veleroExport.Name)
veleroExport.Status.State = dmapi.StateCanceled
err = r.Client.Status().Update(context.TODO(), veleroExport)
if err != nil {
return ctrl.Result{}, err
}
return ctrl.Result{RequeueAfter: requeueAfterFast}, nil
}
}

if veleroExport.Status.Phase == dmapi.PhaseCompleted || veleroExport.Status.State == dmapi.StateCanceled {
if veleroExport.Status.StopTimestamp != nil {
stopTime := veleroExport.Status.StopTimestamp.Time
now := time.Now()
Expand Down Expand Up @@ -629,22 +658,25 @@ func (r *VeleroExportReconciler) precheck(client k8sclient.Client, veleroExport
err = fmt.Errorf("invalid backup plan %s.", vBackupRef.Name)
} else {
// check if any volumesnapshot
emptyVsList := true
vsMap := make(map[string]string)
for _, namespace := range veleroExport.Spec.IncludedNamespaces {
vsList, err := opt.GetVolumeSnapshotList(vBackupRef.Name, namespace)
if err != nil {
err = fmt.Errorf("validate backup failed, could not get volume snapshot for backup plan %s", vBackupRef.Name)
return err
} else {
if len(vsList.Items) > 0 {
emptyVsList = false
break
for _, volumesnapshot := range vsList.Items {
key := volumesnapshot.Namespace + "/" + *volumesnapshot.Spec.Source.PersistentVolumeClaimName
vsMap[key] = volumesnapshot.Name
}
}
}
if emptyVsList {
err = fmt.Errorf("empty volumesnapshot list to export")
return err

for key, _ := range veleroExport.Spec.DataSourceMapping {
if _, ok := vsMap[key]; !ok {
err = fmt.Errorf("volume snapshot for pvc %s doesn't exist", key)
return err
}
}
}
return err
Expand Down
4 changes: 3 additions & 1 deletion pkg/operation/velero_operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ func (o *Operation) GetVeleroBackup(backupName string, veleroNamespace string) (
}
err := o.client.List(context.TODO(), backups, options)
if err != nil {
o.logger.Error(err, fmt.Sprintf("Failed to get velero backup plan %s", backupName))
if !errors.IsNotFound(err) {
o.logger.Error(err, fmt.Sprintf("Failed to list velero backup plan %s", backupName))
}
return nil, err
}
if len(backups.Items) > 0 {
Expand Down

0 comments on commit 488e5ab

Please sign in to comment.