Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions simplyblock_cli/cli-reference.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1899,6 +1899,18 @@ commands:
dest: resize
type: size
default: "0"
- name: backup
help: "create backup task for snapshot"
arguments:
- name: "snapshot_id"
help: "Snapshot id"
dest: snapshot_id
type: str
- name: "--delete-after-finish"
help: "Delete the snapshot after backup is completed"
dest: delete_after_finish
type: bool
action: store_true
- name: "qos"
help: "qos commands"
weight: 700
Expand Down Expand Up @@ -1947,3 +1959,48 @@ commands:
type: str
required: false
default: ""
- name: "backup"
help: "FDB Backup operations"
weight: 800
subcommands:
- name: create
help: "Creates an fdb backup"
arguments:
- name: "cluster_id"
help: "Cluster ID to create db backup for"
dest: cluster_id
type: str
- name: list
help: "Lists all fdb backups"
- name: status
help: "get backup status"
- name: restore
help: "restore a backup"
arguments:
- name: "name"
help: "backup class name"
dest: name
type: str
- name: config
help: "Set backup configuration"
arguments:
- name: "--backup-path"
help: 'local backup path, defaults to /etc/foundationdb/backup'
dest: backup_path
type: str
- name: "--backup-frequency"
help: "backup frequency, can be 3h, 1d"
dest: backup_frequency
type: str
- name: "--s3-bucket"
help: 'AWS S3 bucket name'
dest: bucket_name
type: str
- name: "--s3-region"
help: 'AWS S3 region'
dest: region_name
type: str
- name: "--s3-credentials"
help: 'AWS S3 API key and secret, should be supplied like this: [API_KEY]:[API_SECRET]'
dest: backup_credentials
type: str
56 changes: 56 additions & 0 deletions simplyblock_cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def __init__(self):
self.init_storage_pool()
self.init_snapshot()
self.init_qos()
self.init_backup()
super().__init__()

def init_storage_node(self):
Expand Down Expand Up @@ -748,6 +749,7 @@ def init_snapshot(self):
self.init_snapshot__list(subparser)
self.init_snapshot__delete(subparser)
self.init_snapshot__clone(subparser)
self.init_snapshot__backup(subparser)


def init_snapshot__add(self, subparser):
Expand All @@ -770,6 +772,11 @@ def init_snapshot__clone(self, subparser):
subcommand.add_argument('lvol_name', help='Logical volume name', type=str)
argument = subcommand.add_argument('--resize', help='New logical volume size: 10M, 10G, 10(bytes). Can only increase.', type=size_type(), default='0', dest='resize')

def init_snapshot__backup(self, subparser):
subcommand = self.add_sub_command(subparser, 'backup', 'create backup task for snapshot')
subcommand.add_argument('snapshot_id', help='Snapshot id', type=str)
argument = subcommand.add_argument('--delete-after-finish', help='Delete the snapshot after backup is completed', dest='delete_after_finish', action='store_true')


def init_qos(self):
subparser = self.add_command('qos', 'qos commands')
Expand All @@ -795,6 +802,38 @@ def init_qos__delete(self, subparser):
subcommand.add_argument('cluster_id', help='Cluster UUID', type=str, default='')


def init_backup(self):
subparser = self.add_command('backup', 'FDB Backup operations')
self.init_backup__create(subparser)
self.init_backup__list(subparser)
self.init_backup__status(subparser)
self.init_backup__restore(subparser)
self.init_backup__config(subparser)


def init_backup__create(self, subparser):
subcommand = self.add_sub_command(subparser, 'create', 'Creates an fdb backup')
subcommand.add_argument('cluster_id', help='Cluster ID to create db backup for', type=str)

def init_backup__list(self, subparser):
subcommand = self.add_sub_command(subparser, 'list', 'Lists all fdb backups')

def init_backup__status(self, subparser):
subcommand = self.add_sub_command(subparser, 'status', 'get backup status')

def init_backup__restore(self, subparser):
subcommand = self.add_sub_command(subparser, 'restore', 'restore a backup')
subcommand.add_argument('name', help='backup class name', type=str)

def init_backup__config(self, subparser):
subcommand = self.add_sub_command(subparser, 'config', 'Set backup configuration')
argument = subcommand.add_argument('--backup-path', help='local backup path, defaults to /etc/foundationdb/backup', type=str, dest='backup_path')
argument = subcommand.add_argument('--backup-frequency', help='backup frequency, can be 3h, 1d', type=str, dest='backup_frequency')
argument = subcommand.add_argument('--s3-bucket', help='AWS S3 bucket name', type=str, dest='bucket_name')
argument = subcommand.add_argument('--s3-region', help='AWS S3 region', type=str, dest='region_name')
argument = subcommand.add_argument('--s3-credentials', help='AWS S3 API key and secret, should be supplied like this: [API_KEY]:[API_SECRET]', type=str, dest='backup_credentials')


def run(self):
args = self.parser.parse_args()
if args.debug:
Expand Down Expand Up @@ -1113,6 +1152,8 @@ def run(self):
ret = self.snapshot__delete(sub_command, args)
elif sub_command in ['clone']:
ret = self.snapshot__clone(sub_command, args)
elif sub_command in ['backup']:
ret = self.snapshot__backup(sub_command, args)
else:
self.parser.print_help()

Expand All @@ -1127,6 +1168,21 @@ def run(self):
else:
self.parser.print_help()

elif args.command in ['backup']:
sub_command = args_dict['backup']
if sub_command in ['create']:
ret = self.backup__create(sub_command, args)
elif sub_command in ['list']:
ret = self.backup__list(sub_command, args)
elif sub_command in ['status']:
ret = self.backup__status(sub_command, args)
elif sub_command in ['restore']:
ret = self.backup__restore(sub_command, args)
elif sub_command in ['config']:
ret = self.backup__config(sub_command, args)
else:
self.parser.print_help()

else:
self.parser.print_help()

Expand Down
20 changes: 19 additions & 1 deletion simplyblock_cli/clibase.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from simplyblock_core import storage_node_ops as storage_ops
from simplyblock_core import mgmt_node_ops as mgmt_ops
from simplyblock_core.controllers import pool_controller, lvol_controller, snapshot_controller, device_controller, \
tasks_controller, qos_controller
tasks_controller, qos_controller, backup_controller
from simplyblock_core.controllers import health_controller
from simplyblock_core.models.pool import Pool
from simplyblock_core.models.cluster import Cluster
Expand Down Expand Up @@ -657,6 +657,9 @@ def snapshot__clone(self, sub_command, args):
success, details = snapshot_controller.clone(args.snapshot_id, args.lvol_name, new_size)
return details

def snapshot__backup(self, sub_command, args):
return snapshot_controller.create_backup(args.snapshot_id, args.delete_after_finish)

def qos__add(self, sub_command, args):
return qos_controller.add_class(args.name, args.weight, args.cluster_id)

Expand All @@ -666,6 +669,21 @@ def qos__list(self, sub_command, args):
def qos__delete(self, sub_command, args):
return qos_controller.delete_class(args.name, args.cluster_id)

def backup__create(self, sub_command, args):
return tasks_controller.add_backup_task(args.cluster_id)

def backup__list(self, sub_command, args):
return backup_controller.list_backups()

def backup__status(self, sub_command, args):
return backup_controller.backup_status()

def backup__restore(self, sub_command, args):
return backup_controller.backup_restore(args.name)

def backup__config(self, sub_command, args):
return backup_controller.backup_configure(args.backup_path, args.backup_frequency, args.bucket_name, args.region_name, args.backup_credentials)

def storage_node_list_devices(self, args):
node_id = args.node_id
is_json = args.json
Expand Down
15 changes: 15 additions & 0 deletions simplyblock_core/cluster_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -1193,6 +1193,13 @@ def update_cluster(cluster_id, mgmt_only=False, restart=False, spdk_image=None,
service_file="python simplyblock_core/services/tasks_runner_jc_comp.py",
service_image=service_image)

if "app_BackupService" not in service_names:
utils.create_docker_service(
cluster_docker=cluster_docker,
service_name="app_BackupService",
service_file="python simplyblock_core/services/tasks_runner_fdb_backup.py",
service_image=service_image)

logger.info("Done updating mgmt cluster")

elif cluster.mode == "kubernetes":
Expand Down Expand Up @@ -1239,6 +1246,14 @@ def update_cluster(cluster_id, mgmt_only=False, restart=False, spdk_image=None,
service_file="simplyblock_core/services/snapshot_monitor.py",
container_image=service_image)

if "simplyblock-backup-service" not in deployment_names:
utils.create_k8s_service(
namespace=namespace,
deployment_name="simplyblock-backup-service",
container_name="snapshot-monitor",
service_file="simplyblock_core/services/tasks_runner_fdb_backup.py",
container_image=service_image)

# Update DaemonSets
daemonsets = apps_v1.list_namespaced_daemon_set(namespace=namespace)
for ds in daemonsets.items:
Expand Down
1 change: 1 addition & 0 deletions simplyblock_core/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def get_config_var(name, default=None):
KVD_DB_VERSION = 730
KVD_DB_FILE_PATH = os.getenv('FDB_CLUSTER_FILE', '/etc/foundationdb/fdb.cluster')
KVD_DB_TIMEOUT_MS = 10000
KVD_DB_BACKUP_PATH = "file:///etc/foundationdb/backup"
SPK_DIR = '/home/ec2-user/spdk'
LOG_LEVEL = logging.INFO
LOG_WEB_LEVEL = logging.DEBUG
Expand Down
Loading
Loading