sbcli-pre 1.2.5__zip → 1.2.6__zip
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/PKG-INFO +1 -1
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/env_var +1 -1
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/sbcli_pre.egg-info/PKG-INFO +1 -1
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/sbcli_pre.egg-info/SOURCES.txt +5 -3
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_cli/cli.py +113 -115
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/cluster_ops.py +138 -235
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/constants.py +5 -7
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/controllers/caching_node_controller.py +8 -6
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/controllers/cluster_events.py +9 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/controllers/device_controller.py +56 -63
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/controllers/events_controller.py +5 -3
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/controllers/health_controller.py +30 -40
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/controllers/lvol_controller.py +51 -38
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/controllers/pool_controller.py +8 -4
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/controllers/snapshot_controller.py +9 -3
- sbcli_pre-1.2.6/simplyblock_core/controllers/tasks_controller.py +103 -0
- sbcli_pre-1.2.6/simplyblock_core/controllers/tasks_events.py +37 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/distr_controller.py +13 -9
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/kv_store.py +47 -20
- sbcli_pre-1.2.6/simplyblock_core/mgmt_node_ops.py +205 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/models/events.py +9 -1
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/models/job_schedule.py +6 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/models/nvme_device.py +42 -4
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/models/storage_node.py +9 -1
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/rpc_client.py +55 -10
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/scripts/__init__.py +0 -4
- sbcli_pre-1.2.5/simplyblock_core/scripts/alerting/alert_resources.yaml → sbcli_pre-1.2.6/simplyblock_core/scripts/alerting/alert_resources.yaml.j2 +54 -5
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/scripts/dashboards/cluster.json +1 -1
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/scripts/deploy_stack.sh +9 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/scripts/docker-compose-swarm-monitoring.yml +32 -15
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/scripts/docker-compose-swarm.yml +17 -2
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/scripts/haproxy.cfg +15 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/scripts/install_deps.sh +3 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/scripts/stack_deploy_wait.sh +1 -1
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/services/capacity_and_stats_collector.py +1 -1
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/services/device_monitor.py +5 -46
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/services/distr_event_collector.py +10 -11
- sbcli_pre-1.2.6/simplyblock_core/services/health_check_service.py +134 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/services/lvol_monitor.py +1 -1
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/services/lvol_stat_collector.py +1 -1
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/services/port_stat_collector.py +0 -1
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/services/storage_node_monitor.py +49 -44
- sbcli_pre-1.2.6/simplyblock_core/services/tasks_runner_migration.py +61 -0
- sbcli_pre-1.2.5/simplyblock_core/services/job_tasks.py → sbcli_pre-1.2.6/simplyblock_core/services/tasks_runner_restart.py +95 -46
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/snode_client.py +12 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/storage_node_ops.py +525 -336
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/utils.py +46 -1
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/blueprints/snode_ops.py +103 -25
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/blueprints/web_api_cluster.py +20 -43
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/blueprints/web_api_device.py +10 -7
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/blueprints/web_api_lvol.py +9 -5
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/blueprints/web_api_pool.py +14 -5
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/blueprints/web_api_storage_node.py +3 -10
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/node_utils.py +0 -2
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/utils.py +8 -0
- sbcli_pre-1.2.5/simplyblock_core/mgmt_node_ops.py +0 -80
- sbcli_pre-1.2.5/simplyblock_core/scripts/apply_dashboard.sh +0 -22
- sbcli_pre-1.2.5/simplyblock_core/services/health_check_service.py +0 -136
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/README.md +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/pyproject.toml +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/sbcli_pre.egg-info/dependency_links.txt +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/sbcli_pre.egg-info/entry_points.txt +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/sbcli_pre.egg-info/requires.txt +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/sbcli_pre.egg-info/top_level.txt +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/setup.cfg +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/setup.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_cli/main.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/__init__.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/cnode_client.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/compute_node_ops.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/controllers/__init__.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/controllers/device_events.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/controllers/lvol_events.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/controllers/mgmt_events.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/controllers/pool_events.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/controllers/snapshot_events.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/controllers/storage_events.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/models/__init__.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/models/base_model.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/models/caching_node.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/models/cluster.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/models/compute_node.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/models/deployer.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/models/global_settings.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/models/iface.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/models/lvol_model.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/models/mgmt_node.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/models/pool.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/models/port_stat.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/models/snapshot.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/models/stats.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/pci_utils.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/scripts/alerting/alert_rules.yaml +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/scripts/clean_local_storage_deploy.sh +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/scripts/config_docker.sh +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/scripts/dashboards/devices.json +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/scripts/dashboards/lvols.json +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/scripts/dashboards/node-exporter.json +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/scripts/dashboards/nodes.json +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/scripts/dashboards/pools.json +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/scripts/datasource.yml +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/scripts/db_config_double.sh +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/scripts/db_config_single.sh +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/scripts/prometheus.yml +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/scripts/run_ssh.sh +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/scripts/set_db_config.sh +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/services/__init__.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/services/caching_node_monitor.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/services/cap_monitor.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/services/install_service.sh +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/services/log_agg_service.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/services/mgmt_node_monitor.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/services/remove_service.sh +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/services/service_template.service +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_core/shell_utils.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/__init__.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/app.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/auth_middleware.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/blueprints/__init__.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/blueprints/caching_node_ops.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/blueprints/caching_node_ops_k8s.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/blueprints/node_api_basic.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/blueprints/node_api_caching_docker.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/blueprints/node_api_caching_ks.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/blueprints/web_api_caching_node.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/blueprints/web_api_deployer.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/blueprints/web_api_mgmt_node.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/blueprints/web_api_snapshot.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/caching_node_app.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/caching_node_app_k8s.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/node_webapp.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/snode_app.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/static/delete.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/static/deploy.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/static/deploy_cnode.yaml +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/static/deploy_spdk.yaml +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/static/is_up.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/static/list_deps.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/static/rpac.yaml +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/static/tst.py +0 -0
- {sbcli_pre-1.2.5 → sbcli_pre-1.2.6}/simplyblock_web/templates/deploy_spdk.yaml.j2 +0 -0
@@ -23,7 +23,7 @@ def _generate_string(length):
|
|
23
23
|
string.ascii_letters + string.digits) for _ in range(length))
|
24
24
|
|
25
25
|
|
26
|
-
def add_pool(name, pool_max, lvol_max, max_rw_iops, max_rw_mbytes, max_r_mbytes, max_w_mbytes, has_secret):
|
26
|
+
def add_pool(name, pool_max, lvol_max, max_rw_iops, max_rw_mbytes, max_r_mbytes, max_w_mbytes, has_secret, cluster_id):
|
27
27
|
|
28
28
|
if not name:
|
29
29
|
logger.error("Pool name is empty!")
|
@@ -34,6 +34,11 @@ def add_pool(name, pool_max, lvol_max, max_rw_iops, max_rw_mbytes, max_r_mbytes,
|
|
34
34
|
logger.error(f"Pool found with the same name: {name}")
|
35
35
|
return False
|
36
36
|
|
37
|
+
cluster = db_controller.get_cluster_by_id(cluster_id)
|
38
|
+
if not cluster:
|
39
|
+
logger.error(f"Cluster not found: {cluster_id}")
|
40
|
+
return False
|
41
|
+
|
37
42
|
pool_max = pool_max or 0
|
38
43
|
lvol_max = lvol_max or 0
|
39
44
|
max_rw_iops = max_rw_iops or 0
|
@@ -46,7 +51,6 @@ def add_pool(name, pool_max, lvol_max, max_rw_iops, max_rw_mbytes, max_r_mbytes,
|
|
46
51
|
logger.error("max_rw_mbytes must be greater than max_w_mbytes and max_r_mbytes")
|
47
52
|
return False
|
48
53
|
|
49
|
-
cluster = db_controller.get_clusters()[0]
|
50
54
|
logger.info("Adding pool")
|
51
55
|
pool = Pool()
|
52
56
|
pool.id = str(uuid.uuid4())
|
@@ -136,8 +140,8 @@ def delete_pool(uuid):
|
|
136
140
|
return True
|
137
141
|
|
138
142
|
|
139
|
-
def list_pools(is_json):
|
140
|
-
pools = db_controller.get_pools()
|
143
|
+
def list_pools(is_json, cluster_id=None):
|
144
|
+
pools = db_controller.get_pools(cluster_id)
|
141
145
|
data = []
|
142
146
|
for pool in pools:
|
143
147
|
data.append({
|
@@ -49,7 +49,7 @@ def add(lvol_id, snapshot_name):
|
|
49
49
|
ret = rpc_client.bdev_distrib_create(
|
50
50
|
base_name, new_vuid, lvol.ndcs, lvol.npcs, num_blocks,
|
51
51
|
lvol.distr_bs, lvol_controller.get_jm_names(snode), lvol.distr_chunk_bs,
|
52
|
-
None, None, lvol.distr_page_size)
|
52
|
+
None, None, lvol.distr_page_size, dev_cpu_mask=snode.dev_cpu_mask)
|
53
53
|
if not ret:
|
54
54
|
logger.error("Failed to create Distr bdev")
|
55
55
|
return False, "Failed to create Distr bdev"
|
@@ -119,7 +119,12 @@ def delete(snapshot_uuid):
|
|
119
119
|
logger.error(f"Snapshot not found {snapshot_uuid}")
|
120
120
|
return False
|
121
121
|
|
122
|
-
|
122
|
+
snode = db_controller.get_storage_node_by_id(snap.lvol.node_id)
|
123
|
+
if not snode:
|
124
|
+
logger.error(f"Storage node not found {snap.lvol.node_id}")
|
125
|
+
return False
|
126
|
+
|
127
|
+
for lvol in db_controller.get_lvols(snode.cluster_id):
|
123
128
|
if lvol.cloned_from_snap and lvol.cloned_from_snap == snapshot_uuid:
|
124
129
|
logger.warning(f"Soft delete snapshot with clones, lvol ID: {lvol.get_id()}")
|
125
130
|
snap.deleted = True
|
@@ -227,7 +232,8 @@ def clone(snapshot_id, clone_name, new_size=0):
|
|
227
232
|
name = f"distr_{new_vuid}_1"
|
228
233
|
ret = rpc_client.bdev_distrib_create(
|
229
234
|
name, new_vuid, lvol.ndcs, lvol.npcs, num_blocks,
|
230
|
-
lvol.distr_bs, jm_names, lvol.distr_chunk_bs, None, None, lvol.distr_page_size
|
235
|
+
lvol.distr_bs, jm_names, lvol.distr_chunk_bs, None, None, lvol.distr_page_size,
|
236
|
+
dev_cpu_mask=snode.dev_cpu_mask)
|
231
237
|
if not ret:
|
232
238
|
msg="Failed to create Distr bdev"
|
233
239
|
logger.error(msg)
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# coding=utf-8
|
2
|
+
import logging
|
3
|
+
import time
|
4
|
+
import uuid
|
5
|
+
|
6
|
+
from simplyblock_core import kv_store, constants, utils
|
7
|
+
from simplyblock_core.controllers import tasks_events
|
8
|
+
from simplyblock_core.models.job_schedule import JobSchedule
|
9
|
+
|
10
|
+
logger = logging.getLogger()
|
11
|
+
db_controller = kv_store.DBController()
|
12
|
+
|
13
|
+
|
14
|
+
def _validate_new_task_node_restart(cluster_id, node_id):
|
15
|
+
tasks = db_controller.get_job_tasks(cluster_id)
|
16
|
+
for task in tasks:
|
17
|
+
if task.function_name == JobSchedule.FN_NODE_RESTART and task.node_id == node_id:
|
18
|
+
if task.status != JobSchedule.STATUS_DONE:
|
19
|
+
logger.info(f"Task found, skip adding new task: {task.get_id()}")
|
20
|
+
return False
|
21
|
+
return True
|
22
|
+
|
23
|
+
|
24
|
+
def _validate_new_task_dev_restart(cluster_id, node_id, device_id):
|
25
|
+
tasks = db_controller.get_job_tasks(cluster_id)
|
26
|
+
for task in tasks:
|
27
|
+
if task.function_name == JobSchedule.FN_DEV_RESTART and task.device_id == device_id:
|
28
|
+
if task.status != JobSchedule.STATUS_DONE:
|
29
|
+
logger.info(f"Task found, skip adding new task: {task.get_id()}")
|
30
|
+
return False
|
31
|
+
elif task.function_name == JobSchedule.FN_NODE_RESTART and task.node_id == node_id:
|
32
|
+
if task.status != JobSchedule.STATUS_DONE:
|
33
|
+
logger.info(f"Task found, skip adding new task: {task.get_id()}")
|
34
|
+
return False
|
35
|
+
return True
|
36
|
+
|
37
|
+
|
38
|
+
def _add_task(function_name, cluster_id, node_id, device_id):
|
39
|
+
|
40
|
+
if function_name in [JobSchedule.FN_DEV_RESTART, JobSchedule.FN_DEV_MIG]:
|
41
|
+
if not _validate_new_task_dev_restart(cluster_id, node_id, device_id):
|
42
|
+
return False
|
43
|
+
elif function_name == JobSchedule.FN_NODE_RESTART:
|
44
|
+
if not _validate_new_task_node_restart(cluster_id, node_id):
|
45
|
+
return False
|
46
|
+
|
47
|
+
task_obj = JobSchedule()
|
48
|
+
task_obj.uuid = str(uuid.uuid4())
|
49
|
+
task_obj.cluster_id = cluster_id
|
50
|
+
task_obj.node_id = node_id
|
51
|
+
task_obj.device_id = device_id
|
52
|
+
task_obj.date = int(time.time())
|
53
|
+
task_obj.function_name = function_name
|
54
|
+
task_obj.status = JobSchedule.STATUS_NEW
|
55
|
+
task_obj.write_to_db(db_controller.kv_store)
|
56
|
+
tasks_events.task_create(task_obj)
|
57
|
+
return task_obj.uuid
|
58
|
+
|
59
|
+
|
60
|
+
def add_device_mig_task(device_id):
|
61
|
+
device = db_controller.get_storage_devices(device_id)
|
62
|
+
return _add_task(JobSchedule.FN_DEV_MIG, device.cluster_id, device.node_id, device.get_id())
|
63
|
+
|
64
|
+
|
65
|
+
def add_device_to_auto_restart(device):
|
66
|
+
return _add_task(JobSchedule.FN_DEV_RESTART, device.cluster_id, device.node_id, device.get_id())
|
67
|
+
|
68
|
+
|
69
|
+
def add_node_to_auto_restart(node):
|
70
|
+
return _add_task(JobSchedule.FN_NODE_RESTART, node.cluster_id, node.get_id(), "")
|
71
|
+
|
72
|
+
|
73
|
+
def list_tasks(cluster_id):
|
74
|
+
cluster = db_controller.get_cluster_by_id(cluster_id)
|
75
|
+
if not cluster:
|
76
|
+
logger.error("Cluster not found: %s", cluster_id)
|
77
|
+
return False
|
78
|
+
|
79
|
+
data = []
|
80
|
+
tasks = db_controller.get_job_tasks(cluster_id)
|
81
|
+
for task in tasks:
|
82
|
+
data.append({
|
83
|
+
"Task ID": task.uuid,
|
84
|
+
"Target ID": task.device_id or task.node_id,
|
85
|
+
"Function": task.function_name,
|
86
|
+
"Retry": f"{task.retry}/{constants.TASK_EXEC_RETRY_COUNT}",
|
87
|
+
"Status": task.status,
|
88
|
+
"Result": task.function_result,
|
89
|
+
"Date": time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(task.date)),
|
90
|
+
})
|
91
|
+
return utils.print_table(data)
|
92
|
+
|
93
|
+
|
94
|
+
def cancel_task(task_id):
|
95
|
+
task = db_controller.get_task_by_id(task_id)
|
96
|
+
if not task:
|
97
|
+
logger.error("Task not found: %s", task_id)
|
98
|
+
return False
|
99
|
+
|
100
|
+
task.canceled = True
|
101
|
+
task.write_to_db(db_controller.kv_store)
|
102
|
+
tasks_events.task_canceled(task)
|
103
|
+
return True
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# coding=utf-8
|
2
|
+
import logging
|
3
|
+
|
4
|
+
from simplyblock_core.controllers import events_controller as ec
|
5
|
+
from simplyblock_core.kv_store import DBController
|
6
|
+
|
7
|
+
logger = logging.getLogger()
|
8
|
+
db_controller = DBController()
|
9
|
+
|
10
|
+
|
11
|
+
def _task_event(task, message, caused_by, event):
|
12
|
+
ec.log_event_cluster(
|
13
|
+
cluster_id=task.cluster_id,
|
14
|
+
domain=ec.DOMAIN_CLUSTER,
|
15
|
+
event=event,
|
16
|
+
db_object=task,
|
17
|
+
caused_by=caused_by,
|
18
|
+
message=message,
|
19
|
+
node_id=task.node_id,
|
20
|
+
status=task.status)
|
21
|
+
|
22
|
+
|
23
|
+
def task_create(task, caused_by=ec.CAUSED_BY_CLI):
|
24
|
+
_task_event(task, f"task created: {task.uuid}", caused_by, ec.EVENT_OBJ_CREATED)
|
25
|
+
|
26
|
+
|
27
|
+
def task_updated(task, caused_by=ec.CAUSED_BY_CLI):
|
28
|
+
_task_event(task, f"Task updated: {task.uuid}", caused_by, ec.EVENT_STATUS_CHANGE)
|
29
|
+
|
30
|
+
|
31
|
+
def task_status_change(task, new_state, old_status, caused_by=ec.CAUSED_BY_CLI):
|
32
|
+
_task_event(task, f"task status changed from: {old_status} to: {new_state}", caused_by, ec.EVENT_STATUS_CHANGE)
|
33
|
+
|
34
|
+
|
35
|
+
def task_canceled(task, caused_by=ec.CAUSED_BY_CLI):
|
36
|
+
_task_event(task, f"Task canceled: {task.uuid}", caused_by, ec.EVENT_STATUS_CHANGE)
|
37
|
+
|
@@ -10,8 +10,9 @@ from simplyblock_core.kv_store import DBController
|
|
10
10
|
logger = logging.getLogger()
|
11
11
|
|
12
12
|
|
13
|
-
def send_node_status_event(
|
13
|
+
def send_node_status_event(node, node_status):
|
14
14
|
db_controller = DBController()
|
15
|
+
node_id = node.get_id()
|
15
16
|
logging.info(f"Sending event updates, node: {node_id}, status: {node_status}")
|
16
17
|
node_status_event = {
|
17
18
|
"timestamp": datetime.datetime.now().isoformat("T", "seconds") + 'Z',
|
@@ -20,7 +21,7 @@ def send_node_status_event(node_id, node_status):
|
|
20
21
|
"status": node_status}
|
21
22
|
events = {"events": [node_status_event]}
|
22
23
|
logger.debug(node_status_event)
|
23
|
-
snodes = db_controller.
|
24
|
+
snodes = db_controller.get_storage_nodes_by_cluster_id(node.cluster_id)
|
24
25
|
for node in snodes:
|
25
26
|
if node.status != node.STATUS_ONLINE:
|
26
27
|
continue
|
@@ -29,8 +30,9 @@ def send_node_status_event(node_id, node_status):
|
|
29
30
|
ret = rpc_client.distr_status_events_update(events)
|
30
31
|
|
31
32
|
|
32
|
-
def send_dev_status_event(
|
33
|
+
def send_dev_status_event(device, dev_status):
|
33
34
|
db_controller = DBController()
|
35
|
+
storage_ID = device.cluster_device_order
|
34
36
|
logging.info(f"Sending event updates, device: {storage_ID}, status: {dev_status}")
|
35
37
|
node_status_event = {
|
36
38
|
"timestamp": datetime.datetime.now().isoformat("T", "seconds") + 'Z',
|
@@ -39,7 +41,7 @@ def send_dev_status_event(storage_ID, dev_status):
|
|
39
41
|
"status": dev_status}
|
40
42
|
events = {"events": [node_status_event]}
|
41
43
|
logger.debug(node_status_event)
|
42
|
-
snodes = db_controller.
|
44
|
+
snodes = db_controller.get_storage_nodes_by_cluster_id(device.cluster_id)
|
43
45
|
for node in snodes:
|
44
46
|
if node.status != node.STATUS_ONLINE:
|
45
47
|
continue
|
@@ -52,7 +54,7 @@ def send_dev_status_event(storage_ID, dev_status):
|
|
52
54
|
|
53
55
|
def disconnect_device(device):
|
54
56
|
db_controller = DBController()
|
55
|
-
snodes = db_controller.
|
57
|
+
snodes = db_controller.get_storage_nodes_by_cluster_id(device.cluster_id)
|
56
58
|
for node in snodes:
|
57
59
|
if node.status != node.STATUS_ONLINE:
|
58
60
|
continue
|
@@ -95,7 +97,9 @@ def get_distr_cluster_map(snodes, target_node):
|
|
95
97
|
dev_map[dev.cluster_device_order] = {
|
96
98
|
"UUID": dev.get_id(),
|
97
99
|
"bdev_name": name,
|
98
|
-
"status": dev.status
|
100
|
+
"status": dev.status,
|
101
|
+
"physical_label": dev.physical_label
|
102
|
+
}
|
99
103
|
dev_w_map.append({
|
100
104
|
"weight": dev_w,
|
101
105
|
"id": dev.cluster_device_order})
|
@@ -158,7 +162,7 @@ def parse_distr_cluster_map(map_string):
|
|
158
162
|
"Actual Status": "",
|
159
163
|
"Results": "",
|
160
164
|
}
|
161
|
-
sd = db_controller.
|
165
|
+
sd = db_controller.get_storage_device_by_id(device_id)
|
162
166
|
if sd:
|
163
167
|
data["Actual Status"] = sd.status
|
164
168
|
if sd.status == status:
|
@@ -175,7 +179,7 @@ def parse_distr_cluster_map(map_string):
|
|
175
179
|
|
176
180
|
def send_cluster_map_to_node(node):
|
177
181
|
db_controller = DBController()
|
178
|
-
snodes = db_controller.
|
182
|
+
snodes = db_controller.get_storage_nodes_by_cluster_id(node.cluster_id)
|
179
183
|
rpc_client = RPCClient(node.mgmt_ip, node.rpc_port, node.rpc_username, node.rpc_password)
|
180
184
|
cluster_map_data = get_distr_cluster_map(snodes, node)
|
181
185
|
cluster_map_data['UUID_node_target'] = node.get_id()
|
@@ -189,7 +193,7 @@ def send_cluster_map_to_node(node):
|
|
189
193
|
|
190
194
|
def send_cluster_map_add_node(snode):
|
191
195
|
db_controller = DBController()
|
192
|
-
snodes = db_controller.
|
196
|
+
snodes = db_controller.get_storage_nodes_by_cluster_id(snode.cluster_id)
|
193
197
|
for node in snodes:
|
194
198
|
if node.status != node.STATUS_ONLINE:
|
195
199
|
continue
|
@@ -98,11 +98,19 @@ class DBController:
|
|
98
98
|
nodes.append(n)
|
99
99
|
return sorted(nodes, key=lambda x: x.create_dt)
|
100
100
|
|
101
|
+
def get_storage_node_by_system_id(self, system_id):
|
102
|
+
nodes = StorageNode().read_from_db(self.kv_store)
|
103
|
+
for node in nodes:
|
104
|
+
if node.system_uuid == system_id:
|
105
|
+
return node
|
106
|
+
return None
|
107
|
+
|
101
108
|
def get_storage_node_by_id(self, id):
|
102
109
|
ret = StorageNode().read_from_db(self.kv_store, id)
|
103
110
|
if ret:
|
104
111
|
return ret[0]
|
105
112
|
|
113
|
+
# todo: change this function for multi cluster
|
106
114
|
def get_caching_nodes(self):
|
107
115
|
ret = CachingNode().read_from_db(self.kv_store)
|
108
116
|
ret = sorted(ret, key=lambda x: x.create_dt)
|
@@ -113,6 +121,12 @@ class DBController:
|
|
113
121
|
if ret:
|
114
122
|
return ret[0]
|
115
123
|
|
124
|
+
def get_caching_node_by_system_id(self, system_id):
|
125
|
+
nodes = CachingNode().read_from_db(self.kv_store)
|
126
|
+
for node in nodes:
|
127
|
+
if node.system_uuid == system_id:
|
128
|
+
return node
|
129
|
+
|
116
130
|
def get_caching_node_by_hostname(self, hostname):
|
117
131
|
nodes = self.get_caching_nodes()
|
118
132
|
for node in nodes:
|
@@ -125,20 +139,15 @@ class DBController:
|
|
125
139
|
if node.hostname == hostname:
|
126
140
|
return node
|
127
141
|
|
128
|
-
def
|
129
|
-
# workaround because nvme devices are stored inside the node object itself.
|
142
|
+
def get_storage_device_by_id(self, id):
|
130
143
|
nodes = self.get_storage_nodes()
|
131
|
-
devices = []
|
132
|
-
device = None
|
133
144
|
for node in nodes:
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
return device
|
141
|
-
return devices
|
145
|
+
for dev in node.nvme_devices:
|
146
|
+
if dev.get_id() == id:
|
147
|
+
return dev
|
148
|
+
|
149
|
+
def get_storage_devices(self, id):
|
150
|
+
return self.get_storage_device_by_id(id)
|
142
151
|
|
143
152
|
# Compute node functions
|
144
153
|
def get_compute_node_by_id(self, id):
|
@@ -150,9 +159,15 @@ class DBController:
|
|
150
159
|
ret = ComputeNode().read_from_db(self.kv_store)
|
151
160
|
return ret
|
152
161
|
|
153
|
-
def get_pools(self):
|
154
|
-
|
155
|
-
|
162
|
+
def get_pools(self, cluster_id=None):
|
163
|
+
pools = []
|
164
|
+
if cluster_id:
|
165
|
+
for pool in Pool().read_from_db(self.kv_store):
|
166
|
+
if pool.cluster_id == cluster_id:
|
167
|
+
pools.append(pool)
|
168
|
+
else:
|
169
|
+
pools = Pool().read_from_db(self.kv_store)
|
170
|
+
return pools
|
156
171
|
|
157
172
|
def get_pool_by_id(self, id):
|
158
173
|
ret = Pool().read_from_db(self.kv_store, id)
|
@@ -165,9 +180,16 @@ class DBController:
|
|
165
180
|
if pool.pool_name == name:
|
166
181
|
return pool
|
167
182
|
|
168
|
-
def get_lvols(self):
|
169
|
-
|
170
|
-
|
183
|
+
def get_lvols(self, cluster_id=None):
|
184
|
+
lvols = []
|
185
|
+
if cluster_id:
|
186
|
+
for pool in self.get_pools(cluster_id):
|
187
|
+
if pool.cluster_id == cluster_id:
|
188
|
+
for lv_id in pool.lvols:
|
189
|
+
lvols.append(self.get_lvol_by_id(lv_id))
|
190
|
+
else:
|
191
|
+
lvols = LVol().read_from_db(self.kv_store)
|
192
|
+
return lvols
|
171
193
|
|
172
194
|
def get_snapshots(self):
|
173
195
|
ret = SnapShot().read_from_db(self.kv_store)
|
@@ -259,5 +281,10 @@ class DBController:
|
|
259
281
|
def get_events(self, event_id=""):
|
260
282
|
return EventObj().read_from_db(self.kv_store, id=event_id)
|
261
283
|
|
262
|
-
def get_job_tasks(self, cluster_id):
|
263
|
-
return JobSchedule().read_from_db(self.kv_store, id=cluster_id, reverse=
|
284
|
+
def get_job_tasks(self, cluster_id, reverse=True):
|
285
|
+
return JobSchedule().read_from_db(self.kv_store, id=cluster_id, reverse=reverse)
|
286
|
+
|
287
|
+
def get_task_by_id(self, task_id):
|
288
|
+
for task in self.get_job_tasks(""):
|
289
|
+
if task.uuid == task_id:
|
290
|
+
return task
|
@@ -0,0 +1,205 @@
|
|
1
|
+
# coding=utf-8
|
2
|
+
import json
|
3
|
+
import logging
|
4
|
+
import uuid
|
5
|
+
import time
|
6
|
+
import requests
|
7
|
+
|
8
|
+
import docker
|
9
|
+
|
10
|
+
from simplyblock_core import utils, scripts
|
11
|
+
from simplyblock_core.controllers import mgmt_events
|
12
|
+
from simplyblock_core.kv_store import DBController
|
13
|
+
from simplyblock_core.models.mgmt_node import MgmtNode
|
14
|
+
|
15
|
+
|
16
|
+
logger = logging.getLogger()
|
17
|
+
|
18
|
+
|
19
|
+
def deploy_mgmt_node(cluster_ip, cluster_id, ifname):
|
20
|
+
|
21
|
+
try:
|
22
|
+
resp = requests.get(f"http://{cluster_ip}/cluster/{cluster_id}")
|
23
|
+
resp_json = resp.json()
|
24
|
+
cluster_data = resp_json['results'][0]
|
25
|
+
logger.info(f"Cluster found! NQN:{cluster_data['nqn']}")
|
26
|
+
logger.debug(cluster_data)
|
27
|
+
except Exception as e:
|
28
|
+
logger.error("Error getting cluster data!")
|
29
|
+
logger.error(e)
|
30
|
+
return ""
|
31
|
+
|
32
|
+
logger.info("Installing dependencies...")
|
33
|
+
scripts.install_deps()
|
34
|
+
logger.info("Installing dependencies > Done")
|
35
|
+
|
36
|
+
if not ifname:
|
37
|
+
ifname = "eth0"
|
38
|
+
|
39
|
+
DEV_IP = utils.get_iface_ip(ifname)
|
40
|
+
if not DEV_IP:
|
41
|
+
logger.error(f"Error getting interface ip: {ifname}")
|
42
|
+
return False
|
43
|
+
|
44
|
+
logger.info(f"Node IP: {DEV_IP}")
|
45
|
+
ret = scripts.configure_docker(DEV_IP)
|
46
|
+
|
47
|
+
db_connection = cluster_data['db_connection']
|
48
|
+
scripts.set_db_config(db_connection)
|
49
|
+
time.sleep(1)
|
50
|
+
hostname = utils.get_hostname()
|
51
|
+
db_controller = DBController()
|
52
|
+
nodes = db_controller.get_mgmt_nodes(cluster_id=cluster_id)
|
53
|
+
if not nodes:
|
54
|
+
logger.error("No mgmt nodes was found in the cluster!")
|
55
|
+
return False
|
56
|
+
for node in nodes:
|
57
|
+
if node.hostname == hostname:
|
58
|
+
logger.error("Node already exists in the cluster")
|
59
|
+
return False
|
60
|
+
|
61
|
+
logger.info("Joining docker swarm...")
|
62
|
+
try:
|
63
|
+
cluster_docker = utils.get_docker_client(cluster_id)
|
64
|
+
docker_ip = cluster_docker.info()["Swarm"]["NodeAddr"]
|
65
|
+
join_token = cluster_docker.swarm.attrs['JoinTokens']['Manager']
|
66
|
+
node_docker = docker.DockerClient(base_url=f"tcp://{DEV_IP}:2375", version="auto")
|
67
|
+
if node_docker.info()["Swarm"]["LocalNodeState"] == "active":
|
68
|
+
logger.info("Node is part of another swarm, leaving swarm")
|
69
|
+
try:
|
70
|
+
cluster_docker.nodes.get(node_docker.info()["Swarm"]["NodeID"]).remove(force=True)
|
71
|
+
except:
|
72
|
+
pass
|
73
|
+
node_docker.swarm.leave(force=True)
|
74
|
+
time.sleep(5)
|
75
|
+
|
76
|
+
node_docker.swarm.join([f"{docker_ip}:2377"], join_token)
|
77
|
+
|
78
|
+
retries = 10
|
79
|
+
while retries > 0:
|
80
|
+
if node_docker.info()["Swarm"]["LocalNodeState"] == "active":
|
81
|
+
break
|
82
|
+
logger.info("Waiting for node to be active...")
|
83
|
+
retries -= 1
|
84
|
+
time.sleep(2)
|
85
|
+
logger.info("Joining docker swarm > Done")
|
86
|
+
time.sleep(5)
|
87
|
+
|
88
|
+
except Exception as e:
|
89
|
+
raise e
|
90
|
+
|
91
|
+
logger.info("Adding management node object")
|
92
|
+
node_id = add_mgmt_node(DEV_IP, cluster_id)
|
93
|
+
|
94
|
+
# check if ha setting is required
|
95
|
+
nodes = db_controller.get_mgmt_nodes(cluster_id=cluster_id)
|
96
|
+
if len(nodes) >= 3:
|
97
|
+
logger.info("Waiting for FDB container to be active...")
|
98
|
+
fdb_cont = None
|
99
|
+
retries = 30
|
100
|
+
while retries > 0 and fdb_cont is None:
|
101
|
+
logger.info("Looking for FDB container...")
|
102
|
+
for cont in node_docker.containers.list(all=True):
|
103
|
+
logger.debug(cont.attrs['Name'])
|
104
|
+
if cont.attrs['Name'].startswith("/app_fdb"):
|
105
|
+
fdb_cont = cont
|
106
|
+
break
|
107
|
+
if fdb_cont:
|
108
|
+
logger.info("FDB container found")
|
109
|
+
break
|
110
|
+
else:
|
111
|
+
retries -= 1
|
112
|
+
time.sleep(5)
|
113
|
+
|
114
|
+
if not fdb_cont:
|
115
|
+
logger.warning("FDB container was not found")
|
116
|
+
else:
|
117
|
+
retries = 10
|
118
|
+
while retries > 0:
|
119
|
+
info = node_docker.containers.get(fdb_cont.attrs['Id'])
|
120
|
+
status = info.attrs['State']["Status"]
|
121
|
+
is_running = info.attrs['State']["Running"]
|
122
|
+
if not is_running:
|
123
|
+
logger.info("Container is not running, waiting...")
|
124
|
+
time.sleep(3)
|
125
|
+
retries -= 1
|
126
|
+
else:
|
127
|
+
logger.info(f"Container status: {status}, Is Running: {is_running}")
|
128
|
+
break
|
129
|
+
|
130
|
+
logger.info("Configuring Double DB...")
|
131
|
+
time.sleep(3)
|
132
|
+
scripts.set_db_config_double()
|
133
|
+
for cl in db_controller.get_clusters():
|
134
|
+
cl.ha_type = "ha"
|
135
|
+
cl.write_to_db(db_controller.kv_store)
|
136
|
+
|
137
|
+
logger.info("Node joined the cluster")
|
138
|
+
return node_id
|
139
|
+
|
140
|
+
|
141
|
+
def add_mgmt_node(mgmt_ip, cluster_id=None):
|
142
|
+
db_controller = DBController()
|
143
|
+
hostname = utils.get_hostname()
|
144
|
+
node = db_controller.get_mgmt_node_by_hostname(hostname)
|
145
|
+
if node:
|
146
|
+
logger.error("Node already exists in the cluster")
|
147
|
+
return False
|
148
|
+
|
149
|
+
node = MgmtNode()
|
150
|
+
node.uuid = str(uuid.uuid4())
|
151
|
+
node.hostname = hostname
|
152
|
+
node.docker_ip_port = f"{mgmt_ip}:2375"
|
153
|
+
node.cluster_id = cluster_id
|
154
|
+
node.mgmt_ip = mgmt_ip
|
155
|
+
node.status = MgmtNode.STATUS_ONLINE
|
156
|
+
node.write_to_db(db_controller.kv_store)
|
157
|
+
|
158
|
+
mgmt_events.mgmt_add(node)
|
159
|
+
logger.info("Done")
|
160
|
+
return node.uuid
|
161
|
+
|
162
|
+
|
163
|
+
def list_mgmt_nodes(is_json):
|
164
|
+
db_controller = DBController()
|
165
|
+
nodes = db_controller.get_mgmt_nodes()
|
166
|
+
data = []
|
167
|
+
output = ""
|
168
|
+
|
169
|
+
for node in nodes:
|
170
|
+
logging.debug(node)
|
171
|
+
logging.debug("*" * 20)
|
172
|
+
data.append({
|
173
|
+
"UUID": node.get_id(),
|
174
|
+
"Hostname": node.hostname,
|
175
|
+
"IP": node.mgmt_ip,
|
176
|
+
"Status": node.status,
|
177
|
+
})
|
178
|
+
|
179
|
+
if not data:
|
180
|
+
return output
|
181
|
+
|
182
|
+
if is_json:
|
183
|
+
output = json.dumps(data, indent=2)
|
184
|
+
else:
|
185
|
+
output = utils.print_table(data)
|
186
|
+
return output
|
187
|
+
|
188
|
+
|
189
|
+
def remove_mgmt_node(uuid):
|
190
|
+
db_controller = DBController()
|
191
|
+
snode = db_controller.get_mgmt_node_by_id(uuid)
|
192
|
+
if not snode:
|
193
|
+
logger.error("can not find node")
|
194
|
+
return False
|
195
|
+
|
196
|
+
logging.info("Removing mgmt node")
|
197
|
+
snode.remove(db_controller.kv_store)
|
198
|
+
|
199
|
+
logger.info("Leaving swarm...")
|
200
|
+
node_docker = docker.DockerClient(base_url=f"tcp://{snode.docker_ip_port}", version="auto")
|
201
|
+
node_docker.swarm.leave()
|
202
|
+
|
203
|
+
mgmt_events.mgmt_remove(snode)
|
204
|
+
logging.info("done")
|
205
|
+
|
@@ -1,4 +1,6 @@
|
|
1
1
|
# coding=utf-8
|
2
|
+
from datetime import datetime
|
3
|
+
|
2
4
|
from simplyblock_core.models.base_model import BaseModel
|
3
5
|
|
4
6
|
|
@@ -25,7 +27,7 @@ class EventObj(BaseModel):
|
|
25
27
|
"uuid": {"type": str, 'default': ""},
|
26
28
|
"cluster_uuid": {"type": str, 'default': ""},
|
27
29
|
"node_id": {"type": str, 'default': ""},
|
28
|
-
"date": {"type": int, 'default': 0},
|
30
|
+
"date": {"type": int, 'default': 0}, # in milliseconds
|
29
31
|
|
30
32
|
"event_level": {"type": str, 'default': LEVEL_INFO},
|
31
33
|
|
@@ -49,3 +51,9 @@ class EventObj(BaseModel):
|
|
49
51
|
|
50
52
|
def get_id(self):
|
51
53
|
return "%s/%s/%s" % (self.cluster_uuid, self.date, self.uuid)
|
54
|
+
|
55
|
+
def get_date_string(self):
|
56
|
+
if self.date > 1e10:
|
57
|
+
return str(datetime.fromtimestamp(self.date/1000))
|
58
|
+
else:
|
59
|
+
return str(datetime.fromtimestamp(self.date))
|
@@ -8,6 +8,10 @@ class JobSchedule(BaseModel):
|
|
8
8
|
STATUS_RUNNING = 'running'
|
9
9
|
STATUS_DONE = 'done'
|
10
10
|
|
11
|
+
FN_DEV_RESTART = "device_restart"
|
12
|
+
FN_NODE_RESTART = "node_restart"
|
13
|
+
FN_DEV_MIG = "device_migration"
|
14
|
+
|
11
15
|
attributes = {
|
12
16
|
"uuid": {"type": str, 'default': ""},
|
13
17
|
"cluster_id": {"type": str, 'default': ""},
|
@@ -15,6 +19,8 @@ class JobSchedule(BaseModel):
|
|
15
19
|
"device_id": {"type": str, 'default': ""},
|
16
20
|
"date": {"type": int, 'default': 0},
|
17
21
|
|
22
|
+
"canceled": {"type": bool, 'default': False},
|
23
|
+
|
18
24
|
"function_name": {"type": str, 'default': ""},
|
19
25
|
"function_params": {"type": dict, 'default': {}},
|
20
26
|
"function_result": {"type": str, 'default': ""},
|