diff --git a/api/backupbackingimage.go b/api/backupbackingimage.go index c9cf7a770f..df9470f840 100644 --- a/api/backupbackingimage.go +++ b/api/backupbackingimage.go @@ -4,6 +4,7 @@ import ( "net/http" "github.com/gorilla/mux" + "github.com/longhorn/longhorn-manager/types" "github.com/pkg/errors" "github.com/rancher/go-rancher/api" @@ -56,7 +57,7 @@ func (s *Server) BackupBackingImageRestore(w http.ResponseWriter, req *http.Requ } backupBackingImageName := mux.Vars(req)["name"] - if err := s.m.RestoreBackupBackingImage(backupBackingImageName, input.Secret, input.SecretNamespace); err != nil { + if err := s.m.RestoreBackupBackingImage(backupBackingImageName, input.Secret, input.SecretNamespace, input.DataEngine); err != nil { return errors.Wrapf(err, "failed to restore backup backing image '%s'", backupBackingImageName) } return nil @@ -71,8 +72,9 @@ func (s *Server) BackupBackingImageCreate(w http.ResponseWriter, req *http.Reque } backingImageName := mux.Vars(req)["name"] - if err := s.m.CreateBackupBackingImage(input.Name, backingImageName, input.BackupTargetName); err != nil { - return errors.Wrapf(err, "failed to create backup backing image '%s'", input.Name) + backupBackingImageName := types.GetBackupBackingImageNameFromBIName(backingImageName) + if err := s.m.CreateBackupBackingImage(backupBackingImageName, backingImageName, input.BackupTargetName); err != nil { + return errors.Wrapf(err, "failed to create backup backing image '%s'", backupBackingImageName) } return nil } diff --git a/api/model.go b/api/model.go index 5ecec7887b..73c278f224 100644 --- a/api/model.go +++ b/api/model.go @@ -295,6 +295,7 @@ type UpdateMinNumberOfCopiesInput struct { type BackingImageRestoreInput struct { Secret string `json:"secret"` SecretNamespace string `json:"secretNamespace"` + DataEngine string `json:"dataEngine"` } type AttachInput struct { diff --git a/client/generated_backing_image_restore_input.go b/client/generated_backing_image_restore_input.go index 265a89d1fa..81f24d87e3 100644 --- a/client/generated_backing_image_restore_input.go +++ b/client/generated_backing_image_restore_input.go @@ -7,6 +7,8 @@ const ( type BackingImageRestoreInput struct { Resource `yaml:"-"` + DataEngine string `json:"dataEngine,omitempty" yaml:"data_engine,omitempty"` + Secret string `json:"secret,omitempty" yaml:"secret,omitempty"` SecretNamespace string `json:"secretNamespace,omitempty" yaml:"secret_namespace,omitempty"` diff --git a/controller/system_backup_controller.go b/controller/system_backup_controller.go index 857c4f22f5..9dab360e3b 100644 --- a/controller/system_backup_controller.go +++ b/controller/system_backup_controller.go @@ -987,6 +987,10 @@ func (c *SystemBackupController) BackupBackingImage() (map[string]*longhorn.Back backingImageBackups := make(map[string]*longhorn.BackupBackingImage, len(backingImages)) for _, backingImage := range backingImages { + // TODO: support backup backing image v2 + if types.IsDataEngineV2(backingImage.Spec.DataEngine) { + continue + } backupBackingImage, err := c.createBackingImageBackup(backingImage) if err != nil { return nil, err diff --git a/manager/backupbackingimage.go b/manager/backupbackingimage.go index f6416e6e39..6ef1d25c9a 100644 --- a/manager/backupbackingimage.go +++ b/manager/backupbackingimage.go @@ -41,7 +41,7 @@ func (m *VolumeManager) DeleteBackupBackingImage(name string) error { return m.ds.DeleteBackupBackingImage(name) } -func (m *VolumeManager) RestoreBackupBackingImage(name string, secret, secretNamespace string) error { +func (m *VolumeManager) RestoreBackupBackingImage(name string, secret, secretNamespace string, dataEngine string) error { if name == "" { return fmt.Errorf("restore backing image name is not given") } @@ -62,7 +62,7 @@ func (m *VolumeManager) RestoreBackupBackingImage(name string, secret, secretNam return fmt.Errorf("backing image %v already exists", biName) } - return m.restoreBackingImage(bbi.Spec.BackupTargetName, biName, secret, secretNamespace) + return m.restoreBackingImage(bbi.Spec.BackupTargetName, biName, secret, secretNamespace, dataEngine) } func (m *VolumeManager) CreateBackupBackingImage(name, backingImageName, backupTargetName string) error { diff --git a/manager/volume.go b/manager/volume.go index 0fddcdc29a..5424fc637f 100644 --- a/manager/volume.go +++ b/manager/volume.go @@ -158,7 +158,7 @@ func (m *VolumeManager) Create(name string, spec *longhorn.VolumeSpec, recurring // TODO: We should record the secret and secret namespace in the backing image // so we can auto fill in the secret and namespace when auto restore the backing image in volume creation api. // Currently, if the backing image is encrypted, users need to restore it first so they can specifically assign the secret and namespace - if err := m.restoreBackingImage(backupTargetName, spec.BackingImage, "", ""); err != nil { + if err := m.restoreBackingImage(backupTargetName, spec.BackingImage, "", "", string(spec.DataEngine)); err != nil { return nil, errors.Wrapf(err, "failed to restore backing image %v when create volume %v", spec.BackingImage, name) } @@ -1189,7 +1189,7 @@ func (m *VolumeManager) UpdateSnapshotMaxSize(name string, snapshotMaxSize int64 return v, nil } -func (m *VolumeManager) restoreBackingImage(backupTargetName, biName, secret, secretNamespace string) error { +func (m *VolumeManager) restoreBackingImage(backupTargetName, biName, secret, secretNamespace, dataEngine string) error { if secret != "" || secretNamespace != "" { _, err := m.ds.GetSecretRO(secretNamespace, secret) if err != nil { @@ -1197,6 +1197,14 @@ func (m *VolumeManager) restoreBackingImage(backupTargetName, biName, secret, se } } + if dataEngine == "" { + dataEngine = string(longhorn.DataEngineTypeV1) + } + + if longhorn.DataEngineType(dataEngine) != longhorn.DataEngineTypeV1 && longhorn.DataEngineType(dataEngine) != longhorn.DataEngineTypeV2 { + return fmt.Errorf("invalid data engine type %v", dataEngine) + } + if biName == "" { return nil } @@ -1208,10 +1216,13 @@ func (m *VolumeManager) restoreBackingImage(backupTargetName, biName, secret, se } // backing image already exists if bi != nil { + if bi.Spec.DataEngine != longhorn.DataEngineType(dataEngine) { + return fmt.Errorf("backing image %v already exists with different data engine type %v", biName, bi.Spec.DataEngine) + } return nil } - // try find the backup backing image + // try to find the backup backing image bbi, err := m.ds.GetBackupBackingImagesWithBackupTargetNameRO(backupTargetName, biName) if err != nil { return errors.Wrapf(err, "failed to get backup backing image %v", biName) @@ -1228,6 +1239,7 @@ func (m *VolumeManager) restoreBackingImage(backupTargetName, biName, secret, se Name: biName, }, Spec: longhorn.BackingImageSpec{ + DataEngine: longhorn.DataEngineType(dataEngine), Checksum: bbi.Status.Checksum, SourceType: longhorn.BackingImageDataSourceTypeRestore, SourceParameters: map[string]string{