Skip to content

Commit 7734277

Browse files
committed
Add mirage cleanup command
1 parent 856f956 commit 7734277

9 files changed

Lines changed: 294 additions & 35 deletions

File tree

node_cli/cli/mirage_node.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@
1919

2020
import click
2121

22-
from node_cli.core.node import get_node_signature, backup, get_node_info
23-
from node_cli.mirage.mirage_node import restore_mirage, request_repair
24-
from node_cli.utils.helper import error_exit, streamed_cmd, abort_if_false, URL_TYPE
22+
from node_cli.core.node import backup, get_node_info, get_node_signature
23+
from node_cli.mirage.mirage_node import cleanup as mirage_cleanup
24+
from node_cli.mirage.mirage_node import request_repair, restore_mirage
25+
from node_cli.utils.helper import URL_TYPE, abort_if_false, error_exit, streamed_cmd
2526
from node_cli.utils.texts import safe_load_texts
2627

2728
TEXTS = safe_load_texts()
@@ -116,3 +117,16 @@ def restore_node(backup_path, env_file, config_only):
116117
)
117118
def repair(snapshot_from: str = '') -> None:
118119
request_repair(snapshot_from=snapshot_from)
120+
121+
122+
@node.command('cleanup', help='Cleanup Mirage node.')
123+
@click.option(
124+
'--yes',
125+
is_flag=True,
126+
callback=abort_if_false,
127+
expose_value=False,
128+
prompt='Are you sure you want to cleanup Mirage node?',
129+
)
130+
@streamed_cmd
131+
def cleanup_node():
132+
mirage_cleanup()

node_cli/core/docker_config.py

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import grp
21
import enum
2+
import grp
33
import json
44
import logging
55
import os
@@ -8,19 +8,17 @@
88
import typing
99
from typing import Optional, Tuple
1010

11-
1211
from node_cli.configs import (
13-
DOCKER_DEAMON_CONFIG_PATH,
1412
DOCKER_DAEMON_HOSTS,
13+
DOCKER_DEAMON_CONFIG_PATH,
1514
DOCKER_SERVICE_CONFIG_DIR,
1615
DOCKER_SERVICE_CONFIG_PATH,
1716
DOCKER_SOCKET_PATH,
1817
NODE_DOCKER_CONFIG_PATH,
1918
SKALE_RUN_DIR,
2019
)
21-
from node_cli.utils.helper import run_cmd
2220
from node_cli.utils.docker_utils import docker_client, get_containers
23-
21+
from node_cli.utils.helper import run_cmd
2422

2523
logger = logging.getLogger(__name__)
2624

@@ -184,3 +182,54 @@ def configure_docker() -> None:
184182
save_docker_group_id(group_id)
185183

186184
logger.info('Docker configuration finished')
185+
186+
187+
def remove_docker_service_override_config() -> None:
188+
if os.path.isfile(DOCKER_SERVICE_CONFIG_PATH):
189+
logger.info('Removing docker service override config')
190+
os.remove(DOCKER_SERVICE_CONFIG_PATH)
191+
192+
193+
def reset_docker_daemon_config() -> None:
194+
if os.path.isfile(DOCKER_DEAMON_CONFIG_PATH):
195+
logger.info('Resetting docker daemon config')
196+
with open(DOCKER_DEAMON_CONFIG_PATH, 'r') as daemon_config:
197+
config = json.load(daemon_config)
198+
199+
# Remove the keys we added
200+
config.pop('live-restore', None)
201+
config.pop('hosts', None)
202+
203+
if config:
204+
# Write back remaining config
205+
with open(DOCKER_DEAMON_CONFIG_PATH, 'w') as daemon_config:
206+
json.dump(config, daemon_config)
207+
else:
208+
# Remove file if empty
209+
os.remove(DOCKER_DEAMON_CONFIG_PATH)
210+
211+
212+
def remove_node_docker_config() -> None:
213+
if os.path.isfile(NODE_DOCKER_CONFIG_PATH):
214+
logger.info('Removing node docker config')
215+
os.remove(NODE_DOCKER_CONFIG_PATH)
216+
217+
218+
def remove_skale_run_dir() -> None:
219+
if os.path.isdir(SKALE_RUN_DIR):
220+
os.rmdir(SKALE_RUN_DIR)
221+
logger.info('Removed SKALE run directory')
222+
223+
224+
def cleanup_docker_configuration() -> None:
225+
"""Cleanup all skale specific docker configuration files and directories"""
226+
logger.info('Cleaning up docker configuration')
227+
228+
remove_docker_service_override_config()
229+
reset_docker_daemon_config()
230+
remove_node_docker_config()
231+
remove_skale_run_dir()
232+
restart_docker_service()
233+
wait_for_socket_initialization()
234+
235+
logger.info('Docker configuration cleanup finished')

node_cli/core/schains.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@
5858
BLUEPRINT_NAME = 'schains'
5959

6060

61+
class NoDataDirForChainError(Exception):
62+
"""Raised when no data directory is found"""
63+
64+
pass
65+
66+
6167
def get_schain_firewall_rules(schain: str) -> None:
6268
status, payload = get_request(
6369
blueprint=BLUEPRINT_NAME, method='firewall-rules', params={'schain_name': schain}
@@ -249,8 +255,17 @@ def ensure_schain_volume(schain: str, schain_type: str, env_type: str) -> None:
249255
logger.warning('Volume %s already exists', schain)
250256

251257

252-
def cleanup_sync_datadir(schain_name: str, base_path: str = SCHAINS_MNT_DIR_SINGLE_CHAIN) -> None:
253-
base_path = os.path.join(base_path, schain_name)
258+
def cleanup_datadir_for_single_chain_node(
259+
chain_name: str = '', base_path: str = SCHAINS_MNT_DIR_SINGLE_CHAIN
260+
) -> None:
261+
if not chain_name:
262+
folders = [f for f in os.listdir(base_path) if os.path.isdir(os.path.join(base_path, f))]
263+
if not folders:
264+
raise NoDataDirForChainError(
265+
f'No data directory found in {base_path}. Please check the path or specify a chain name.'
266+
)
267+
chain_name = folders[0]
268+
base_path = os.path.join(base_path, chain_name)
254269
regular_folders_pattern = f'{base_path}/[!snapshots]*'
255270
logger.info('Removing regular folders')
256271
for filepath in glob.glob(regular_folders_pattern):

node_cli/mirage/mirage_node.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,23 @@
2121
import logging
2222
import time
2323

24-
from node_cli.configs import SKALE_DIR, RESTORE_SLEEP_TIMEOUT
24+
from node_cli.configs import RESTORE_SLEEP_TIMEOUT, SKALE_DIR
2525
from node_cli.configs.env import SKALE_DIR_ENV_FILEPATH
26-
from node_cli.core.node import compose_node_env
26+
from node_cli.core.docker_config import cleanup_docker_configuration
2727
from node_cli.core.host import save_env_params
28+
from node_cli.core.node import compose_node_env
2829
from node_cli.core.static_config import get_static_params
2930
from node_cli.mirage.record.chain_record import ChainRecord
30-
from node_cli.operations import restore_mirage_op
31-
from node_cli.utils.decorators import check_inited, check_not_inited
31+
from node_cli.operations import (
32+
cleanup_mirage_op,
33+
restore_mirage_op,
34+
)
35+
from node_cli.utils.decorators import check_inited, check_not_inited, check_user
3236
from node_cli.utils.exit_codes import CLIExitCodes
3337
from node_cli.utils.helper import error_exit
3438
from node_cli.utils.node_type import NodeType
3539
from node_cli.utils.texts import safe_load_texts
3640

37-
3841
logger = logging.getLogger(__name__)
3942
TEXTS = safe_load_texts()
4043

@@ -64,3 +67,13 @@ def request_repair(snapshot_from: str = '') -> None:
6467
record.set_snapshot_from(snapshot_from)
6568

6669
print(TEXTS['mirage']['node']['repair']['repair_requested'])
70+
71+
72+
@check_inited
73+
@check_user
74+
def cleanup() -> None:
75+
env = compose_node_env(SKALE_DIR_ENV_FILEPATH, save=False, node_type=NodeType.MIRAGE)
76+
chain_name = env['SCHAIN_NAME']
77+
cleanup_mirage_op(env, chain_name)
78+
logger.info('Mirage node was cleaned up, all containers and data removed')
79+
cleanup_docker_configuration()

node_cli/operations/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,9 @@
3232
cleanup_sync as cleanup_sync_op,
3333
configure_nftables,
3434
)
35+
from node_cli.operations.mirage import ( # noqa
36+
update_mirage as update_mirage_op,
37+
MirageUpdateType,
38+
restore_mirage as restore_mirage_op,
39+
cleanup as cleanup_mirage_op,
40+
)

node_cli/operations/base.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,22 @@
1717
# You should have received a copy of the GNU Affero General Public License
1818
# along with this program. If not, see <https://www.gnu.org/licenses/>.
1919

20-
import time
21-
22-
import distro
2320
import functools
2421
import logging
22+
import time
2523
from typing import Dict, Optional
2624

25+
import distro
26+
27+
from node_cli.cli.info import TYPE, VERSION
2728
from node_cli.configs import (
2829
CONTAINER_CONFIG_PATH,
2930
CONTAINER_CONFIG_TMP_PATH,
30-
SKALE_DIR,
3131
GLOBAL_SKALE_DIR,
32+
SKALE_DIR,
3233
)
33-
from node_cli.core.checks import CheckType, run_checks as run_host_checks
34+
from node_cli.core.checks import CheckType
35+
from node_cli.core.checks import run_checks as run_host_checks
3436
from node_cli.core.docker_config import configure_docker
3537
from node_cli.core.host import (
3638
ensure_btrfs_kernel_module_autoloaded,
@@ -40,19 +42,19 @@
4042
from node_cli.core.nftables import configure_nftables
4143
from node_cli.core.nginx import generate_nginx_config
4244
from node_cli.core.node_options import NodeOptions
43-
from node_cli.core.resources import update_resource_allocation, init_shared_space_volume
45+
from node_cli.core.resources import init_shared_space_volume, update_resource_allocation
4446
from node_cli.core.schains import (
47+
cleanup_datadir_for_single_chain_node,
4548
update_node_cli_schain_status,
46-
cleanup_sync_datadir,
4749
)
48-
from node_cli.cli.info import VERSION, TYPE
4950
from node_cli.operations.common import configure_filebeat, configure_flask, unpack_backup_archive
5051
from node_cli.operations.docker_lvmpy import lvmpy_install
5152
from node_cli.operations.skale_node import (
5253
download_skale_node,
5354
sync_skale_node,
5455
update_images,
5556
)
57+
from node_cli.operations.docker_lvmpy import lvmpy_install
5658
from node_cli.operations.volume import (
5759
cleanup_volume_artifacts,
5860
ensure_filestorage_mapping,
@@ -64,12 +66,16 @@
6466
docker_cleanup,
6567
remove_dynamic_containers,
6668
)
69+
<<<<<<< Updated upstream
6770
from node_cli.utils.helper import str_to_bool, rm_dir
6871
from node_cli.utils.meta import get_meta_info, update_meta
72+
=======
73+
from node_cli.utils.helper import rm_dir, str_to_bool
74+
from node_cli.utils.meta import CliMetaManager, MirageCliMetaManager
75+
>>>>>>> Stashed changes
6976
from node_cli.utils.node_type import NodeType
7077
from node_cli.utils.print_formatters import print_failed_requirements_checks
7178

72-
7379
logger = logging.getLogger(__name__)
7480

7581

@@ -508,6 +514,6 @@ def restore_mirage(env, backup_path, config_only=False):
508514

509515
def cleanup_sync(env, schain_name: str) -> None:
510516
turn_off(env, node_type=NodeType.SYNC)
511-
cleanup_sync_datadir(schain_name=schain_name)
517+
cleanup_datadir_for_single_chain_node(schain_name=schain_name)
512518
rm_dir(GLOBAL_SKALE_DIR)
513519
rm_dir(SKALE_DIR)

node_cli/operations/common.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,18 @@
1717
# You should have received a copy of the GNU Affero General Public License
1818
# along with this program. If not, see <https://www.gnu.org/licenses/>.
1919

20+
import logging
2021
import os
22+
import secrets
23+
import shutil
2124
import stat
2225
import tarfile
23-
import logging
24-
import shutil
25-
import secrets
26-
2726
from shutil import copyfile
2827

2928
from node_cli.configs import (
30-
G_CONF_HOME,
3129
FILEBEAT_CONFIG_PATH,
3230
FLASK_SECRET_KEY_FILE,
31+
G_CONF_HOME,
3332
SRC_FILEBEAT_CONFIG_PATH,
3433
)
3534

0 commit comments

Comments
 (0)