Skip to content

Commit

Permalink
Merge pull request #786 from skalenetwork/safe-update
Browse files Browse the repository at this point in the history
Check that it is safe to update before running procedure
  • Loading branch information
badrogger authored Oct 9, 2024
2 parents ae52add + 62ca678 commit 5a53762
Show file tree
Hide file tree
Showing 11 changed files with 362 additions and 284 deletions.
22 changes: 18 additions & 4 deletions node_cli/cli/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,17 @@ def init_node(env_file):
expose_value=False,
prompt='Are you sure you want to update SKALE node software?')
@click.option('--pull-config', 'pull_config_for_schain', hidden=True, type=str)
@click.option(
'--unsafe',
'unsafe_ok',
help='Allow unsafe update',
hidden=True,
is_flag=True
)
@click.argument('env_file')
@streamed_cmd
def update_node(env_file, pull_config_for_schain):
update(env_file, pull_config_for_schain)
def update_node(env_file, pull_config_for_schain, unsafe_ok):
update(env_file, pull_config_for_schain, unsafe_ok)


@node.command('signature', help='Get node signature for given validator id')
Expand Down Expand Up @@ -173,9 +180,16 @@ def remove_node_from_maintenance():
@click.option('--yes', is_flag=True, callback=abort_if_false,
expose_value=False,
prompt='Are you sure you want to turn off the node?')
@click.option(
'--unsafe',
'unsafe_ok',
help='Allow unsafe turn-off',
hidden=True,
is_flag=True
)
@streamed_cmd
def _turn_off(maintenance_on):
turn_off(maintenance_on)
def _turn_off(maintenance_on, unsafe_ok):
turn_off(maintenance_on, unsafe_ok)


@node.command('turn-on', help='Turn on the node')
Expand Down
9 changes: 8 additions & 1 deletion node_cli/cli/sync_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,14 @@ def _init_sync(env_file, archive, catchup, historic_state):
@click.option('--yes', is_flag=True, callback=abort_if_false,
expose_value=False,
prompt='Are you sure you want to update SKALE node software?')
@click.option(
'--unsafe',
'unsafe_ok',
help='Allow unsafe update',
hidden=True,
is_flag=True
)
@click.argument('env_file')
@streamed_cmd
def _update_sync(env_file):
def _update_sync(env_file, unsafe_ok):
update_sync(env_file)
30 changes: 23 additions & 7 deletions node_cli/configs/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,22 @@

ROUTES = {
'v1': {
'node': ['info', 'register', 'maintenance-on', 'maintenance-off', 'signature',
'send-tg-notification', 'exit/start', 'exit/status', 'set-domain-name'],
'node': [
'info',
'register',
'maintenance-on',
'maintenance-off',
'signature',
'send-tg-notification',
'exit/start',
'exit/status',
'set-domain-name',
'update-safe',
],
'health': ['containers', 'schains', 'sgx'],
'schains': ['config', 'list', 'dkg-statuses', 'firewall-rules', 'repair', 'get'],
'ssl': ['status', 'upload'],
'wallet': ['info', 'send-eth']
'wallet': ['info', 'send-eth'],
}
}

Expand All @@ -40,8 +50,11 @@ class RouteNotFoundException(Exception):


def route_exists(blueprint, method, api_version):
return ROUTES.get(api_version) and ROUTES[api_version].get(blueprint) and \
method in ROUTES[api_version][blueprint]
return (
ROUTES.get(api_version)
and ROUTES[api_version].get(blueprint)
and method in ROUTES[api_version][blueprint]
)


def get_route(blueprint, method, api_version=CURRENT_API_VERSION, check=True):
Expand All @@ -53,5 +66,8 @@ def get_route(blueprint, method, api_version=CURRENT_API_VERSION, check=True):

def get_all_available_routes(api_version=CURRENT_API_VERSION):
routes = ROUTES[api_version]
return [get_route(blueprint, method, api_version) for blueprint in routes
for method in routes[blueprint]]
return [
get_route(blueprint, method, api_version)
for blueprint in routes
for method in routes[blueprint]
]
26 changes: 23 additions & 3 deletions node_cli/core/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,16 @@ class NodeStatuses(Enum):
NOT_CREATED = 5


def is_update_safe() -> bool:
status, payload = get_request(BLUEPRINT_NAME, 'update-safe')
if status == 'error':
return False
safe = payload['update_safe']
if not safe:
logger.info('Locked schains: %s', payload['unsafe_chains'])
return safe


@check_inited
@check_user
def register_node(name, p2p_ip,
Expand Down Expand Up @@ -206,7 +216,10 @@ def init_sync(

@check_inited
@check_user
def update_sync(env_filepath):
def update_sync(env_filepath: str, unsafe_ok: bool = False) -> None:
if not unsafe_ok and not is_update_safe():
error_msg = 'Cannot update safely'
error_exit(error_msg, exit_code=CLIExitCodes.UNSAFE_UPDATE)
logger.info('Node update started')
configure_firewall_rules()
env = get_node_env(env_filepath, sync_node=True)
Expand Down Expand Up @@ -259,7 +272,11 @@ def get_node_env(

@check_inited
@check_user
def update(env_filepath, pull_config_for_schain):
def update(env_filepath: str, pull_config_for_schain: str, unsafe_ok: bool = False) -> None:
if not unsafe_ok and not is_update_safe():
error_msg = 'Cannot update safely'
error_exit(error_msg, exit_code=CLIExitCodes.UNSAFE_UPDATE)

logger.info('Node update started')
configure_firewall_rules()
env = get_node_env(
Expand Down Expand Up @@ -388,7 +405,10 @@ def set_maintenance_mode_off():

@check_inited
@check_user
def turn_off(maintenance_on):
def turn_off(maintenance_on: bool = False, unsafe_ok: bool = False) -> None:
if not unsafe_ok and not is_update_safe():
error_msg = 'Cannot turn off safely'
error_exit(error_msg, exit_code=CLIExitCodes.UNSAFE_UPDATE)
if maintenance_on:
set_maintenance_mode_on()
turn_off_op()
Expand Down
1 change: 1 addition & 0 deletions node_cli/utils/exit_codes.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ class CLIExitCodes(IntEnum):
REVERT_ERROR = 6
BAD_USER_ERROR = 7
NODE_STATE_ERROR = 8
UNSAFE_UPDATE = 9
3 changes: 2 additions & 1 deletion node_cli/utils/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import sys
import uuid
from urllib.parse import urlparse
from typing import Optional

import yaml
import shutil
Expand Down Expand Up @@ -230,7 +231,7 @@ def post_request(blueprint, method, json=None, files=None):
return status, payload


def get_request(blueprint, method, params=None):
def get_request(blueprint: str, method: str, params: Optional[dict] = None) -> tuple[str, str]:
route = get_route(blueprint, method)
url = construct_url(route)
try:
Expand Down
Loading

0 comments on commit 5a53762

Please sign in to comment.