sbcli-pre 1.2.3__zip → 1.2.5__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.
Files changed (141) hide show
  1. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/PKG-INFO +20 -5
  2. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/README.md +19 -4
  3. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/env_var +1 -1
  4. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/sbcli_pre.egg-info/PKG-INFO +20 -5
  5. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/sbcli_pre.egg-info/SOURCES.txt +5 -5
  6. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_cli/cli.py +115 -113
  7. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/cluster_ops.py +238 -141
  8. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/constants.py +7 -5
  9. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/controllers/caching_node_controller.py +6 -8
  10. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/controllers/cluster_events.py +0 -9
  11. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/controllers/device_controller.py +63 -56
  12. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/controllers/events_controller.py +3 -5
  13. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/controllers/health_controller.py +40 -30
  14. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/controllers/lvol_controller.py +36 -42
  15. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/controllers/pool_controller.py +4 -8
  16. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/controllers/snapshot_controller.py +3 -9
  17. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/distr_controller.py +9 -13
  18. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/kv_store.py +29 -47
  19. sbcli_pre-1.2.5/simplyblock_core/mgmt_node_ops.py +80 -0
  20. sbcli_pre-1.2.5/simplyblock_core/models/deployer.py +62 -0
  21. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/models/events.py +1 -9
  22. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/models/job_schedule.py +0 -6
  23. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/models/nvme_device.py +4 -42
  24. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/models/storage_node.py +1 -9
  25. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/rpc_client.py +10 -55
  26. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/scripts/__init__.py +4 -0
  27. sbcli_pre-1.2.3/simplyblock_core/scripts/alerting/alert_resources.yaml.j2 → sbcli_pre-1.2.5/simplyblock_core/scripts/alerting/alert_resources.yaml +5 -54
  28. sbcli_pre-1.2.5/simplyblock_core/scripts/apply_dashboard.sh +22 -0
  29. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/scripts/dashboards/cluster.json +1 -1
  30. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/scripts/deploy_stack.sh +0 -2
  31. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/scripts/docker-compose-swarm-monitoring.yml +13 -22
  32. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/scripts/docker-compose-swarm.yml +2 -17
  33. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/scripts/haproxy.cfg +0 -15
  34. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/scripts/install_deps.sh +0 -1
  35. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/services/capacity_and_stats_collector.py +1 -1
  36. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/services/device_monitor.py +44 -3
  37. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/services/distr_event_collector.py +11 -10
  38. sbcli_pre-1.2.5/simplyblock_core/services/health_check_service.py +136 -0
  39. sbcli_pre-1.2.3/simplyblock_core/services/tasks_runner_restart.py → sbcli_pre-1.2.5/simplyblock_core/services/job_tasks.py +46 -93
  40. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/services/lvol_monitor.py +1 -1
  41. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/services/lvol_stat_collector.py +1 -1
  42. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/services/port_stat_collector.py +1 -0
  43. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/services/storage_node_monitor.py +44 -49
  44. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/snode_client.py +0 -12
  45. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/storage_node_ops.py +336 -525
  46. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/utils.py +1 -46
  47. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/app.py +2 -1
  48. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/blueprints/snode_ops.py +25 -103
  49. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/blueprints/web_api_cluster.py +43 -20
  50. sbcli_pre-1.2.5/simplyblock_web/blueprints/web_api_deployer.py +394 -0
  51. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/blueprints/web_api_device.py +7 -10
  52. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/blueprints/web_api_lvol.py +5 -9
  53. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/blueprints/web_api_pool.py +5 -14
  54. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/blueprints/web_api_storage_node.py +10 -3
  55. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/node_utils.py +2 -0
  56. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/utils.py +0 -8
  57. sbcli_pre-1.2.3/simplyblock_core/controllers/tasks_controller.py +0 -103
  58. sbcli_pre-1.2.3/simplyblock_core/controllers/tasks_events.py +0 -37
  59. sbcli_pre-1.2.3/simplyblock_core/mgmt_node_ops.py +0 -205
  60. sbcli_pre-1.2.3/simplyblock_core/services/health_check_service.py +0 -134
  61. sbcli_pre-1.2.3/simplyblock_core/services/tasks_runner_migration.py +0 -61
  62. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/pyproject.toml +0 -0
  63. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/sbcli_pre.egg-info/dependency_links.txt +0 -0
  64. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/sbcli_pre.egg-info/entry_points.txt +0 -0
  65. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/sbcli_pre.egg-info/requires.txt +0 -0
  66. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/sbcli_pre.egg-info/top_level.txt +0 -0
  67. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/setup.cfg +0 -0
  68. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/setup.py +0 -0
  69. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_cli/main.py +0 -0
  70. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/__init__.py +0 -0
  71. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/cnode_client.py +0 -0
  72. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/compute_node_ops.py +0 -0
  73. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/controllers/__init__.py +0 -0
  74. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/controllers/device_events.py +0 -0
  75. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/controllers/lvol_events.py +0 -0
  76. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/controllers/mgmt_events.py +0 -0
  77. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/controllers/pool_events.py +0 -0
  78. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/controllers/snapshot_events.py +0 -0
  79. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/controllers/storage_events.py +0 -0
  80. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/models/__init__.py +0 -0
  81. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/models/base_model.py +0 -0
  82. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/models/caching_node.py +0 -0
  83. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/models/cluster.py +0 -0
  84. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/models/compute_node.py +0 -0
  85. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/models/global_settings.py +0 -0
  86. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/models/iface.py +0 -0
  87. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/models/lvol_model.py +0 -0
  88. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/models/mgmt_node.py +0 -0
  89. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/models/pool.py +0 -0
  90. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/models/port_stat.py +0 -0
  91. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/models/snapshot.py +0 -0
  92. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/models/stats.py +0 -0
  93. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/pci_utils.py +0 -0
  94. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/scripts/alerting/alert_rules.yaml +0 -0
  95. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/scripts/clean_local_storage_deploy.sh +0 -0
  96. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/scripts/config_docker.sh +0 -0
  97. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/scripts/dashboards/devices.json +0 -0
  98. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/scripts/dashboards/lvols.json +0 -0
  99. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/scripts/dashboards/node-exporter.json +0 -0
  100. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/scripts/dashboards/nodes.json +0 -0
  101. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/scripts/dashboards/pools.json +0 -0
  102. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/scripts/datasource.yml +0 -0
  103. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/scripts/db_config_double.sh +0 -0
  104. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/scripts/db_config_single.sh +0 -0
  105. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/scripts/prometheus.yml +0 -0
  106. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/scripts/run_ssh.sh +0 -0
  107. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/scripts/set_db_config.sh +0 -0
  108. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/scripts/stack_deploy_wait.sh +0 -0
  109. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/services/__init__.py +0 -0
  110. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/services/caching_node_monitor.py +0 -0
  111. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/services/cap_monitor.py +0 -0
  112. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/services/install_service.sh +0 -0
  113. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/services/log_agg_service.py +0 -0
  114. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/services/mgmt_node_monitor.py +0 -0
  115. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/services/remove_service.sh +0 -0
  116. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/services/service_template.service +0 -0
  117. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_core/shell_utils.py +0 -0
  118. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/__init__.py +0 -0
  119. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/auth_middleware.py +0 -0
  120. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/blueprints/__init__.py +0 -0
  121. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/blueprints/caching_node_ops.py +0 -0
  122. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/blueprints/caching_node_ops_k8s.py +0 -0
  123. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/blueprints/node_api_basic.py +0 -0
  124. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/blueprints/node_api_caching_docker.py +0 -0
  125. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/blueprints/node_api_caching_ks.py +0 -0
  126. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/blueprints/web_api_caching_node.py +0 -0
  127. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/blueprints/web_api_mgmt_node.py +0 -0
  128. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/blueprints/web_api_snapshot.py +0 -0
  129. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/caching_node_app.py +0 -0
  130. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/caching_node_app_k8s.py +0 -0
  131. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/node_webapp.py +0 -0
  132. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/snode_app.py +0 -0
  133. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/static/delete.py +0 -0
  134. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/static/deploy.py +0 -0
  135. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/static/deploy_cnode.yaml +0 -0
  136. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/static/deploy_spdk.yaml +0 -0
  137. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/static/is_up.py +0 -0
  138. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/static/list_deps.py +0 -0
  139. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/static/rpac.yaml +0 -0
  140. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/static/tst.py +0 -0
  141. {sbcli_pre-1.2.3 → sbcli_pre-1.2.5}/simplyblock_web/templates/deploy_spdk.yaml.j2 +0 -0
@@ -1,19 +1,15 @@
1
1
  # coding=utf-8
2
2
  import json
3
3
  import logging
4
+ import math
4
5
  import os
5
- import re
6
- import tempfile
7
- import shutil
8
- import subprocess
9
6
  import time
10
7
  import uuid
11
8
 
12
9
  import docker
13
10
  import requests
14
- from jinja2 import Environment, FileSystemLoader
15
11
 
16
- from simplyblock_core import utils, scripts, constants, mgmt_node_ops, storage_node_ops
12
+ from simplyblock_core import utils, scripts, constants, mgmt_node_ops, storage_node_ops, shell_utils
17
13
  from simplyblock_core.controllers import cluster_events, device_controller
18
14
  from simplyblock_core.kv_store import DBController
19
15
  from simplyblock_core.models.cluster import Cluster
@@ -21,33 +17,10 @@ from simplyblock_core.models.nvme_device import NVMeDevice
21
17
  from simplyblock_core.models.storage_node import StorageNode
22
18
 
23
19
  logger = logging.getLogger()
24
- TOP_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
25
-
26
- def _add_grafana_dashboards(username, password, cluster_ip):
27
- url = f"http://{username}:{password}@{cluster_ip}/grafana/api/dashboards/import"
28
- headers = {'Content-Type': 'application/json'}
29
- dirpath, _, filenames = next(os.walk(os.path.join(constants.INSTALL_DIR, "scripts", "dashboards")))
30
- ret = True
31
- for filename in filenames:
32
- with open(os.path.join(dirpath, filename), 'r') as f:
33
- st = f.read()
34
- # st = st.replace("$Cluster", cluster_id)
35
- st = json.loads(st)
36
- payload = json.dumps(st)
37
- response = requests.post(url, headers=headers, data=payload)
38
- logger.debug(response.status_code)
39
- logger.debug(response.text)
40
- if response.status_code == 200:
41
- resp = response.json()
42
- logger.info(f"Dashboard: {resp['title']}, imported: {resp['imported']}")
43
- else:
44
- logger.error(f"Error importing dashboard, status code:{response.status_code} text:{response.text}")
45
- ret = False
46
- return ret
47
20
 
48
21
 
49
22
  def _add_graylog_input(cluster_ip, password):
50
- url = f"http://{cluster_ip}/graylog/api/system/inputs"
23
+ url = f"http://{cluster_ip}:9000/api/system/inputs"
51
24
  payload = json.dumps({
52
25
  "title": "spdk log input",
53
26
  "type": "org.graylog2.inputs.gelf.udp.GELFUDPInput",
@@ -74,8 +47,7 @@ def _add_graylog_input(cluster_ip, password):
74
47
 
75
48
 
76
49
  def create_cluster(blk_size, page_size_in_blocks, cli_pass,
77
- cap_warn, cap_crit, prov_cap_warn, prov_cap_crit, ifname, log_del_interval, metrics_retention_period,
78
- contact_point, grafana_endpoint):
50
+ cap_warn, cap_crit, prov_cap_warn, prov_cap_crit, ifname, log_del_interval, metrics_retention_period):
79
51
  logger.info("Installing dependencies...")
80
52
  ret = scripts.install_deps()
81
53
  logger.info("Installing dependencies > Done")
@@ -130,44 +102,6 @@ def create_cluster(blk_size, page_size_in_blocks, cli_pass,
130
102
  if prov_cap_crit and prov_cap_crit > 0:
131
103
  c.prov_cap_crit = prov_cap_crit
132
104
 
133
- alerts_template_folder = os.path.join(TOP_DIR, "simplyblock_core/scripts/alerting/")
134
- alert_resources_file = "alert_resources.yaml"
135
-
136
- env = Environment(loader=FileSystemLoader(alerts_template_folder), trim_blocks=True, lstrip_blocks=True)
137
- template = env.get_template(f'{alert_resources_file}.j2')
138
-
139
- slack_pattern = re.compile(r"https://hooks\.slack\.com/services/\S+")
140
- email_pattern = re.compile(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$")
141
-
142
- if slack_pattern.match(contact_point):
143
- ALERT_TYPE = "slack"
144
- elif email_pattern.match(contact_point):
145
- ALERT_TYPE = "email"
146
- else:
147
- ALERT_TYPE = "slack"
148
- contact_point = 'https://hooks.slack.com/services/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'
149
-
150
- values = {
151
- 'CONTACT_POINT': contact_point,
152
- 'GRAFANA_ENDPOINT': grafana_endpoint,
153
- 'ALERT_TYPE': ALERT_TYPE,
154
- }
155
-
156
- temp_dir = tempfile.mkdtemp()
157
-
158
- temp_file_path = os.path.join(temp_dir, alert_resources_file)
159
- with open(temp_file_path, 'w') as file:
160
- file.write(template.render(values))
161
-
162
- destination_file_path = os.path.join(alerts_template_folder, alert_resources_file)
163
- try:
164
- subprocess.run(['sudo', '-v'], check=True) # sudo -v checks if the current user has sudo permissions
165
- subprocess.run(['sudo', 'mv', temp_file_path, destination_file_path], check=True)
166
- print(f"File moved to {destination_file_path} successfully.")
167
- except subprocess.CalledProcessError as e:
168
- print(f"An error occurred: {e}")
169
- shutil.rmtree(temp_dir)
170
-
171
105
  logger.info("Deploying swarm stack ...")
172
106
  ret = scripts.deploy_stack(cli_pass, DEV_IP, constants.SIMPLY_BLOCK_DOCKER_IMAGE, c.secret, c.uuid, log_del_interval, metrics_retention_period)
173
107
  logger.info("Deploying swarm stack > Done")
@@ -188,8 +122,8 @@ def create_cluster(blk_size, page_size_in_blocks, cli_pass,
188
122
  mgmt_node_ops.add_mgmt_node(DEV_IP, c.uuid)
189
123
 
190
124
  logger.info("Applying dashboard...")
191
- ret = _add_grafana_dashboards("admin", c.secret, DEV_IP)
192
- logger.info(f"Applying dashboard > {ret}")
125
+ ret = scripts.apply_dashboard(c.secret)
126
+ logger.info("Applying dashboard > Done")
193
127
 
194
128
  logger.info("New Cluster has been created")
195
129
  logger.info(c.uuid)
@@ -242,39 +176,203 @@ def deploy_spdk(node_docker, spdk_cpu_mask, spdk_mem):
242
176
  break
243
177
 
244
178
 
245
- def add_cluster(blk_size, page_size_in_blocks, cap_warn, cap_crit, prov_cap_warn, prov_cap_crit):
246
- db_controller = DBController()
247
- clusters = db_controller.get_clusters()
248
- if not clusters:
249
- logger.error("No previous clusters found!")
179
+ def join_cluster(cluster_ip, cluster_id, role, ifname, data_nics, spdk_cpu_mask, spdk_mem): # role: ["management", "storage"]
180
+
181
+ if role not in ["management", "storage", "storage-alloc"]:
182
+ logger.error(f"Unknown role: {role}")
250
183
  return False
251
184
 
252
- default_cluster = clusters[0]
253
- logger.info("Adding new cluster")
254
- cluster = Cluster()
255
- cluster.uuid = str(uuid.uuid4())
256
- cluster.blk_size = blk_size
257
- cluster.page_size_in_blocks = page_size_in_blocks
258
- cluster.ha_type = default_cluster.ha_type
259
- cluster.nqn = f"{constants.CLUSTER_NQN}:{cluster.uuid}"
260
- cluster.cli_pass = default_cluster.cli_pass
261
- cluster.secret = default_cluster.secret
262
- cluster.db_connection = default_cluster.db_connection
263
- if cap_warn and cap_warn > 0:
264
- cluster.cap_warn = cap_warn
265
- if cap_crit and cap_crit > 0:
266
- cluster.cap_crit = cap_crit
267
- if prov_cap_warn and prov_cap_warn > 0:
268
- cluster.prov_cap_warn = prov_cap_warn
269
- if prov_cap_crit and prov_cap_crit > 0:
270
- cluster.prov_cap_crit = prov_cap_crit
185
+ try:
186
+ resp = requests.get(f"http://{cluster_ip}/cluster/{cluster_id}")
187
+ resp_json = resp.json()
188
+ cluster_data = resp_json['results'][0]
189
+ logger.info(f"Cluster found! NQN:{cluster_data['nqn']}")
190
+ logger.debug(cluster_data)
191
+ except Exception as e:
192
+ logger.error("Error getting cluster data!")
193
+ logger.error(e)
194
+ return ""
271
195
 
272
- cluster.status = Cluster.STATUS_ACTIVE
273
- cluster.updated_at = int(time.time())
274
- cluster.write_to_db(db_controller.kv_store)
275
- cluster_events.cluster_create(cluster)
196
+ logger.info("Installing dependencies...")
197
+ ret = scripts.install_deps()
198
+ logger.info("Installing dependencies > Done")
199
+
200
+ if not ifname:
201
+ ifname = "eth0"
202
+
203
+ DEV_IP = utils.get_iface_ip(ifname)
204
+ if not DEV_IP:
205
+ logger.error(f"Error getting interface ip: {ifname}")
206
+ return False
207
+
208
+ logger.info(f"Node IP: {DEV_IP}")
209
+ ret = scripts.configure_docker(DEV_IP)
276
210
 
277
- return cluster.get_id()
211
+ db_connection = cluster_data['db_connection']
212
+ ret = scripts.set_db_config(db_connection)
213
+
214
+ if role == "storage":
215
+ logger.info("Deploying SPDK")
216
+ node_cpu_count = os.cpu_count()
217
+ if spdk_cpu_mask:
218
+ requested_cpu_count = len(format(int(spdk_cpu_mask, 16), 'b'))
219
+ if requested_cpu_count > node_cpu_count:
220
+ logger.error(f"The requested cpu count: {requested_cpu_count} "
221
+ f"is larger than the node's cpu count: {node_cpu_count}")
222
+ return False
223
+ else:
224
+ spdk_cpu_mask = hex(int(math.pow(2, node_cpu_count))-1)
225
+ if spdk_mem:
226
+ spdk_mem = int(spdk_mem/(1024*1024))
227
+ else:
228
+ spdk_mem = 4096
229
+ node_docker = docker.DockerClient(base_url=f"tcp://{DEV_IP}:2375", version="auto", timeout=60*5)
230
+ deploy_spdk(node_docker, spdk_cpu_mask, spdk_mem)
231
+ time.sleep(5)
232
+
233
+ logger.info("Joining docker swarm...")
234
+ db_controller = DBController()
235
+ nodes = db_controller.get_mgmt_nodes(cluster_id=cluster_id)
236
+ if not nodes:
237
+ logger.error("No mgmt nodes was found in the cluster!")
238
+ exit(1)
239
+
240
+ try:
241
+ cluster_docker = utils.get_docker_client(cluster_id)
242
+ docker_ip = cluster_docker.info()["Swarm"]["NodeAddr"]
243
+
244
+ if role == 'management':
245
+ join_token = cluster_docker.swarm.attrs['JoinTokens']['Manager']
246
+ else:
247
+ join_token = cluster_docker.swarm.attrs['JoinTokens']['Worker']
248
+
249
+ node_docker = docker.DockerClient(base_url=f"tcp://{DEV_IP}:2375", version="auto")
250
+ if node_docker.info()["Swarm"]["LocalNodeState"] == "active":
251
+ logger.info("Node is part of another swarm, leaving swarm")
252
+ try:
253
+ cluster_docker.nodes.get(node_docker.info()["Swarm"]["NodeID"]).remove(force=True)
254
+ except:
255
+ pass
256
+ node_docker.swarm.leave(force=True)
257
+ time.sleep(5)
258
+ node_docker.swarm.join([f"{docker_ip}:2377"], join_token)
259
+
260
+ retries = 10
261
+ while retries > 0:
262
+ if node_docker.info()["Swarm"]["LocalNodeState"] == "active":
263
+ break
264
+ logger.info("Waiting for node to be active...")
265
+ retries -= 1
266
+ time.sleep(2)
267
+ logger.info("Joining docker swarm > Done")
268
+ time.sleep(5)
269
+
270
+ except Exception as e:
271
+ raise e
272
+
273
+ if role == 'management':
274
+ mgmt_node_ops.add_mgmt_node(DEV_IP, cluster_id)
275
+ cluster_obj = db_controller.get_cluster_by_id(cluster_id)
276
+ nodes = db_controller.get_mgmt_nodes(cluster_id=cluster_id)
277
+ if len(nodes) >= 3:
278
+ logger.info("Waiting for FDB container to be active...")
279
+ fdb_cont = None
280
+ retries = 30
281
+ while retries > 0 and fdb_cont is None:
282
+ logger.info("Looking for FDB container...")
283
+ for cont in node_docker.containers.list(all=True):
284
+ logger.debug(cont.attrs['Name'])
285
+ if cont.attrs['Name'].startswith("/app_fdb"):
286
+ fdb_cont = cont
287
+ break
288
+ if fdb_cont:
289
+ logger.info("FDB container found")
290
+ break
291
+ else:
292
+ retries -= 1
293
+ time.sleep(5)
294
+
295
+ if not fdb_cont:
296
+ logger.warning("FDB container was not found")
297
+ else:
298
+ retries = 10
299
+ while retries > 0:
300
+ info = node_docker.containers.get(fdb_cont.attrs['Id'])
301
+ status = info.attrs['State']["Status"]
302
+ is_running = info.attrs['State']["Running"]
303
+ if not is_running:
304
+ logger.info("Container is not running, waiting...")
305
+ time.sleep(3)
306
+ retries -= 1
307
+ else:
308
+ logger.info(f"Container status: {status}, Is Running: {is_running}")
309
+ break
310
+
311
+ logger.info("Configuring Double DB...")
312
+ time.sleep(3)
313
+ out = scripts.set_db_config_double()
314
+ cluster_obj.ha_type = "ha"
315
+ cluster_obj.write_to_db(db_controller.kv_store)
316
+ logger.info("Configuring DB > Done")
317
+
318
+ elif role == "storage":
319
+ # add storage node
320
+ fdb_cont = None
321
+ retries = 30
322
+ while retries > 0 and fdb_cont is None:
323
+ logger.info("Looking for SpdkAppProxy container...")
324
+ for cont in node_docker.containers.list(all=True):
325
+ logger.debug(cont.attrs['Name'])
326
+ if cont.attrs['Name'].startswith("/app_SpdkAppProxy"):
327
+ fdb_cont = cont
328
+ break
329
+ if fdb_cont:
330
+ logger.info("SpdkAppProxy container found")
331
+ break
332
+ else:
333
+ retries -= 1
334
+ time.sleep(5)
335
+
336
+ if not fdb_cont:
337
+ logger.warning("SpdkAppProxy container was not found")
338
+ else:
339
+ retries = 10
340
+ while retries > 0:
341
+ info = node_docker.containers.get(fdb_cont.attrs['Id'])
342
+ status = info.attrs['State']["Status"]
343
+ is_running = info.attrs['State']["Running"]
344
+ if not is_running:
345
+ logger.info("Container is not running, waiting...")
346
+ time.sleep(3)
347
+ retries -= 1
348
+ else:
349
+ logger.info(f"Container status: {status}, Is Running: {is_running}")
350
+ break
351
+ storage_node_ops.add_storage_node(cluster_id, ifname, data_nics)
352
+
353
+ logger.info("Node joined the cluster")
354
+
355
+
356
+ def add_cluster(blk_size, page_size_in_blocks, model_ids, tls,
357
+ auth_hosts_only, dhchap, nqn, iscsi, cli_pass):
358
+ db_controller = DBController()
359
+ logger.info("Adding new cluster")
360
+ c = Cluster()
361
+ c.uuid = str(uuid.uuid4())
362
+ c.blk_size = blk_size
363
+ c.page_size_in_blocks = page_size_in_blocks
364
+ c.model_ids = model_ids
365
+ c.tls = tls
366
+ c.auth_hosts_only = auth_hosts_only
367
+ c.nqn = nqn
368
+ c.iscsi = iscsi
369
+ c.dhchap = dhchap
370
+ c.cli_pass = cli_pass
371
+ c.status = Cluster.STATUS_ACTIVE
372
+ c.updated_at = int(time.time())
373
+ c.write_to_db(db_controller.kv_store)
374
+ logger.info("New Cluster has been created")
375
+ logger.info(c.uuid)
278
376
 
279
377
 
280
378
  def show_cluster(cl_id, is_json=False):
@@ -284,7 +382,7 @@ def show_cluster(cl_id, is_json=False):
284
382
  logger.error(f"Cluster not found {cl_id}")
285
383
  return False
286
384
 
287
- st = db_controller.get_storage_nodes_by_cluster_id(cl_id)
385
+ st = db_controller.get_storage_nodes()
288
386
  data = []
289
387
  for node in st:
290
388
  for dev in node.nvme_devices:
@@ -345,7 +443,7 @@ def cluster_set_read_only(cl_id):
345
443
 
346
444
  ret = set_cluster_status(cl_id, Cluster.STATUS_READONLY)
347
445
  if ret:
348
- st = db_controller.get_storage_nodes_by_cluster_id(cl_id)
446
+ st = db_controller.get_storage_nodes()
349
447
  for node in st:
350
448
  for dev in node.nvme_devices:
351
449
  if dev.status == NVMeDevice.STATUS_ONLINE:
@@ -365,7 +463,7 @@ def cluster_set_active(cl_id):
365
463
 
366
464
  ret = set_cluster_status(cl_id, Cluster.STATUS_ACTIVE)
367
465
  if ret:
368
- st = db_controller.get_storage_nodes_by_cluster_id(cl_id)
466
+ st = db_controller.get_storage_nodes()
369
467
  for node in st:
370
468
  for dev in node.nvme_devices:
371
469
  if dev.status == NVMeDevice.STATUS_READONLY:
@@ -376,11 +474,11 @@ def cluster_set_active(cl_id):
376
474
  def list():
377
475
  db_controller = DBController()
378
476
  cls = db_controller.get_clusters()
477
+ st = db_controller.get_storage_nodes()
379
478
  mt = db_controller.get_mgmt_nodes()
380
479
 
381
480
  data = []
382
481
  for cl in cls:
383
- st = db_controller.get_storage_nodes_by_cluster_id(cl.get_id())
384
482
  data.append({
385
483
  "UUID": cl.id,
386
484
  "NQN": cl.nqn,
@@ -525,7 +623,7 @@ def get_logs(cluster_id, is_json=False):
525
623
  vuid = record.object_dict['vuid']
526
624
 
527
625
  out.append({
528
- "Date": record.get_date_string(),
626
+ "Date": time.strftime("%H:%M:%S, %d/%m/%Y", time.gmtime(record.date)),
529
627
  "NodeId": record.node_id,
530
628
  "Event": record.event,
531
629
  "Level": record.event_level,
@@ -557,12 +655,12 @@ def update_cluster(cl_id):
557
655
  logger.error(f"Cluster not found {cl_id}")
558
656
  return False
559
657
 
560
- # try:
561
- # out, _, ret_code = shell_utils.run_command("pip install sbcli-dev --upgrade")
562
- # if ret_code == 0:
563
- # logger.info("sbcli-dev is upgraded")
564
- # except Exception as e:
565
- # logger.error(e)
658
+ try:
659
+ out, _, ret_code = shell_utils.run_command("pip install sbcli-dev --upgrade")
660
+ if ret_code == 0:
661
+ logger.info("sbcli-dev is upgraded")
662
+ except Exception as e:
663
+ logger.error(e)
566
664
 
567
665
  try:
568
666
  logger.info("Updating mgmt cluster")
@@ -577,7 +675,7 @@ def update_cluster(cl_id):
577
675
  except Exception as e:
578
676
  print(e)
579
677
 
580
- for node in db_controller.get_storage_nodes_by_cluster_id(cl_id):
678
+ for node in db_controller.get_storage_nodes():
581
679
  node_docker = docker.DockerClient(base_url=f"tcp://{node.mgmt_ip}:2375", version="auto")
582
680
  logger.info(f"Pulling image {constants.SIMPLY_BLOCK_SPDK_ULTRA_IMAGE}")
583
681
  node_docker.images.pull(constants.SIMPLY_BLOCK_SPDK_ULTRA_IMAGE)
@@ -589,7 +687,29 @@ def update_cluster(cl_id):
589
687
  logger.info("Done")
590
688
  return True
591
689
 
592
-
690
+
691
+ def list_tasks(cluster_id):
692
+ db_controller = DBController()
693
+ cluster = db_controller.get_cluster_by_id(cluster_id)
694
+ if not cluster:
695
+ logger.error("Cluster not found: %s", cluster_id)
696
+ return False
697
+
698
+ data = []
699
+ tasks = db_controller.get_job_tasks(cluster_id)
700
+ for task in tasks:
701
+ data.append({
702
+ "UUID": task.uuid,
703
+ "Device": task.device_id,
704
+ "Function": task.function_name,
705
+ "Retry": f"{task.retry}/{constants.TASK_EXEC_RETRY_COUNT}",
706
+ "Status": task.status,
707
+ "Result": task.function_result,
708
+ "Date": time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(task.date)),
709
+ })
710
+ return utils.print_table(data)
711
+
712
+
593
713
  def cluster_grace_startup(cl_id):
594
714
  db_controller = DBController()
595
715
  cluster = db_controller.get_cluster_by_id(cl_id)
@@ -599,7 +719,7 @@ def cluster_grace_startup(cl_id):
599
719
  logger.info(f"Unsuspending cluster: {cl_id}")
600
720
  unsuspend_cluster(cl_id)
601
721
 
602
- st = db_controller.get_storage_nodes_by_cluster_id(cl_id)
722
+ st = db_controller.get_storage_nodes()
603
723
  for node in st:
604
724
  logger.info(f"Restarting node: {node.get_id()}")
605
725
  storage_node_ops.restart_storage_node(node.get_id())
@@ -607,7 +727,7 @@ def cluster_grace_startup(cl_id):
607
727
  get_node = db_controller.get_storage_node_by_id(node.get_id())
608
728
  if get_node.status != StorageNode.STATUS_ONLINE:
609
729
  logger.error("failed to restart node")
610
-
730
+
611
731
  return True
612
732
 
613
733
 
@@ -618,36 +738,13 @@ def cluster_grace_shutdown(cl_id):
618
738
  logger.error(f"Cluster not found {cl_id}")
619
739
  return False
620
740
 
621
- st = db_controller.get_storage_nodes_by_cluster_id(cl_id)
741
+ st = db_controller.get_storage_nodes()
622
742
  for node in st:
623
743
  logger.info(f"Suspending node: {node.get_id()}")
624
744
  storage_node_ops.suspend_storage_node(node.get_id())
625
745
  logger.info(f"Shutting down node: {node.get_id()}")
626
746
  storage_node_ops.shutdown_storage_node(node.get_id())
627
-
747
+
628
748
  logger.info(f"Suspending cluster: {cl_id}")
629
749
  suspend_cluster(cl_id)
630
750
  return True
631
-
632
-
633
- def delete_cluster(cl_id):
634
- db_controller = DBController()
635
- cluster = db_controller.get_cluster_by_id(cl_id)
636
- if not cluster:
637
- logger.error(f"Cluster not found {cl_id}")
638
- return False
639
-
640
- nodes = db_controller.get_storage_nodes_by_cluster_id(cl_id)
641
- if nodes:
642
- logger.error("Can only remove Empty cluster, Storage nodes found")
643
- return False
644
-
645
- pools = db_controller.get_pools(cl_id)
646
- if pools:
647
- logger.error("Can only remove Empty cluster, Pools found")
648
- return False
649
-
650
- logger.info(f"Deleting Cluster {cl_id}")
651
- cluster_events.cluster_delete(cluster)
652
- cluster.remove(db_controller.kv_store)
653
- logger.info("Done")
@@ -9,7 +9,9 @@ RPC_HTTP_PROXY_PORT = 8080
9
9
  LOG_LEVEL = logging.INFO
10
10
  LOG_WEB_DEBUG = True
11
11
 
12
- INSTALL_DIR = os.path.dirname(os.path.realpath(__file__))
12
+ FILE_DIR = os.path.dirname(os.path.realpath(__file__))
13
+ INSTALL_DIR = os.path.dirname(FILE_DIR)
14
+ TOP_DIR = os.path.dirname(INSTALL_DIR)
13
15
 
14
16
  NODE_MONITOR_INTERVAL_SEC = 3
15
17
  DEVICE_MONITOR_INTERVAL_SEC = 5
@@ -20,7 +22,7 @@ DEV_MONITOR_INTERVAL_SEC = 10
20
22
  DEV_STAT_COLLECTOR_INTERVAL_SEC = 2
21
23
  PROT_STAT_COLLECTOR_INTERVAL_SEC = 2
22
24
  DISTR_EVENT_COLLECTOR_INTERVAL_SEC = 2
23
- DISTR_EVENT_COLLECTOR_NUM_OF_EVENTS = 10
25
+ DISTR_EVENT_COLLECTOR_NUM_OF_EVENTS = 20
24
26
  CAP_MONITOR_INTERVAL_SEC = 30
25
27
  SSD_VENDOR_WHITE_LIST = ["1d0f:cd01", "1d0f:cd00"]
26
28
 
@@ -52,12 +54,12 @@ GRAYLOG_CHECK_INTERVAL_SEC = 60
52
54
 
53
55
  FDB_CHECK_INTERVAL_SEC = 60
54
56
 
55
- SIMPLY_BLOCK_DOCKER_IMAGE = "simplyblock/simplyblock:pre-release"
56
- SIMPLY_BLOCK_CLI_NAME = "sbcli"
57
+ SIMPLY_BLOCK_CLI_NAME = "sbcli-dev"
57
58
  TASK_EXEC_INTERVAL_SEC = 30
58
59
  TASK_EXEC_RETRY_COUNT = 8
59
60
 
61
+ SIMPLY_BLOCK_DOCKER_IMAGE = "simplyblock/simplyblock:dev"
60
62
  SIMPLY_BLOCK_SPDK_CORE_IMAGE = "simplyblock/spdk-core:latest"
61
- SIMPLY_BLOCK_SPDK_ULTRA_IMAGE = "simplyblock/spdk:prerelease-latest"
63
+ SIMPLY_BLOCK_SPDK_ULTRA_IMAGE = "simplyblock/spdk:main-latest"
62
64
 
63
65
  GELF_PORT = 12201
@@ -66,6 +66,7 @@ def addNvmeDevices(cluster, rpc_client, devs, snode):
66
66
  'model_id': model_number,
67
67
  'serial_number': nvme_driver_data['ctrlr_data']['serial_number'],
68
68
  'nvme_bdev': nvme_bdev,
69
+ 'alloc_bdev': nvme_bdev,
69
70
  'node_id': snode.get_id(),
70
71
  'cluster_id': snode.cluster_id,
71
72
  'status': 'online'
@@ -87,10 +88,10 @@ def add_node(cluster_id, node_ip, iface_name, data_nics_list, spdk_cpu_mask, spd
87
88
  snode_api = CNodeClient(node_ip)
88
89
 
89
90
  node_info, _ = snode_api.info()
90
- system_id = node_info['system_id']
91
- hostname = node_info['hostname']
92
91
  logger.info(f"Node found: {node_info['hostname']}")
93
- snode = db_controller.get_caching_node_by_system_id(system_id)
92
+
93
+ hostname = node_info['hostname']
94
+ snode = db_controller.get_storage_node_by_hostname(hostname)
94
95
  if snode:
95
96
  logger.error("Node already exists, try remove it first.")
96
97
  return False
@@ -118,8 +119,9 @@ def add_node(cluster_id, node_ip, iface_name, data_nics_list, spdk_cpu_mask, spd
118
119
  snode.uuid = str(uuid.uuid4())
119
120
  snode.status = CachingNode.STATUS_IN_CREATION
120
121
  # snode.baseboard_sn = node_info['system_id']
121
- snode.system_uuid = system_id
122
+ snode.system_uuid = node_info['system_id']
122
123
  snode.hostname = hostname
124
+ # snode.host_nqn = subsystem_nqn
123
125
  snode.subsystem = subsystem_nqn
124
126
  snode.data_nics = data_nics
125
127
  snode.mgmt_ip = node_info['network_interface'][iface_name]['ip']
@@ -348,10 +350,6 @@ def connect(caching_node_id, lvol_id):
348
350
  logger.info(f"Already connected, dev path: {clvol.device_path}")
349
351
  return False
350
352
 
351
- if cnode.cluster_id != pool.cluster_id:
352
- logger.error("Caching node and LVol are in different clusters")
353
- return False
354
-
355
353
  logger.info("Connecting to remote LVOL")
356
354
  mini_id = lvol.get_id().split("-")[0]
357
355
  rem_name = f"rem_{mini_id}"
@@ -60,12 +60,3 @@ def cluster_prov_cap_crit(cluster, util):
60
60
  msg = f"Cluster provisioned capacity reached: {util}%"
61
61
  _cluster_cap_event(cluster, msg, event_level=EventObj.LEVEL_CRITICAL)
62
62
 
63
-
64
- def cluster_delete(cluster):
65
- ec.log_event_cluster(
66
- cluster_id=cluster.get_id(),
67
- domain=ec.DOMAIN_CLUSTER,
68
- event=ec.EVENT_OBJ_DELETED,
69
- db_object=cluster,
70
- caused_by=ec.CAUSED_BY_CLI,
71
- message=f"Cluster deleted {cluster.get_id()}")