vantage6 5.0.0a0__tar.gz → 5.0.0a7__tar.gz

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.

Potentially problematic release.


This version of vantage6 might be problematic. Click here for more details.

Files changed (83) hide show
  1. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/PKG-INFO +1 -1
  2. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/setup.py +2 -2
  3. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/tests_cli/test_node_cli.py +33 -5
  4. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/tests_cli/test_server_cli.py +1 -1
  5. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/tests_cli/test_wizard.py +5 -5
  6. vantage6-5.0.0a7/vantage6/cli/__build__ +1 -0
  7. vantage6-5.0.0a7/vantage6/cli/__init__.py +3 -0
  8. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/algorithm/create.py +26 -8
  9. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/algorithm/update.py +5 -1
  10. vantage6-5.0.0a7/vantage6/cli/algostore/attach.py +49 -0
  11. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/algostore/new.py +9 -3
  12. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/cli.py +2 -0
  13. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/common/start.py +1 -1
  14. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/common/utils.py +27 -4
  15. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/configuration_wizard.py +63 -51
  16. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/context/node.py +18 -1
  17. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/dev/create.py +3 -2
  18. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/dev/start.py +2 -2
  19. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/node/attach.py +7 -3
  20. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/node/clean.py +6 -2
  21. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/node/common/__init__.py +26 -4
  22. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/node/create_private_key.py +10 -2
  23. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/node/new.py +7 -3
  24. vantage6-5.0.0a7/vantage6/cli/node/restart.py +128 -0
  25. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/node/set_api_key.py +7 -3
  26. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/node/start.py +12 -4
  27. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/node/stop.py +7 -3
  28. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/node/version.py +7 -3
  29. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/server/attach.py +7 -3
  30. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/server/new.py +7 -3
  31. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/server/start.py +1 -1
  32. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/server/stop.py +7 -3
  33. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/template/node_config.j2 +3 -1
  34. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/test/feature_tester.py +10 -3
  35. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/utils.py +5 -1
  36. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6.egg-info/PKG-INFO +1 -1
  37. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6.egg-info/SOURCES.txt +1 -1
  38. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6.egg-info/requires.txt +4 -4
  39. vantage6-5.0.0a0/vantage6/cli/__build__ +0 -1
  40. vantage6-5.0.0a0/vantage6/cli/__init__.py +0 -3
  41. vantage6-5.0.0a0/vantage6/cli/algostore/attach.py +0 -32
  42. vantage6-5.0.0a0/vantage6/cli/dev/data/olympic_athletes_2016.csv +0 -2425
  43. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/setup.cfg +0 -0
  44. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/tests_cli/__init__.py +0 -0
  45. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/tests_cli/test_example.py +0 -0
  46. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/_version.py +0 -0
  47. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/algostore/files.py +0 -0
  48. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/algostore/list.py +0 -0
  49. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/algostore/remove.py +0 -0
  50. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/algostore/start.py +0 -0
  51. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/algostore/stop.py +0 -0
  52. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/common/decorator.py +0 -0
  53. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/configuration_manager.py +0 -0
  54. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/context/__init__.py +0 -0
  55. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/context/algorithm_store.py +0 -0
  56. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/context/base_server.py +0 -0
  57. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/context/server.py +0 -0
  58. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/dev/remove.py +0 -0
  59. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/dev/stop.py +0 -0
  60. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/dev/utils.py +0 -0
  61. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/globals.py +0 -0
  62. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/node/files.py +0 -0
  63. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/node/list.py +0 -0
  64. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/node/remove.py +0 -0
  65. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/rabbitmq/__init__.py +0 -0
  66. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/rabbitmq/definitions.py +0 -0
  67. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/rabbitmq/queue_manager.py +0 -0
  68. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/rabbitmq/rabbitmq.config +0 -0
  69. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/server/common/__init__.py +0 -0
  70. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/server/files.py +0 -0
  71. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/server/import_.py +0 -0
  72. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/server/list.py +0 -0
  73. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/server/remove.py +0 -0
  74. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/server/shell.py +0 -0
  75. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/server/version.py +0 -0
  76. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/template/algo_store_config.j2 +0 -0
  77. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/template/server_config.j2 +0 -0
  78. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/template/server_import_config.j2 +0 -0
  79. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/test/common/diagnostic_runner.py +0 -0
  80. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6/cli/test/integration_test.py +0 -0
  81. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6.egg-info/dependency_links.txt +0 -0
  82. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6.egg-info/entry_points.txt +0 -0
  83. {vantage6-5.0.0a0 → vantage6-5.0.0a7}/vantage6.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vantage6
3
- Version: 5.0.0a0
3
+ Version: 5.0.0a7
4
4
  Summary: vantage6 command line interface
5
5
  Home-page: https://github.com/vantage6/vantage6
6
6
  Requires-Python: >=3.10
@@ -38,12 +38,12 @@ setup(
38
38
  "copier==9.2.0",
39
39
  "docker==7.1.0",
40
40
  "ipython==8.10.0",
41
- "jinja2==3.1.4",
41
+ "jinja2==3.1.5",
42
42
  "pandas>=1.5.3",
43
43
  "questionary==1.10.0",
44
44
  "rich==13.5.2",
45
45
  "schema==0.7.5",
46
- "SQLAlchemy==1.4.46",
46
+ "sqlalchemy==2.0.37",
47
47
  f'vantage6-common == {version_ns["__version__"]}',
48
48
  f'vantage6-client == {version_ns["__version__"]}',
49
49
  ],
@@ -17,6 +17,7 @@ from vantage6.cli.node.list import cli_node_list
17
17
  from vantage6.cli.node.new import cli_node_new_configuration
18
18
  from vantage6.cli.node.files import cli_node_files
19
19
  from vantage6.cli.node.start import cli_node_start
20
+ from vantage6.cli.node.restart import cli_node_restart
20
21
  from vantage6.cli.node.stop import cli_node_stop
21
22
  from vantage6.cli.node.attach import cli_node_attach
22
23
  from vantage6.cli.node.create_private_key import cli_node_create_private_key
@@ -85,7 +86,7 @@ class NodeCLITest(unittest.TestCase):
85
86
  )
86
87
 
87
88
  @patch("vantage6.cli.node.new.configuration_wizard")
88
- @patch("vantage6.cli.node.new.check_config_writeable")
89
+ @patch("vantage6.cli.node.new.ensure_config_dir_writable")
89
90
  @patch("vantage6.cli.node.common.NodeContext")
90
91
  def test_new_config(self, context, permissions, wizard):
91
92
  """No error produced when creating new configuration."""
@@ -147,7 +148,7 @@ class NodeCLITest(unittest.TestCase):
147
148
  # check non-zero exit code
148
149
  self.assertEqual(result.exit_code, 1)
149
150
 
150
- @patch("vantage6.cli.node.new.check_config_writeable")
151
+ @patch("vantage6.cli.node.new.ensure_config_dir_writable")
151
152
  @patch("vantage6.cli.node.common.NodeContext")
152
153
  def test_new_write_permissions(self, context, permissions):
153
154
  """User needs write permissions."""
@@ -243,19 +244,28 @@ class NodeCLITest(unittest.TestCase):
243
244
 
244
245
  runner = CliRunner()
245
246
 
247
+ # Should fail when starting node with non-existing database CSV file
246
248
  with runner.isolated_filesystem():
247
249
  result = runner.invoke(cli_node_start, ["--name", "some-name"])
250
+ self.assertEqual(result.exit_code, 1)
248
251
 
252
+ # now do it with a SQL database which doesn't have to be an existing file
253
+ ctx.databases = [{"label": "some_label", "uri": "data.db", "type": "sql"}]
254
+ with runner.isolated_filesystem():
255
+ result = runner.invoke(cli_node_start, ["--name", "some-name"])
249
256
  self.assertEqual(result.exit_code, 0)
250
257
 
258
+ def _setup_stop_test(self, containers):
259
+ container1 = MagicMock()
260
+ container1.name = f"{APPNAME}-iknl-user"
261
+ containers.list.return_value = [container1]
262
+
251
263
  @patch("docker.DockerClient.containers")
252
264
  @patch("vantage6.cli.node.stop.check_docker_running", return_value=True)
253
265
  @patch("vantage6.cli.node.stop.NodeContext")
254
266
  @patch("vantage6.cli.node.stop.delete_volume_if_exists")
255
267
  def test_stop(self, delete_volume, node_context, check_docker, containers):
256
- container1 = MagicMock()
257
- container1.name = f"{APPNAME}-iknl-user"
258
- containers.list.return_value = [container1]
268
+ self._setup_stop_test(containers)
259
269
 
260
270
  runner = CliRunner()
261
271
 
@@ -267,6 +277,24 @@ class NodeCLITest(unittest.TestCase):
267
277
 
268
278
  self.assertEqual(result.exit_code, 0)
269
279
 
280
+ @patch("docker.DockerClient.containers")
281
+ @patch("vantage6.cli.node.stop.check_docker_running", return_value=True)
282
+ @patch("vantage6.cli.node.stop.NodeContext")
283
+ @patch("vantage6.cli.node.stop.delete_volume_if_exists")
284
+ @patch("vantage6.cli.node.restart.subprocess.run")
285
+ def test_restart(
286
+ self, subprocess_run, delete_volume, node_context, check_docker, containers
287
+ ):
288
+ """Restart a node without errors."""
289
+ self._setup_stop_test(containers)
290
+ # The subprocess.run() function is called with the command to start the node.
291
+ # Unfortunately it is hard to test this, so we just return a successful run
292
+ subprocess_run.return_value = MagicMock(returncode=0)
293
+ runner = CliRunner()
294
+ with runner.isolated_filesystem():
295
+ result = runner.invoke(cli_node_restart, ["--name", "iknl"])
296
+ self.assertEqual(result.exit_code, 0)
297
+
270
298
  @patch("vantage6.cli.node.attach.time")
271
299
  @patch("vantage6.cli.node.attach.print_log_worker")
272
300
  @patch("docker.DockerClient.containers")
@@ -112,7 +112,7 @@ class ServerCLITest(unittest.TestCase):
112
112
  self.assertEqual(result.exit_code, 0)
113
113
 
114
114
  @patch("vantage6.cli.server.new.configuration_wizard")
115
- @patch("vantage6.cli.server.new.check_config_writeable")
115
+ @patch("vantage6.cli.server.new.ensure_config_dir_writable")
116
116
  @patch("vantage6.cli.server.new.ServerContext")
117
117
  def test_new(self, context, permissions, wizard):
118
118
  """New configuration without errors."""
@@ -33,8 +33,8 @@ class WizardTest(unittest.TestCase):
33
33
  """An error is printed when docker is not running"""
34
34
 
35
35
  with patch(f"{module_path}.q") as q:
36
- q.prompt.side_effect = self.prompts
37
- q.confirm.return_value.ask.side_effect = [
36
+ q.unsafe_prompt.side_effect = self.prompts
37
+ q.confirm.return_value.unsafe_ask.side_effect = [
38
38
  True, # add a database
39
39
  False, # don't enable two-factor authentication
40
40
  True, # add VPN server
@@ -79,8 +79,8 @@ class WizardTest(unittest.TestCase):
79
79
 
80
80
  def test_server_wizard(self):
81
81
  with patch(f"{module_path}.q") as q:
82
- q.prompt.side_effect = self.prompts
83
- q.confirm.return_value.ask.side_effect = [
82
+ q.unsafe_prompt.side_effect = self.prompts
83
+ q.confirm.return_value.unsafe_ask.side_effect = [
84
84
  True,
85
85
  True,
86
86
  True,
@@ -134,7 +134,7 @@ class WizardTest(unittest.TestCase):
134
134
  available_configurations.return_value = [[config], []]
135
135
 
136
136
  with patch(f"{module_path}.q") as q:
137
- q.select.return_value.ask.return_value = "vtg6"
137
+ q.select.return_value.unsafe_ask.return_value = "vtg6"
138
138
  name = select_configuration_questionaire(InstanceType.NODE, True)
139
139
 
140
140
  self.assertEqual(name, "vtg6")
@@ -0,0 +1 @@
1
+ 7
@@ -0,0 +1,3 @@
1
+ """Command line interface for the vantage6 infrastructure."""
2
+
3
+ from ._version import version_info, __version__ # noqa: F401
@@ -33,14 +33,11 @@ def cli_algorithm_create(name: str, directory: str) -> dict:
33
33
  can be used to build an appropriate Docker image that can be used as a
34
34
  vantage6 algorithm.
35
35
  """
36
- if not name:
37
- name = q.text("Name of your new algorithm:").ask()
38
-
39
- if not directory:
40
- default_dir = str(Path(os.getcwd()) / name)
41
- directory = q.text(
42
- "Directory to put the algorithm in:", default=default_dir
43
- ).ask()
36
+ try:
37
+ name, directory = _get_user_input(name, directory)
38
+ except KeyboardInterrupt:
39
+ info("Aborted by user!")
40
+ return
44
41
 
45
42
  # Create the template. The `unsafe` flag is used to allow running a Python script
46
43
  # after creating the template that cleans up some things.
@@ -49,3 +46,24 @@ def cli_algorithm_create(name: str, directory: str) -> dict:
49
46
  )
50
47
  info("Template created!")
51
48
  info(f"You can find your new algorithm in: {directory}")
49
+
50
+
51
+ def _get_user_input(name: str, directory: str) -> None:
52
+ """Get user input for the algorithm creation
53
+
54
+ Parameters
55
+ ----------
56
+ name : str
57
+ Name for the new algorithm
58
+ directory : str
59
+ Directory to put the algorithm into
60
+ """
61
+ if not name:
62
+ name = q.text("Name of your new algorithm:").unsafe_ask()
63
+
64
+ if not directory:
65
+ default_dir = str(Path(os.getcwd()) / name)
66
+ directory = q.text(
67
+ "Directory to put the algorithm in:", default=default_dir
68
+ ).unsafe_ask()
69
+ return name, directory
@@ -34,7 +34,11 @@ def cli_algorithm_update(directory: str, change_answers: bool) -> dict:
34
34
  """
35
35
  if not directory:
36
36
  default_dir = str(Path(os.getcwd()))
37
- directory = q.text("Algorithm directory:", default=default_dir).ask()
37
+ try:
38
+ directory = q.text("Algorithm directory:", default=default_dir).unsafe_ask()
39
+ except KeyboardInterrupt:
40
+ info("Aborted by user!")
41
+ return
38
42
 
39
43
  info("Updating template...")
40
44
  try:
@@ -0,0 +1,49 @@
1
+ import click
2
+ import docker
3
+ import questionary as q
4
+
5
+ from colorama import Fore, Style
6
+
7
+ from vantage6.common import error
8
+ from vantage6.common.docker.addons import check_docker_running
9
+ from vantage6.common.globals import APPNAME, InstanceType
10
+ from vantage6.cli.common.start import attach_logs
11
+ from vantage6.cli.globals import DEFAULT_SERVER_SYSTEM_FOLDERS
12
+
13
+
14
+ @click.command()
15
+ @click.option("-n", "--name", default=None, help="configuration name")
16
+ @click.option("--system", "system_folders", flag_value=True)
17
+ @click.option(
18
+ "--user", "system_folders", flag_value=False, default=DEFAULT_SERVER_SYSTEM_FOLDERS
19
+ )
20
+ def cli_algo_store_attach(name: str, system_folders: bool) -> None:
21
+ """
22
+ Show the server logs in the current console.
23
+ """
24
+ check_docker_running()
25
+ client = docker.from_env()
26
+
27
+ running_servers = client.containers.list(
28
+ filters={"label": f"{APPNAME}-type={InstanceType.ALGORITHM_STORE}"}
29
+ )
30
+ running_server_names = [container.name for container in running_servers]
31
+
32
+ if not name:
33
+ try:
34
+ name = q.select(
35
+ "Select the algorithm store you wish to attach:",
36
+ choices=running_server_names,
37
+ ).unsafe_ask()
38
+ except KeyboardInterrupt:
39
+ error("Aborted by user!")
40
+ return
41
+ else:
42
+ post_fix = "system" if system_folders else "user"
43
+ name = f"{APPNAME}-{name}-{post_fix}-{InstanceType.ALGORITHM_STORE}"
44
+
45
+ if name in running_server_names:
46
+ container = client.containers.get(name)
47
+ attach_logs(container, InstanceType.ALGORITHM_STORE)
48
+ else:
49
+ error(f"{Fore.RED}{name}{Style.RESET_ALL} is not running!")
@@ -1,7 +1,7 @@
1
1
  import click
2
2
  from colorama import Fore, Style
3
3
 
4
- from vantage6.common import info, error, check_config_writeable
4
+ from vantage6.common import info, error, ensure_config_dir_writable
5
5
  from vantage6.common.globals import InstanceType
6
6
  from vantage6.cli.globals import DEFAULT_SERVER_SYSTEM_FOLDERS
7
7
  from vantage6.cli.context.algorithm_store import AlgorithmStoreContext
@@ -36,7 +36,7 @@ def cli_algo_store_new(name: str, system_folders: bool) -> None:
36
36
  exit(1)
37
37
 
38
38
  # Check that we can write in this folder
39
- if not check_config_writeable(system_folders):
39
+ if not ensure_config_dir_writable(system_folders):
40
40
  error("Your user does not have write access to all folders. Exiting")
41
41
  info(
42
42
  f"Create a new server using '{Fore.GREEN}v6 algorithm-store new "
@@ -45,7 +45,13 @@ def cli_algo_store_new(name: str, system_folders: bool) -> None:
45
45
  exit(1)
46
46
 
47
47
  # create config in ctx location
48
- cfg_file = configuration_wizard(InstanceType.ALGORITHM_STORE, name, system_folders)
48
+ try:
49
+ cfg_file = configuration_wizard(
50
+ InstanceType.ALGORITHM_STORE, name, system_folders
51
+ )
52
+ except KeyboardInterrupt:
53
+ error("Configuration creation aborted.")
54
+ exit(1)
49
55
  info(f"New configuration created: {Fore.GREEN}{cfg_file}{Style.RESET_ALL}")
50
56
 
51
57
  flag = "" if system_folders else "--user"
@@ -17,6 +17,7 @@ from vantage6.cli.node.files import cli_node_files
17
17
  from vantage6.cli.node.list import cli_node_list
18
18
  from vantage6.cli.node.new import cli_node_new_configuration
19
19
  from vantage6.cli.node.remove import cli_node_remove
20
+ from vantage6.cli.node.restart import cli_node_restart
20
21
  from vantage6.cli.node.set_api_key import cli_node_set_api_key
21
22
  from vantage6.cli.node.start import cli_node_start
22
23
  from vantage6.cli.node.stop import cli_node_stop
@@ -75,6 +76,7 @@ cli_node.add_command(cli_node_files, name="files")
75
76
  cli_node.add_command(cli_node_list, name="list")
76
77
  cli_node.add_command(cli_node_new_configuration, name="new")
77
78
  cli_node.add_command(cli_node_remove, name="remove")
79
+ cli_node.add_command(cli_node_restart, name="restart")
78
80
  cli_node.add_command(cli_node_set_api_key, name="set-api-key")
79
81
  cli_node.add_command(cli_node_start, name="start")
80
82
  cli_node.add_command(cli_node_stop, name="stop")
@@ -241,7 +241,7 @@ def mount_database(
241
241
  # try to mount database
242
242
  uri = ctx.config["uri"]
243
243
  url = make_url(uri)
244
- environment_vars = None
244
+ environment_vars = {}
245
245
  mount = None
246
246
 
247
247
  # If host is None, we're dealing with a file-based DB, like SQLite
@@ -38,10 +38,14 @@ def get_server_name(
38
38
  f"{instance_type}s that are running"
39
39
  )
40
40
  exit(1)
41
- name = q.select(
42
- f"Select the {instance_type} you wish to inspect:",
43
- choices=running_server_names,
44
- ).ask()
41
+ try:
42
+ name = q.select(
43
+ f"Select the {instance_type} you wish to inspect:",
44
+ choices=running_server_names,
45
+ ).unsafe_ask()
46
+ except KeyboardInterrupt:
47
+ error("Aborted by user!")
48
+ exit(1)
45
49
  else:
46
50
  post_fix = "system" if system_folders else "user"
47
51
  name = f"{APPNAME}-{name}-{post_fix}"
@@ -135,3 +139,22 @@ def print_log_worker(logs_stream: Iterable[bytes]) -> None:
135
139
  "the container."
136
140
  )
137
141
  print(log)
142
+
143
+
144
+ def get_name_from_container_name(container_name: str) -> str:
145
+ """
146
+ Get the node/server/store name from a container name.
147
+
148
+ Parameters
149
+ ----------
150
+ container_name : str
151
+ The name of the container
152
+
153
+ Returns
154
+ -------
155
+ str
156
+ The name of the node/server/store
157
+ """
158
+ # Container name is structured as: f"{APPNAME}-{name}-{post_fix}"
159
+ # Take into account that name can contain '-'
160
+ return "-".join(container_name.split("-")[1:-1])