Skip to content

Commit

Permalink
feat(backup): upgrade CRs for multiple backup store
Browse files Browse the repository at this point in the history
Upgrade CRs for Volume, BackupVolume, Backup, BackupBackingImage,
and BackingImageDataSource.

Ref: 5411

Signed-off-by: James Lu <james.lu@suse.com>
  • Loading branch information
mantissahz committed Sep 26, 2024
1 parent 1a76623 commit e23a124
Show file tree
Hide file tree
Showing 3 changed files with 242 additions and 0 deletions.
3 changes: 3 additions & 0 deletions types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ const (
LonghornKindEngine = "Engine"
LonghornKindReplica = "Replica"
LonghornKindBackup = "Backup"
LonghornKindBackupBackingImage = "BackupBackingImage"
LonghornKindBackupTarget = "BackupTarget"
LonghornKindBackupVolume = "BackupVolume"
LonghornKindSnapshot = "Snapshot"
LonghornKindEngineImage = "EngineImage"
LonghornKindInstanceManager = "InstanceManager"
Expand Down
60 changes: 60 additions & 0 deletions upgrade/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,46 @@ func ListAndUpdateEnginesInProvidedCache(namespace string, lhClient *lhclientset
return engines, nil
}

// ListAndUpdateBackupTargetsInProvidedCache list all backup targets and save them into the provided cached `resourceMap`. This method is not thread-safe.
func ListAndUpdateBackupTargetsInProvidedCache(namespace string, lhClient *lhclientset.Clientset, resourceMaps map[string]interface{}) (map[string]*longhorn.BackupTarget, error) {
if v, ok := resourceMaps[types.LonghornKindBackupTarget]; ok {
return v.(map[string]*longhorn.BackupTarget), nil
}

backupTargets := map[string]*longhorn.BackupTarget{}
backupTargetList, err := lhClient.LonghornV1beta2().BackupTargets(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
return nil, err
}
for i, backupTarget := range backupTargetList.Items {
backupTargets[backupTarget.Name] = &backupTargetList.Items[i]
}

resourceMaps[types.LonghornKindBackupTarget] = backupTargets

return backupTargets, nil
}

// ListAndUpdateBackupVolumesInProvidedCache list all backup volumes and save them into the provided cached `resourceMap`. This method is not thread-safe.
func ListAndUpdateBackupVolumesInProvidedCache(namespace string, lhClient *lhclientset.Clientset, resourceMaps map[string]interface{}) (map[string]*longhorn.BackupVolume, error) {
if v, ok := resourceMaps[types.LonghornKindBackupVolume]; ok {
return v.(map[string]*longhorn.BackupVolume), nil
}

backupVolumes := map[string]*longhorn.BackupVolume{}
backupVolumeList, err := lhClient.LonghornV1beta2().BackupVolumes(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
return nil, err
}
for i, backupVolume := range backupVolumeList.Items {
backupVolumes[backupVolume.Name] = &backupVolumeList.Items[i]
}

resourceMaps[types.LonghornKindBackupVolume] = backupVolumes

return backupVolumes, nil
}

// ListAndUpdateBackupsInProvidedCache list all backups and save them into the provided cached `resourceMap`. This method is not thread-safe.
func ListAndUpdateBackupsInProvidedCache(namespace string, lhClient *lhclientset.Clientset, resourceMaps map[string]interface{}) (map[string]*longhorn.Backup, error) {
if v, ok := resourceMaps[types.LonghornKindBackup]; ok {
Expand All @@ -552,6 +592,26 @@ func ListAndUpdateBackupsInProvidedCache(namespace string, lhClient *lhclientset
return backups, nil
}

// ListAndUpdateBackupBackingImagesInProvidedCache list all backupBackingImages and save them into the provided cached `resourceMap`. This method is not thread-safe.
func ListAndUpdateBackupBackingImagesInProvidedCache(namespace string, lhClient *lhclientset.Clientset, resourceMaps map[string]interface{}) (map[string]*longhorn.BackupBackingImage, error) {
if v, ok := resourceMaps[types.LonghornKindBackupBackingImage]; ok {
return v.(map[string]*longhorn.BackupBackingImage), nil
}

bbis := map[string]*longhorn.BackupBackingImage{}
bbisList, err := lhClient.LonghornV1beta2().BackupBackingImages(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
return nil, err
}
for i, bids := range bbisList.Items {
bbis[bids.Name] = &bbisList.Items[i]
}

resourceMaps[types.LonghornKindBackupBackingImage] = bbis

return bbis, nil
}

// ListAndUpdateSnapshotsInProvidedCache list all snapshots and save them into the provided cached `resourceMap`. This method is not thread-safe.
func ListAndUpdateSnapshotsInProvidedCache(namespace string, lhClient *lhclientset.Clientset, resourceMaps map[string]interface{}) (map[string]*longhorn.Snapshot, error) {
if v, ok := resourceMaps[types.LonghornKindSnapshot]; ok {
Expand Down
179 changes: 179 additions & 0 deletions upgrade/v17xto180/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/longhorn/longhorn-manager/types"

longhorn "github.com/longhorn/longhorn-manager/k8s/pkg/apis/longhorn/v1beta2"
lhclientset "github.com/longhorn/longhorn-manager/k8s/pkg/client/clientset/versioned"
upgradeutil "github.com/longhorn/longhorn-manager/upgrade/util"
)
Expand All @@ -17,9 +18,187 @@ const (
)

func UpgradeResources(namespace string, lhClient *lhclientset.Clientset, kubeClient *clientset.Clientset, resourceMaps map[string]interface{}) error {
if err := upgradeVolumes(namespace, lhClient, resourceMaps); err != nil {
return err
}

if err := upgradeBackupVolumes(namespace, lhClient, resourceMaps); err != nil {
return err
}
if err := upgradeBackups(namespace, lhClient, resourceMaps); err != nil {
return err
}

if err := upgradeBackupBackingImages(namespace, lhClient, resourceMaps); err != nil {
return err
}

if err := upgradeBackingImageDataSources(namespace, lhClient, resourceMaps); err != nil {
return err
}

return upgradeBackingImages(namespace, lhClient, resourceMaps)
}

func upgradeVolumes(namespace string, lhClient *lhclientset.Clientset, resourceMaps map[string]interface{}) (err error) {
defer func() {
err = errors.Wrapf(err, upgradeLogPrefix+"upgrade volume failed")
}()

volumesMap, err := upgradeutil.ListAndUpdateVolumesInProvidedCache(namespace, lhClient, resourceMaps)
if err != nil {
if apierrors.IsNotFound(err) {
return nil
}
return errors.Wrapf(err, "failed to list all existing Longhorn volumes during the volume upgrade")
}

for _, v := range volumesMap {
if v.Spec.BackupTargetName == "" {
v.Spec.BackupTargetName = types.DefaultBackupTargetName
}
}

return nil
}

func upgradeBackupVolumes(namespace string, lhClient *lhclientset.Clientset, resourceMaps map[string]interface{}) (err error) {
defer func() {
err = errors.Wrapf(err, upgradeLogPrefix+"upgrade backup volume failed")
}()

backupVolumeMap, err := upgradeutil.ListAndUpdateBackupVolumesInProvidedCache(namespace, lhClient, resourceMaps)
if err != nil {
if apierrors.IsNotFound(err) {
return nil
}
return errors.Wrapf(err, "failed to list all existing Longhorn BackupVolumes during the Longhorn BackupVolume upgrade")
}

for _, bv := range backupVolumeMap {
if bv.Spec.BackupTargetName == "" {
bv.Spec.BackupTargetName = types.DefaultBackupTargetName
}

if bv.Spec.VolumeName == "" {
bv.Spec.VolumeName = bv.Name
}

if bv.Labels == nil {
bv.Labels = make(map[string]string)
}

_, exists := bv.Labels[types.LonghornLabelBackupVolume]
if !exists {
bv.Labels[types.LonghornLabelBackupVolume] = bv.Spec.VolumeName
}

_, exists = bv.Labels[types.LonghornLabelBackupTarget]
if !exists {
bv.Labels[types.LonghornLabelBackupTarget] = types.DefaultBackupTargetName
}
}

return nil
}

func upgradeBackups(namespace string, lhClient *lhclientset.Clientset, resourceMaps map[string]interface{}) (err error) {
defer func() {
err = errors.Wrapf(err, upgradeLogPrefix+"upgrade backup failed")
}()

backupMap, err := upgradeutil.ListAndUpdateBackupsInProvidedCache(namespace, lhClient, resourceMaps)
if err != nil {
if apierrors.IsNotFound(err) {
return nil
}
return errors.Wrapf(err, "failed to list all existing Longhorn Backups during the Longhorn Backup upgrade")
}

for _, b := range backupMap {
if b.Spec.BackupTargetName == "" {
b.Spec.BackupTargetName = types.DefaultBackupTargetName
}

if b.Labels == nil {
b.Labels = make(map[string]string)
}

_, exists := b.Labels[types.LonghornLabelBackupTarget]
if !exists {
b.Labels[types.LonghornLabelBackupTarget] = b.Spec.BackupTargetName
}

_, exists = b.Labels[types.LonghornLabelBackupVolume]
if !exists {
b.Labels[types.LonghornLabelBackupVolume] = b.Status.VolumeName
}
}

return nil
}

func upgradeBackupBackingImages(namespace string, lhClient *lhclientset.Clientset, resourceMaps map[string]interface{}) (err error) {
defer func() {
err = errors.Wrapf(err, upgradeLogPrefix+"upgrade backup backing images failed")
}()

backupBackingImageMap, err := upgradeutil.ListAndUpdateBackupBackingImagesInProvidedCache(namespace, lhClient, resourceMaps)
if err != nil {
if apierrors.IsNotFound(err) {
return nil
}
return errors.Wrapf(err, "failed to list all existing Longhorn Backups during the Longhorn Backup Backing Images upgrade")
}

for _, bbi := range backupBackingImageMap {
if bbi.Spec.BackingImage == "" {
bbi.Spec.BackingImage = bbi.Status.BackingImage
}

if bbi.Spec.BackupTargetName == "" {
bbi.Spec.BackupTargetName = types.DefaultBackupTargetName
}

if bbi.Labels == nil {
bbi.Labels = make(map[string]string)
}

_, exists := bbi.Labels[types.LonghornLabelBackupTarget]
if !exists {
bbi.Labels[types.LonghornLabelBackupTarget] = bbi.Spec.BackupTargetName
}

_, exists = bbi.Labels[types.LonghornLabelBackingImage]
if !exists {
bbi.Labels[types.LonghornLabelBackingImage] = bbi.Spec.BackingImage
}
}

return nil
}

func upgradeBackingImageDataSources(namespace string, lhClient *lhclientset.Clientset, resourceMaps map[string]interface{}) (err error) {
defer func() {
err = errors.Wrapf(err, upgradeLogPrefix+"upgrade backing image data source failed")
}()

backingImageDataSourcesMap, err := upgradeutil.ListAndUpdateBackingImageDataSourcesInProvidedCache(namespace, lhClient, resourceMaps)
if err != nil {
if apierrors.IsNotFound(err) {
return nil
}
return errors.Wrapf(err, "failed to list all existing Longhorn Backups during the Longhorn Backup Backing Images upgrade")
}

for _, bids := range backingImageDataSourcesMap {
if _, exists := bids.Spec.Parameters[longhorn.DataSourceTypeRestoreParameterBackupTargetName]; !exists {
bids.Spec.Parameters[longhorn.DataSourceTypeRestoreParameterBackupTargetName] = types.DefaultBackupTargetName
}
}
return nil
}

func upgradeBackingImages(namespace string, lhClient *lhclientset.Clientset, resourceMaps map[string]interface{}) (err error) {
defer func() {
err = errors.Wrapf(err, upgradeLogPrefix+"upgrade backing image failed")
Expand Down

0 comments on commit e23a124

Please sign in to comment.