Skip to content

Commit

Permalink
Add click restore command in schains group
Browse files Browse the repository at this point in the history
  • Loading branch information
badrogger committed Sep 14, 2023
1 parent 418c957 commit 2c04a0d
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 11 deletions.
8 changes: 8 additions & 0 deletions node_cli/cli/schains.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from node_cli.core.schains import (
describe,
get_schain_firewall_rules,
restore_schain_from_snapshot,
show_config,
show_dkg_info,
show_schains,
Expand Down Expand Up @@ -95,3 +96,10 @@ def repair(schain_name: str, snapshot_from: Optional[str] = None) -> None:
)
def info_(schain_name: str, json_format: bool) -> None:
describe(schain_name, raw=json_format)


@schains.command('restore', help='Restore schain from local snapshot')
@click.argument('schain_name')
@click.argument('snapshot_path')
def restore(schain_name: str, snapshot_path: str) -> None:
restore_schain_from_snapshot(schain_name, snapshot_path)
26 changes: 15 additions & 11 deletions node_cli/core/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -357,26 +357,30 @@ def is_base_containers_alive():
return len(skale_containers) >= BASE_CONTAINERS_AMOUNT


def get_node_info(format):
def get_node_info_plain():
status, payload = get_request(
blueprint=BLUEPRINT_NAME,
method='info'
)
if status == 'ok':
node_info = payload['node_info']
if format == 'json':
print(node_info)
elif node_info['status'] == NodeStatuses.NOT_CREATED.value:
print(TEXTS['service']['node_not_registered'])
else:
print_node_info(
node_info,
get_node_status(int(node_info['status']))
)
return payload['node_info']
else:
error_exit(payload, exit_code=CLIExitCodes.BAD_API_RESPONSE)


def get_node_info(format):
node_info = get_node_info_plain()
if format == 'json':
print(node_info)
elif node_info['status'] == NodeStatuses.NOT_CREATED.value:
print(TEXTS['service']['node_not_registered'])
else:
print_node_info(
node_info,
get_node_status(int(node_info['status']))
)


def get_node_status(status):
node_status = NodeStatuses(status).name
return TEXTS['node']['status'][node_status]
Expand Down
61 changes: 61 additions & 0 deletions node_cli/core/schains.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import logging
import os
import pprint
import shutil
from pathlib import Path

from typing import Optional

from node_cli.core.node import get_node_info_plain
from node_cli.utils.helper import get_request, post_request, error_exit
from node_cli.utils.exit_codes import CLIExitCodes
from node_cli.utils.print_formatters import (
Expand All @@ -11,6 +15,8 @@
print_schain_info,
print_schains
)
from node_cli.utils.helper import run_cmd
from lvmpy.src.core import mount, volume_mountpoint


logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -98,3 +104,58 @@ def describe(schain: str, raw=False) -> None:
print_schain_info(payload, raw=raw)
else:
error_exit(payload, exit_code=CLIExitCodes.BAD_API_RESPONSE)


def btrfs_set_readonly_false(subvolume_path: str) -> None:
run_cmd(['btrfs', 'property', 'set', '-ts', subvolume_path, 'ro', 'false'])


def btrfs_receive_binary(src_path: str, binary_path: str) -> None:
run_cmd(['btrfs', 'receive', '-f', binary_path, src_path])


def get_block_number_from_path(snapshot_path: str) -> int:
stem = Path(snapshot_path).stem
try:
int(stem.split('-')[-1])
except ValueError:
return -1


def get_node_id() -> int:
info = get_node_info_plain()
return info['node_id']


def migrate_prices_and_blocks(src_path: str, node_id: int) -> None:
prices_path = os.path.join(f'prices_{node_id}.db')
shutil.move(Path(src_path).glob('prices_*.db'), prices_path)
blocks_path = os.path.join(f'blocks_{node_id}.db')
shutil.move(Path(src_path).glob('blocks_*.db'), blocks_path)


def fillin_snapshot_folder(src_path: str, block_number: int) -> None:
snapshot_folder_path = os.path.join(
src_path, 'snapshots', str(block_number))
os.makedirs(snapshot_folder_path, exist_ok=True)
for subvolume_path in os.listdir(src_path):
# TODO: Finalise
snapshot_path_for_subvolume = snapshot_folder_path(subvolume_path)
btrfs_set_readonly_false(subvolume_path)


def restore_schain_from_snapshot(schain: str, snapshot_path: str) -> None:
block_number = get_block_number_from_path(snapshot_path)
if block_number == -1:
logger.error('Invalid snapshot path format')
return
node_id = get_node_id()

mount(schain)
src_path = volume_mountpoint(schain)
btrfs_receive_binary(src_path, snapshot_path)

for subvolume_path in os.listdir(src_path):
btrfs_set_readonly_false(subvolume_path)

migrate_prices_and_blocks(src_path, node_id)

0 comments on commit 2c04a0d

Please sign in to comment.