sbcli-pre 1.2.5__zip → 1.2.7__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 (142) hide show
  1. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/PKG-INFO +1 -1
  2. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/env_var +1 -1
  3. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/sbcli_pre.egg-info/PKG-INFO +1 -1
  4. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/sbcli_pre.egg-info/SOURCES.txt +5 -3
  5. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_cli/cli.py +138 -136
  6. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/cluster_ops.py +138 -235
  7. sbcli_pre-1.2.7/simplyblock_core/constants.py +91 -0
  8. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/controllers/caching_node_controller.py +8 -6
  9. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/controllers/cluster_events.py +9 -0
  10. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/controllers/device_controller.py +56 -63
  11. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/controllers/events_controller.py +5 -3
  12. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/controllers/health_controller.py +30 -40
  13. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/controllers/lvol_controller.py +75 -39
  14. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/controllers/pool_controller.py +8 -4
  15. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/controllers/snapshot_controller.py +36 -3
  16. sbcli_pre-1.2.7/simplyblock_core/controllers/tasks_controller.py +103 -0
  17. sbcli_pre-1.2.7/simplyblock_core/controllers/tasks_events.py +37 -0
  18. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/distr_controller.py +13 -9
  19. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/kv_store.py +62 -20
  20. sbcli_pre-1.2.7/simplyblock_core/mgmt_node_ops.py +205 -0
  21. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/models/events.py +9 -1
  22. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/models/job_schedule.py +6 -0
  23. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/models/nvme_device.py +42 -4
  24. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/models/storage_node.py +14 -2
  25. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/rpc_client.py +55 -10
  26. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/scripts/__init__.py +0 -4
  27. sbcli_pre-1.2.5/simplyblock_core/scripts/alerting/alert_resources.yaml → sbcli_pre-1.2.7/simplyblock_core/scripts/alerting/alert_resources.yaml.j2 +54 -5
  28. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/scripts/dashboards/cluster.json +1 -1
  29. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/scripts/deploy_stack.sh +9 -0
  30. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/scripts/docker-compose-swarm-monitoring.yml +32 -15
  31. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/scripts/docker-compose-swarm.yml +17 -2
  32. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/scripts/haproxy.cfg +15 -0
  33. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/scripts/install_deps.sh +3 -0
  34. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/scripts/stack_deploy_wait.sh +1 -1
  35. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/services/capacity_and_stats_collector.py +1 -1
  36. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/services/device_monitor.py +5 -46
  37. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/services/distr_event_collector.py +10 -11
  38. sbcli_pre-1.2.7/simplyblock_core/services/health_check_service.py +134 -0
  39. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/services/lvol_monitor.py +1 -1
  40. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/services/lvol_stat_collector.py +1 -1
  41. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/services/port_stat_collector.py +0 -1
  42. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/services/storage_node_monitor.py +49 -44
  43. sbcli_pre-1.2.7/simplyblock_core/services/tasks_runner_migration.py +61 -0
  44. sbcli_pre-1.2.5/simplyblock_core/services/job_tasks.py → sbcli_pre-1.2.7/simplyblock_core/services/tasks_runner_restart.py +95 -46
  45. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/snode_client.py +12 -0
  46. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/storage_node_ops.py +630 -358
  47. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/utils.py +126 -1
  48. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/blueprints/snode_ops.py +103 -25
  49. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/blueprints/web_api_cluster.py +20 -43
  50. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/blueprints/web_api_device.py +10 -7
  51. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/blueprints/web_api_lvol.py +9 -5
  52. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/blueprints/web_api_pool.py +14 -5
  53. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/blueprints/web_api_storage_node.py +15 -15
  54. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/node_utils.py +0 -2
  55. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/utils.py +8 -0
  56. sbcli_pre-1.2.5/simplyblock_core/constants.py +0 -65
  57. sbcli_pre-1.2.5/simplyblock_core/mgmt_node_ops.py +0 -80
  58. sbcli_pre-1.2.5/simplyblock_core/scripts/apply_dashboard.sh +0 -22
  59. sbcli_pre-1.2.5/simplyblock_core/services/health_check_service.py +0 -136
  60. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/README.md +0 -0
  61. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/pyproject.toml +0 -0
  62. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/sbcli_pre.egg-info/dependency_links.txt +0 -0
  63. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/sbcli_pre.egg-info/entry_points.txt +0 -0
  64. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/sbcli_pre.egg-info/requires.txt +0 -0
  65. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/sbcli_pre.egg-info/top_level.txt +0 -0
  66. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/setup.cfg +0 -0
  67. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/setup.py +0 -0
  68. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_cli/main.py +0 -0
  69. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/__init__.py +0 -0
  70. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/cnode_client.py +0 -0
  71. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/compute_node_ops.py +0 -0
  72. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/controllers/__init__.py +0 -0
  73. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/controllers/device_events.py +0 -0
  74. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/controllers/lvol_events.py +0 -0
  75. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/controllers/mgmt_events.py +0 -0
  76. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/controllers/pool_events.py +0 -0
  77. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/controllers/snapshot_events.py +0 -0
  78. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/controllers/storage_events.py +0 -0
  79. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/models/__init__.py +0 -0
  80. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/models/base_model.py +0 -0
  81. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/models/caching_node.py +0 -0
  82. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/models/cluster.py +0 -0
  83. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/models/compute_node.py +0 -0
  84. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/models/deployer.py +0 -0
  85. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/models/global_settings.py +0 -0
  86. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/models/iface.py +0 -0
  87. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/models/lvol_model.py +0 -0
  88. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/models/mgmt_node.py +0 -0
  89. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/models/pool.py +0 -0
  90. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/models/port_stat.py +0 -0
  91. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/models/snapshot.py +0 -0
  92. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/models/stats.py +0 -0
  93. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/pci_utils.py +0 -0
  94. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/scripts/alerting/alert_rules.yaml +0 -0
  95. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/scripts/clean_local_storage_deploy.sh +0 -0
  96. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/scripts/config_docker.sh +0 -0
  97. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/scripts/dashboards/devices.json +0 -0
  98. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/scripts/dashboards/lvols.json +0 -0
  99. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/scripts/dashboards/node-exporter.json +0 -0
  100. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/scripts/dashboards/nodes.json +0 -0
  101. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/scripts/dashboards/pools.json +0 -0
  102. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/scripts/datasource.yml +0 -0
  103. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/scripts/db_config_double.sh +0 -0
  104. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/scripts/db_config_single.sh +0 -0
  105. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/scripts/prometheus.yml +0 -0
  106. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/scripts/run_ssh.sh +0 -0
  107. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/scripts/set_db_config.sh +0 -0
  108. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/services/__init__.py +0 -0
  109. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/services/caching_node_monitor.py +0 -0
  110. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/services/cap_monitor.py +0 -0
  111. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/services/install_service.sh +0 -0
  112. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/services/log_agg_service.py +0 -0
  113. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/services/mgmt_node_monitor.py +0 -0
  114. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/services/remove_service.sh +0 -0
  115. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/services/service_template.service +0 -0
  116. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_core/shell_utils.py +0 -0
  117. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/__init__.py +0 -0
  118. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/app.py +0 -0
  119. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/auth_middleware.py +0 -0
  120. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/blueprints/__init__.py +0 -0
  121. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/blueprints/caching_node_ops.py +0 -0
  122. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/blueprints/caching_node_ops_k8s.py +0 -0
  123. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/blueprints/node_api_basic.py +0 -0
  124. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/blueprints/node_api_caching_docker.py +0 -0
  125. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/blueprints/node_api_caching_ks.py +0 -0
  126. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/blueprints/web_api_caching_node.py +0 -0
  127. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/blueprints/web_api_deployer.py +0 -0
  128. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/blueprints/web_api_mgmt_node.py +0 -0
  129. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/blueprints/web_api_snapshot.py +0 -0
  130. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/caching_node_app.py +0 -0
  131. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/caching_node_app_k8s.py +0 -0
  132. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/node_webapp.py +0 -0
  133. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/snode_app.py +0 -0
  134. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/static/delete.py +0 -0
  135. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/static/deploy.py +0 -0
  136. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/static/deploy_cnode.yaml +0 -0
  137. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/static/deploy_spdk.yaml +0 -0
  138. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/static/is_up.py +0 -0
  139. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/static/list_deps.py +0 -0
  140. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/static/rpac.yaml +0 -0
  141. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/static/tst.py +0 -0
  142. {sbcli_pre-1.2.5 → sbcli_pre-1.2.7}/simplyblock_web/templates/deploy_spdk.yaml.j2 +0 -0
@@ -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 get_storage_devices(self, id=""):
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
- if node.nvme_devices:
135
- devices.extend(node.nvme_devices)
136
- for dev in node.nvme_devices:
137
- if dev.get_id() == id:
138
- device = dev
139
- if id:
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
- ret = Pool().read_from_db(self.kv_store)
155
- return ret
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
- ret = LVol().read_from_db(self.kv_store)
170
- return ret
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,25 @@ 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=True)
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
291
+
292
+ def get_snapshots_by_node_id(self, node_id):
293
+ ret = []
294
+ snaps = SnapShot().read_from_db(self.kv_store)
295
+ for snap in snaps:
296
+ if snap.lvol.host_id == node_id:
297
+ ret.append(snap)
298
+ return ret
299
+
300
+ def get_snode_size(self, node_id):
301
+ snode = self.get_storage_node_by_id(node_id)
302
+ total_node_capacity = 0
303
+ for dev in snode.nvme_devices:
304
+ total_node_capacity += dev.size
305
+ return total_node_capacity
@@ -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': ""},
@@ -28,7 +28,7 @@ class NVMeDevice(BaseModel):
28
28
  "serial_number": {"type": str, 'default': ""},
29
29
  "overload_percentage": {"type": int, 'default': 0},
30
30
  "nvme_bdev": {"type": str, 'default': ""},
31
- "alloc_bdev": {"type": str, 'default': ""},
31
+ "nvme_controller": {"type": str, 'default': ""},
32
32
  "alceml_bdev": {"type": str, 'default': ""},
33
33
  "node_id": {"type": str, 'default': ""},
34
34
  "pt_bdev": {"type": str, 'default': ""},
@@ -37,7 +37,6 @@ class NVMeDevice(BaseModel):
37
37
  "nvmf_port": {"type": int, 'default': 0},
38
38
  "remote_bdev": {"type": str, 'default': ""},
39
39
  "testing_bdev": {"type": str, 'default': ""},
40
- "jm_bdev": {"type": str, 'default': ""},
41
40
  "cluster_device_order": {"type": int, 'default': 0},
42
41
  "health_check": {"type": bool, "default": True},
43
42
  "cluster_id": {"type": str, 'default': ""},
@@ -47,6 +46,13 @@ class NVMeDevice(BaseModel):
47
46
  "io_error": {"type": bool, 'default': False},
48
47
  "retries_exhausted": {"type": bool, 'default': False},
49
48
 
49
+ "partition_main_bdev": {"type": str, 'default': ""},
50
+ "partition_main_size": {"type": int, 'default': 0},
51
+ "partition_jm_bdev": {"type": str, 'default': ""},
52
+ "partition_jm_size": {"type": int, 'default': 0},
53
+
54
+ "physical_label": {"type": int, 'default': 0},
55
+
50
56
  }
51
57
 
52
58
  def __init__(self, data=None):
@@ -57,5 +63,37 @@ class NVMeDevice(BaseModel):
57
63
  def get_id(self):
58
64
  return self.uuid
59
65
 
60
- def get_capacity_percentage(self):
61
- return ((self.size - self.capacity) / self.size) * 100
66
+
67
+ class JMDevice(BaseModel):
68
+
69
+ STATUS_ONLINE = 'online'
70
+ STATUS_UNAVAILABLE = 'unavailable'
71
+ STATUS_REMOVED = 'removed'
72
+ STATUS_FAILED = 'failed'
73
+ STATUS_READONLY = 'read_only'
74
+
75
+ attributes = {
76
+ "uuid": {"type": str, 'default': ""},
77
+ "device_name": {"type": str, 'default': ""},
78
+ "status": {"type": str, 'default': ""},
79
+ "size": {"type": int, 'default': -1},
80
+
81
+ "jm_nvme_bdev_list": {"type": List[str], 'default': []},
82
+ "raid_bdev": {"type": str, 'default': ""},
83
+ "nvme_bdev": {"type": str, 'default': ""},
84
+ "alceml_bdev": {"type": str, 'default': ""},
85
+ "jm_bdev": {"type": str, 'default': ""},
86
+
87
+
88
+ "health_check": {"type": bool, "default": True},
89
+ "io_error": {"type": bool, 'default': False},
90
+ }
91
+
92
+ def __init__(self, data=None):
93
+ super(JMDevice, self).__init__()
94
+ self.set_attrs(self.attributes, data)
95
+ self.object_type = "object"
96
+
97
+ def get_id(self):
98
+ return self.uuid
99
+
@@ -5,7 +5,7 @@ from typing import List
5
5
 
6
6
  from simplyblock_core.models.base_model import BaseModel
7
7
  from simplyblock_core.models.iface import IFace
8
- from simplyblock_core.models.nvme_device import NVMeDevice
8
+ from simplyblock_core.models.nvme_device import NVMeDevice, JMDevice
9
9
 
10
10
 
11
11
  class StorageNode(BaseModel):
@@ -61,7 +61,9 @@ class StorageNode(BaseModel):
61
61
  "remote_devices": {"type": List[NVMeDevice], 'default': []},
62
62
  "host_secret": {"type": str, "default": ""},
63
63
  "ctrl_secret": {"type": str, "default": ""},
64
-
64
+ "max_lvol": {"type": int, "default": 0},
65
+ "max_snap": {"type": int, "default": 0},
66
+ "max_prov": {"type": str, "default": ""},
65
67
  "cpu": {"type": int, "default": 0},
66
68
  "cpu_hz": {"type": int, "default": 0},
67
69
  "memory": {"type": int, "default": 0},
@@ -70,10 +72,16 @@ class StorageNode(BaseModel):
70
72
 
71
73
  # spdk params
72
74
  "spdk_cpu_mask": {"type": str, "default": ""},
75
+ "app_thread_mask": {"type": str, "default": ""},
76
+ "pollers_mask": {"type": str, "default": ""},
77
+ "os_cores": {"type": str, "default": []},
78
+ "nvme_pollers_cores": {"type": str, "default": ""},
79
+ "dev_cpu_mask": {"type": str, "default": ""},
73
80
  "spdk_mem": {"type": int, "default": 0},
74
81
  "spdk_image": {"type": str, "default": ""},
75
82
  "spdk_debug": {"type": bool, "default": False},
76
83
 
84
+
77
85
  "ec2_metadata": {"type": dict, "default": {}},
78
86
  "ec2_instance_id": {"type": str, "default": ""},
79
87
  "ec2_public_ip": {"type": str, "default": ""},
@@ -84,6 +92,10 @@ class StorageNode(BaseModel):
84
92
  "iobuf_small_bufsize": {"type": int, "default": 0},
85
93
  "iobuf_large_bufsize": {"type": int, "default": 0},
86
94
 
95
+ "num_partitions_per_dev": {"type": int, "default": 1},
96
+ "jm_percent": {"type": int, "default": 3},
97
+ "jm_device": {"type": JMDevice, "default": None},
98
+
87
99
  }
88
100
 
89
101
  def __init__(self, data=None):
@@ -306,9 +306,9 @@ class RPCClient:
306
306
  params = {"name": name}
307
307
  return self._request("bdev_compress_delete", params)
308
308
 
309
- def ultra21_bdev_pass_create(self, alloc_bdev, vuid, pt_name):
309
+ def ultra21_bdev_pass_create(self, base_bdev, vuid, pt_name):
310
310
  params = {
311
- "base_bdev": alloc_bdev,
311
+ "base_bdev": base_bdev,
312
312
  "vuid": vuid,
313
313
  "pt_bdev": pt_name
314
314
  }
@@ -318,7 +318,8 @@ class RPCClient:
318
318
  params = {"name": name}
319
319
  return self._request2("ultra21_bdev_pass_delete", params)
320
320
 
321
- def bdev_alceml_create(self, alceml_name, nvme_name, uuid, pba_init_mode=3):
321
+ def bdev_alceml_create(self, alceml_name, nvme_name, uuid, pba_init_mode=3,
322
+ dev_cpu_mask=""):
322
323
  params = {
323
324
  "name": alceml_name,
324
325
  "cntr_path": nvme_name,
@@ -334,10 +335,13 @@ class RPCClient:
334
335
  "use_optimized": True,
335
336
  "pba_nbalign": 4096
336
337
  }
338
+ if dev_cpu_mask:
339
+ params["bdb_lcpu_mask"] = int(dev_cpu_mask,16)
337
340
  return self._request("bdev_alceml_create", params)
338
341
 
339
342
  def bdev_distrib_create(self, name, vuid, ndcs, npcs, num_blocks, block_size, jm_names,
340
- chunk_size, ha_comm_addrs=None, ha_inode_self=None, pba_page_size=2097152):
343
+ chunk_size, ha_comm_addrs=None, ha_inode_self=None, pba_page_size=2097152,
344
+ dev_cpu_mask=""):
341
345
  """"
342
346
  // Optional (not specified = no HA)
343
347
  // Comma-separated communication addresses, for each node, e.g. "192.168.10.1:45001,192.168.10.1:32768".
@@ -363,6 +367,8 @@ class RPCClient:
363
367
  if ha_comm_addrs:
364
368
  params['ha_comm_addrs'] = ha_comm_addrs
365
369
  params['ha_inode_self'] = ha_inode_self
370
+ if dev_cpu_mask:
371
+ params["bdb_lcpu_mask"] = int(dev_cpu_mask, 16)
366
372
 
367
373
  return self._request("bdev_distrib_create", params)
368
374
 
@@ -386,7 +392,7 @@ class RPCClient:
386
392
  params = {
387
393
  "name": name,
388
394
  "raid_level": "0",
389
- "strip_size_kb": 4 * len(bdevs_list),
395
+ "strip_size_kb": 4,
390
396
  "base_bdevs": bdevs_list
391
397
  }
392
398
  return self._request("bdev_raid_create", params)
@@ -428,8 +434,9 @@ class RPCClient:
428
434
  "trsvcid": str(port),
429
435
  "subnqn": nqn,
430
436
  "fabrics_connect_timeout_us": 100000,
431
- "fast_io_fail_timeout_sec": 0,
437
+ "fast_io_fail_timeout_sec": 1,
432
438
  "num_io_queues": 16384,
439
+ "ctrlr_loss_timeout_sec": 2,
433
440
  }
434
441
  return self._request("bdev_nvme_attach_controller", params)
435
442
 
@@ -477,9 +484,9 @@ class RPCClient:
477
484
  params = {
478
485
  "bdev_retry_count": 0,
479
486
  "transport_retry_count": 0,
480
- "ctrlr_loss_timeout_sec": -1,
481
- "fast_io_fail_timeout_sec": 5,
482
- "reconnect_delay_sec": 5,
487
+ "ctrlr_loss_timeout_sec": 2,
488
+ "fast_io_fail_timeout_sec": 1,
489
+ "reconnect_delay_sec": 1,
483
490
  "keep_alive_timeout_ms": 200,
484
491
  "transport_ack_timeout": 7,
485
492
  "timeout_us": 100000
@@ -583,12 +590,14 @@ class RPCClient:
583
590
  }
584
591
  return self._request("ultra21_lvol_dismount", params)
585
592
 
586
- def bdev_jm_create(self, name, name_storage1, block_size=4096):
593
+ def bdev_jm_create(self, name, name_storage1, block_size=4096, dev_cpu_mask=""):
587
594
  params = {
588
595
  "name": name,
589
596
  "name_storage1": name_storage1,
590
597
  "block_size": block_size
591
598
  }
599
+ if dev_cpu_mask:
600
+ params["bdb_lcpu_mask"] = int(dev_cpu_mask, 16)
592
601
  return self._request("bdev_jm_create", params)
593
602
 
594
603
  def bdev_jm_delete(self, name):
@@ -620,6 +629,42 @@ class RPCClient:
620
629
  def framework_start_init(self):
621
630
  return self._request("framework_start_init")
622
631
 
632
+ def bdev_examine(self, name):
633
+ params = {"name": name}
634
+ return self._request("bdev_examine", params)
635
+
636
+ def nbd_start_disk(self, bdev_name, nbd_device="/dev/nbd0"):
637
+ params = {
638
+ "bdev_name": bdev_name,
639
+ "nbd_device": nbd_device,
640
+ }
641
+ return self._request("nbd_start_disk", params)
642
+
643
+ def nbd_stop_disk(self, nbd_device):
644
+ params = {
645
+ "nbd_device": nbd_device
646
+ }
647
+ return self._request("nbd_stop_disk", params)
648
+
649
+
623
650
  def bdev_jm_unmap_vuid(self, name, vuid):
624
651
  params = {"name": name, "vuid": vuid}
625
652
  return self._request("bdev_jm_unmap_vuid", params)
653
+
654
+ def sock_impl_set_options(self):
655
+ method = "sock_impl_set_options"
656
+ params = {"impl_name": "posix", "enable_quickack": True,
657
+ "enable_zerocopy_send_server": True,
658
+ "enable_zerocopy_send_client": True}
659
+ return self._request(method, params)
660
+
661
+ def nvmf_set_config(self, poll_groups_mask):
662
+ params = {"poll_groups_mask": poll_groups_mask}
663
+ return self._request("nvmf_set_config", params)
664
+
665
+ def thread_get_stats(self):
666
+ return self._request("thread_get_stats")
667
+
668
+ def thread_set_cpumask(self, app_thread_process_id, app_thread_mask):
669
+ params = {"id": app_thread_process_id, "cpumask": app_thread_mask}
670
+ return self._request("thread_set_cpumask", params)
@@ -35,10 +35,6 @@ def deploy_stack(cli_pass, dev_ip, image_name, graylog_password, cluster_id, log
35
35
  return __run_script(
36
36
  ['sudo', 'bash', '-x', os.path.join(DIR_PATH, 'deploy_stack.sh'), cli_pass, dev_ip, image_name, pass_hash, graylog_password, cluster_id, log_del_interval, metrics_retention_period])
37
37
 
38
- def apply_dashboard(grafanaPassword):
39
- return __run_script(
40
- ['sudo', 'bash', '-x', os.path.join(DIR_PATH, 'apply_dashboard.sh'), grafanaPassword])
41
-
42
38
 
43
39
  def deploy_cleaner():
44
40
  return __run_script(['sudo', 'bash', '-x', os.path.join(DIR_PATH, 'clean_local_storage_deploy.sh')])