Skip to content

Commit

Permalink
fix(e2e): use backup target API if settings are removed
Browse files Browse the repository at this point in the history
ref: longhorn/longhorn 5411, 10043

Signed-off-by: James Lu <[email protected]>
  • Loading branch information
mantissahz authored and derekbit committed Dec 27, 2024
1 parent 90e9c03 commit e23e21e
Show file tree
Hide file tree
Showing 2 changed files with 180 additions and 10 deletions.
117 changes: 117 additions & 0 deletions e2e/libs/backupstore/base.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,42 @@
from abc import ABC, abstractmethod
import hashlib
import os
import re

from kubernetes import client

from utility.utility import get_longhorn_client

SECOND = 1
MINUTE = 60 * SECOND
HOUR = 60 * MINUTE

duration_u = {
"s": SECOND,
"m": MINUTE,
"h": HOUR,
}


def from_k8s_duration_to_seconds(duration_s):
# k8s duration string format such as "3h5m30s"
total = 0
pattern_str = r'([0-9]+)([smh]+)'
pattern = re.compile(pattern_str)
matches = pattern.findall(duration_s)
if not len(matches):
raise Exception("Invalid duration {}".format(duration_s))

for v, u in matches:
total += int(v) * duration_u[u]

return total


class Base(ABC):

DEFAULT_BACKUPTARGET = "default"

def __init__(self):
self.core_api = client.CoreV1Api()
backupstore = os.environ.get('LONGHORN_BACKUPSTORE')
Expand Down Expand Up @@ -34,6 +64,54 @@ def backup_volume_path(self, volume_name):

return backupstore_bv_path

def get_backupstore_url(self):
return get_longhorn_client().by_id_backupTarget(
self.DEFAULT_BACKUPTARGET).backupTargetURL

def get_backupstore_secret(self):
return get_longhorn_client().by_id_backupTarget(
self.DEFAULT_BACKUPTARGET).credentialSecret

def get_backupstore_poll_interval(self):
k8s_duration = get_longhorn_client().by_id_backupTarget(
self.DEFAULT_BACKUPTARGET).pollInterval
return from_k8s_duration_to_seconds(k8s_duration)

def set_backupstore_url(self, url):
bt = get_longhorn_client().by_id_backupTarget(
self.DEFAULT_BACKUPTARGET)
p_interval = from_k8s_duration_to_seconds(bt.pollInterval)
self.update_backupstore(url=url,
credential_secret=bt.credentialSecret,
poll_interval=p_interval)

def set_backupstore_secret(self, secret):
bt = get_longhorn_client().by_id_backupTarget(
self.DEFAULT_BACKUPTARGET)
p_interval = from_k8s_duration_to_seconds(bt.pollInterval)
self.update_backupstore(url=bt.backupTargetURL,
credential_secret=secret,
poll_interval=p_interval)

def set_backupstore_poll_interval(self, poll_interval):
bt = get_longhorn_client().by_id_backupTarget(
self.DEFAULT_BACKUPTARGET)
self.update_backupstore(url=bt.backupTargetURL,
credential_secret=bt.credentialSecret,
poll_interval=poll_interval)

def reset_backupstore(self):
self.update_backupstore()

def update_backupstore(self,
url="", credential_secret="", poll_interval=300):
backup_target = get_longhorn_client().by_id_backupTarget(
self.DEFAULT_BACKUPTARGET)
backup_target.backupTargetUpdate(name=self.DEFAULT_BACKUPTARGET,
backupTargetURL=url,
credentialSecret=credential_secret,
pollInterval=str(poll_interval))

@abstractmethod
def get_backup_volume_prefix(self, volume_name):
return NotImplemented
Expand Down Expand Up @@ -77,3 +155,42 @@ def delete_random_backup_block(self):
@abstractmethod
def count_backup_block_files(self):
return NotImplemented


class BackupStore(Base):

def __init__(self):
super().__init__()

def get_backup_volume_prefix(self, volume_name):
return NotImplemented

def get_backup_cfg_file_path(self, volume_name, backup_name):
return NotImplemented

def get_volume_cfg_file_path(self, volume_name):
return NotImplemented

def get_backup_blocks_dir(self, volume_name):
return NotImplemented

def create_file_in_backupstore(self):
return NotImplemented

def write_backup_cfg_file(self, volume_name, backup_name, data):
return NotImplemented

def delete_file_in_backupstore(self):
return NotImplemented

def delete_backup_cfg_file(self):
return NotImplemented

def delete_volume_cfg_file(self):
return NotImplemented

def delete_random_backup_block(self):
return NotImplemented

def count_backup_block_files(self):
return NotImplemented
73 changes: 63 additions & 10 deletions e2e/libs/setting/setting.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,25 @@
from utility.utility import get_retry_count_and_interval
from utility.utility import logging

from backupstore.base import BackupStore


class Setting:

SETTING_BACKUP_TARGET = "backup-target"
SETTING_BACKUP_TARGET_CREDENTIAL_SECRET = "backup-target-credential-secret"
SETTING_BACKUPSTORE_POLL_INTERVAL = "backupstore-poll-interval"

SETTING_BACKUP_TARGET_NOT_SUPPORTED = \
f"setting {SETTING_BACKUP_TARGET} is not supported"
SETTING_BACKUP_TARGET_CREDENTIAL_SECRET_NOT_SUPPORTED = \
f"setting {SETTING_BACKUP_TARGET_CREDENTIAL_SECRET} is not supported"
SETTING_SETTING_BACKUPSTORE_POLL_INTERVAL_NOT_SUPPORTED = \
f"setting {SETTING_BACKUPSTORE_POLL_INTERVAL} is not supported"

def __init__(self):
self.retry_count, self.retry_interval = get_retry_count_and_interval()
self.backupstore = BackupStore()

def update_setting(self, key, value, retry=True):
if retry:
Expand Down Expand Up @@ -43,23 +54,65 @@ def set_backupstore(self):
backupstore = self.get_backupstore_url()
if backupstore:
backupsettings = backupstore.split("$")
self.update_setting(self.SETTING_BACKUP_TARGET, backupsettings[0])
if len(backupsettings) > 1:
self.update_setting(self.SETTING_BACKUP_TARGET_CREDENTIAL_SECRET, backupsettings[1])

poll_interval = self.get_backupstore_poll_interval()
self.update_setting(self.SETTING_BACKUPSTORE_POLL_INTERVAL, poll_interval)
try:
self.update_setting(self.SETTING_BACKUP_TARGET,
backupsettings[0],
retry=False)
if len(backupsettings) > 1:
self.update_setting(
self.SETTING_BACKUP_TARGET_CREDENTIAL_SECRET,
backupsettings[1],
retry=False)

self.update_setting(self.SETTING_BACKUPSTORE_POLL_INTERVAL,
poll_interval,
retry=False)
except Exception as e:
if self.SETTING_BACKUP_TARGET_NOT_SUPPORTED in e.error.message:
self.backupstore.set_backupstore_url(backupsettings[0])
if len(backupsettings) > 1:
self.backupstore.set_backupstore_secret(
backupsettings[1])
self.backupstore.set_backupstore_poll_interval(
poll_interval)
else:
logging(e)

def reset_backupstore(self):
self.update_setting(self.SETTING_BACKUP_TARGET, "")
self.update_setting(self.SETTING_BACKUP_TARGET_CREDENTIAL_SECRET, "")
self.update_setting(self.SETTING_BACKUPSTORE_POLL_INTERVAL, "300")
try:
self.update_setting(self.SETTING_BACKUP_TARGET, "", retry=False)
self.update_setting(self.SETTING_BACKUP_TARGET_CREDENTIAL_SECRET,
"",
retry=False)
self.update_setting(self.SETTING_BACKUPSTORE_POLL_INTERVAL,
"300",
retry=False)
except Exception as e:
if self.SETTING_BACKUP_TARGET_NOT_SUPPORTED in e.error.message:
self.backupstore.reset_backupstore()
else:
logging(e)

def get_backup_target(self):
return self.get_setting(self.SETTING_BACKUP_TARGET)
try:
return self.get_setting(self.SETTING_BACKUP_TARGET)
except Exception as e:
if self.SETTING_BACKUP_TARGET_NOT_SUPPORTED in e.error.message:
return self.backupstore.get_backupstore_url()
else:
logging(e)

def get_secret(self):
return self.get_setting(self.SETTING_BACKUP_TARGET_CREDENTIAL_SECRET)
try:
return self.get_setting(
self.SETTING_BACKUP_TARGET_CREDENTIAL_SECRET)
except Exception as e:
if (self.SETTING_BACKUP_TARGET_CREDENTIAL_SECRET_NOT_SUPPORTED
in e.error.message):
return self.backupstore.get_backupstore_secret()
else:
logging(e)

def reset_settings(self):
client = get_longhorn_client()
Expand Down

0 comments on commit e23e21e

Please sign in to comment.