vantage6 4.2.1__py3-none-any.whl → 4.3.0b3__py3-none-any.whl

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 (64) hide show
  1. tests_cli/test_example.py +0 -1
  2. tests_cli/test_node_cli.py +74 -79
  3. tests_cli/test_server_cli.py +22 -22
  4. tests_cli/test_wizard.py +41 -29
  5. vantage6/cli/__build__ +1 -1
  6. vantage6/cli/_version.py +11 -8
  7. vantage6/cli/algorithm/create.py +14 -14
  8. vantage6/cli/algorithm/update.py +9 -6
  9. vantage6/cli/algostore/attach.py +32 -0
  10. vantage6/cli/algostore/new.py +55 -0
  11. vantage6/cli/algostore/start.py +102 -0
  12. vantage6/cli/algostore/stop.py +60 -0
  13. vantage6/cli/cli.py +32 -12
  14. vantage6/cli/common/decorator.py +92 -0
  15. vantage6/cli/common/start.py +232 -0
  16. vantage6/cli/configuration_manager.py +22 -32
  17. vantage6/cli/configuration_wizard.py +255 -193
  18. vantage6/cli/context/__init__.py +86 -0
  19. vantage6/cli/context/algorithm_store.py +130 -0
  20. vantage6/cli/context/base_server.py +89 -0
  21. vantage6/cli/context/node.py +254 -0
  22. vantage6/cli/context/server.py +127 -0
  23. vantage6/cli/dev/create.py +180 -113
  24. vantage6/cli/dev/remove.py +20 -19
  25. vantage6/cli/dev/start.py +10 -10
  26. vantage6/cli/dev/stop.py +7 -5
  27. vantage6/cli/globals.py +24 -0
  28. vantage6/cli/node/attach.py +21 -10
  29. vantage6/cli/node/clean.py +4 -2
  30. vantage6/cli/node/common/__init__.py +15 -11
  31. vantage6/cli/node/create_private_key.py +58 -27
  32. vantage6/cli/node/files.py +14 -6
  33. vantage6/cli/node/list.py +18 -24
  34. vantage6/cli/node/new.py +21 -12
  35. vantage6/cli/node/remove.py +31 -22
  36. vantage6/cli/node/set_api_key.py +18 -12
  37. vantage6/cli/node/start.py +38 -12
  38. vantage6/cli/node/stop.py +32 -18
  39. vantage6/cli/node/version.py +23 -13
  40. vantage6/cli/rabbitmq/__init__.py +9 -9
  41. vantage6/cli/rabbitmq/definitions.py +24 -28
  42. vantage6/cli/rabbitmq/queue_manager.py +37 -40
  43. vantage6/cli/server/attach.py +16 -11
  44. vantage6/cli/server/common/__init__.py +37 -25
  45. vantage6/cli/server/files.py +1 -1
  46. vantage6/cli/server/import_.py +45 -37
  47. vantage6/cli/server/list.py +22 -23
  48. vantage6/cli/server/new.py +20 -14
  49. vantage6/cli/server/remove.py +5 -4
  50. vantage6/cli/server/shell.py +17 -6
  51. vantage6/cli/server/start.py +118 -174
  52. vantage6/cli/server/stop.py +31 -23
  53. vantage6/cli/server/version.py +16 -13
  54. vantage6/cli/test/common/diagnostic_runner.py +30 -34
  55. vantage6/cli/test/feature_tester.py +51 -25
  56. vantage6/cli/test/integration_test.py +69 -29
  57. vantage6/cli/utils.py +6 -5
  58. {vantage6-4.2.1.dist-info → vantage6-4.3.0b3.dist-info}/METADATA +5 -3
  59. vantage6-4.3.0b3.dist-info/RECORD +68 -0
  60. vantage6/cli/context.py +0 -416
  61. vantage6-4.2.1.dist-info/RECORD +0 -58
  62. {vantage6-4.2.1.dist-info → vantage6-4.3.0b3.dist-info}/WHEEL +0 -0
  63. {vantage6-4.2.1.dist-info → vantage6-4.3.0b3.dist-info}/entry_points.txt +0 -0
  64. {vantage6-4.2.1.dist-info → vantage6-4.3.0b3.dist-info}/top_level.txt +0 -0
@@ -16,12 +16,20 @@ from vantage6.cli.node.common import find_running_node_names, print_log_worker
16
16
 
17
17
  @click.command()
18
18
  @click.option("-n", "--name", default=None, help="Configuration name")
19
- @click.option('--system', 'system_folders', flag_value=True,
20
- help="Search for configuration in system folders rather than "
21
- "user folders")
22
- @click.option('--user', 'system_folders', flag_value=False, default=N_FOL,
23
- help="Search for configuration in user folders rather than "
24
- "system folders. This is the default")
19
+ @click.option(
20
+ "--system",
21
+ "system_folders",
22
+ flag_value=True,
23
+ help="Search for configuration in system folders rather than " "user folders",
24
+ )
25
+ @click.option(
26
+ "--user",
27
+ "system_folders",
28
+ flag_value=False,
29
+ default=N_FOL,
30
+ help="Search for configuration in user folders rather than "
31
+ "system folders. This is the default",
32
+ )
25
33
  def cli_node_attach(name: str, system_folders: bool) -> None:
26
34
  """
27
35
  Show the node logs in the current console.
@@ -36,8 +44,9 @@ def cli_node_attach(name: str, system_folders: bool) -> None:
36
44
  return
37
45
 
38
46
  if not name:
39
- name = q.select("Select the node you wish to inspect:",
40
- choices=running_node_names).ask()
47
+ name = q.select(
48
+ "Select the node you wish to inspect:", choices=running_node_names
49
+ ).ask()
41
50
  else:
42
51
  post_fix = "system" if system_folders else "user"
43
52
  name = f"{APPNAME}-{name}-{post_fix}"
@@ -51,8 +60,10 @@ def cli_node_attach(name: str, system_folders: bool) -> None:
51
60
  time.sleep(1)
52
61
  except KeyboardInterrupt:
53
62
  info("Closing log file. Keyboard Interrupt.")
54
- info("Note that your node is still running! Shut it down with "
55
- f"'{Fore.RED}v6 node stop{Style.RESET_ALL}'")
63
+ info(
64
+ "Note that your node is still running! Shut it down with "
65
+ f"'{Fore.RED}v6 node stop{Style.RESET_ALL}'"
66
+ )
56
67
  exit(0)
57
68
  else:
58
69
  error(f"{Fore.RED}{name}{Style.RESET_ALL} was not running!?")
@@ -33,8 +33,10 @@ def cli_node_clean() -> None:
33
33
  volume.remove()
34
34
  # info(volume.name)
35
35
  except docker.errors.APIError as e:
36
- error(f"Failed to remove volume {Fore.RED}'{volume.name}'"
37
- f"{Style.RESET_ALL}. Is it still in use?")
36
+ error(
37
+ f"Failed to remove volume {Fore.RED}'{volume.name}'"
38
+ f"{Style.RESET_ALL}. Is it still in use?"
39
+ )
38
40
  debug(e)
39
41
  exit(1)
40
42
  info("Done!")
@@ -8,10 +8,10 @@ import docker
8
8
  from colorama import Fore, Style
9
9
 
10
10
  from vantage6.common import error, info, debug
11
- from vantage6.common.globals import STRING_ENCODING, APPNAME
11
+ from vantage6.common.globals import STRING_ENCODING, APPNAME, InstanceType
12
12
  from vantage6.client import UserClient
13
13
 
14
- from vantage6.cli.context import NodeContext
14
+ from vantage6.cli.context.node import NodeContext
15
15
  from vantage6.cli.configuration_wizard import select_configuration_questionaire
16
16
 
17
17
 
@@ -42,15 +42,15 @@ def create_client(ctx: NodeContext) -> UserClient:
42
42
  UserClient
43
43
  vantage6 client
44
44
  """
45
- host = ctx.config['server_url']
45
+ host = ctx.config["server_url"]
46
46
  # if the server is run locally, we need to use localhost here instead of
47
47
  # the host address of docker
48
- if host in ['http://host.docker.internal', 'http://172.17.0.1']:
49
- host = 'http://localhost'
50
- port = ctx.config['port']
51
- api_path = ctx.config['api_path']
48
+ if host in ["http://host.docker.internal", "http://172.17.0.1"]:
49
+ host = "http://localhost"
50
+ port = ctx.config["port"]
51
+ api_path = ctx.config["api_path"]
52
52
  info(f"Connecting to server at '{host}:{port}{api_path}'")
53
- return UserClient(host, port, api_path, log_level='warn')
53
+ return UserClient(host, port, api_path, log_level="warn")
54
54
 
55
55
 
56
56
  def create_client_and_authenticate(ctx: NodeContext) -> UserClient:
@@ -92,8 +92,11 @@ def select_node(name: str, system_folders: bool) -> tuple[str, str]:
92
92
  str
93
93
  Name of the configuration file
94
94
  """
95
- name = name if name else \
96
- select_configuration_questionaire("node", system_folders)
95
+ name = (
96
+ name
97
+ if name
98
+ else select_configuration_questionaire(InstanceType.NODE, system_folders)
99
+ )
97
100
 
98
101
  # raise error if config could not be found
99
102
  if not NodeContext.config_exists(name, system_folders):
@@ -120,5 +123,6 @@ def find_running_node_names(client: docker.DockerClient) -> list[str]:
120
123
  List of names of running nodes
121
124
  """
122
125
  running_nodes = client.containers.list(
123
- filters={"label": f"{APPNAME}-type=node"})
126
+ filters={"label": f"{APPNAME}-type={InstanceType.NODE}"}
127
+ )
124
128
  return [node.name for node in running_nodes]
@@ -3,39 +3,70 @@ import click
3
3
  from colorama import Fore, Style
4
4
 
5
5
  from vantage6.common import (
6
- warning, error, info, debug, bytes_to_base64s,
6
+ warning,
7
+ error,
8
+ info,
9
+ debug,
10
+ bytes_to_base64s,
7
11
  )
8
12
 
9
13
  from vantage6.common.encryption import RSACryptor
10
- from vantage6.cli.context import NodeContext
11
- from vantage6.cli.globals import (
12
- DEFAULT_NODE_SYSTEM_FOLDERS as N_FOL
13
- )
14
- from vantage6.cli.node.common import (
15
- select_node, create_client_and_authenticate
16
- )
14
+ from vantage6.cli.context.node import NodeContext
15
+ from vantage6.cli.globals import DEFAULT_NODE_SYSTEM_FOLDERS as N_FOL
16
+ from vantage6.cli.node.common import select_node, create_client_and_authenticate
17
17
 
18
18
 
19
19
  @click.command()
20
20
  @click.option("-n", "--name", default=None, help="Configuration name")
21
- @click.option("-c", "--config", default=None,
22
- help='Absolute path to configuration-file; overrides NAME')
23
- @click.option('--system', 'system_folders', flag_value=True,
24
- help="Search for configuration in system folders rather than "
25
- "user folders")
26
- @click.option('--user', 'system_folders', flag_value=False, default=N_FOL,
27
- help="Search for configuration in user folders rather than "
28
- "system folders. This is the default")
29
- @click.option('--no-upload', 'upload', flag_value=False, default=True,
30
- help="Don't upload the public key to the server")
31
- @click.option("-o", "--organization-name", default=None,
32
- help="Organization name. Used in the filename of the private key"
33
- " so that it can easily be recognized again later")
34
- @click.option('--overwrite', 'overwrite', flag_value=True, default=False,
35
- help="Overwrite existing private key if present")
21
+ @click.option(
22
+ "-c",
23
+ "--config",
24
+ default=None,
25
+ help="Absolute path to configuration-file; overrides NAME",
26
+ )
27
+ @click.option(
28
+ "--system",
29
+ "system_folders",
30
+ flag_value=True,
31
+ help="Search for configuration in system folders rather than " "user folders",
32
+ )
33
+ @click.option(
34
+ "--user",
35
+ "system_folders",
36
+ flag_value=False,
37
+ default=N_FOL,
38
+ help="Search for configuration in user folders rather than "
39
+ "system folders. This is the default",
40
+ )
41
+ @click.option(
42
+ "--no-upload",
43
+ "upload",
44
+ flag_value=False,
45
+ default=True,
46
+ help="Don't upload the public key to the server",
47
+ )
48
+ @click.option(
49
+ "-o",
50
+ "--organization-name",
51
+ default=None,
52
+ help="Organization name. Used in the filename of the private key"
53
+ " so that it can easily be recognized again later",
54
+ )
55
+ @click.option(
56
+ "--overwrite",
57
+ "overwrite",
58
+ flag_value=True,
59
+ default=False,
60
+ help="Overwrite existing private key if present",
61
+ )
36
62
  def cli_node_create_private_key(
37
- name: str, config: str, system_folders: bool, upload: bool,
38
- organization_name: str, overwrite: bool) -> None:
63
+ name: str,
64
+ config: str,
65
+ system_folders: bool,
66
+ upload: bool,
67
+ organization_name: str,
68
+ overwrite: bool,
69
+ ) -> None:
39
70
  """
40
71
  Create and upload a new private key
41
72
 
@@ -117,7 +148,7 @@ def cli_node_create_private_key(
117
148
  "This will overwrite any previously existing key!"
118
149
  )
119
150
 
120
- if 'client' not in locals():
151
+ if "client" not in locals():
121
152
  client = create_client_and_authenticate(ctx)
122
153
 
123
154
  # TODO what happens if the user doesn't have permission to upload key?
@@ -126,7 +157,7 @@ def cli_node_create_private_key(
126
157
  client.request(
127
158
  f"/organization/{client.whoami.organization_id}",
128
159
  method="patch",
129
- json={"public_key": bytes_to_base64s(public_key)}
160
+ json={"public_key": bytes_to_base64s(public_key)},
130
161
  )
131
162
 
132
163
  except Exception as e:
@@ -1,18 +1,26 @@
1
1
  import click
2
2
 
3
3
  from vantage6.common import info
4
- from vantage6.cli.context import NodeContext
4
+ from vantage6.cli.context.node import NodeContext
5
5
  from vantage6.cli.globals import DEFAULT_NODE_SYSTEM_FOLDERS as N_FOL
6
6
  from vantage6.cli.node.common import select_node
7
7
 
8
8
 
9
9
  @click.command()
10
10
  @click.option("-n", "--name", default=None, help="Configuration name")
11
- @click.option('--system', 'system_folders', flag_value=True,
12
- help="Search for the configuration in the system folders")
13
- @click.option('--user', 'system_folders', flag_value=False, default=N_FOL,
14
- help="Search for the configuration in the user folders. This is "
15
- "the default")
11
+ @click.option(
12
+ "--system",
13
+ "system_folders",
14
+ flag_value=True,
15
+ help="Search for the configuration in the system folders",
16
+ )
17
+ @click.option(
18
+ "--user",
19
+ "system_folders",
20
+ flag_value=False,
21
+ default=N_FOL,
22
+ help="Search for the configuration in the user folders. This is " "the default",
23
+ )
16
24
  def cli_node_files(name: str, system_folders: bool) -> None:
17
25
  """
18
26
  Prints the location of important node files.
vantage6/cli/node/list.py CHANGED
@@ -5,7 +5,7 @@ from colorama import Fore, Style
5
5
  from vantage6.common import warning
6
6
  from vantage6.common.globals import APPNAME
7
7
  from vantage6.common.docker.addons import check_docker_running
8
- from vantage6.cli.context import NodeContext
8
+ from vantage6.cli.context.node import NodeContext
9
9
  from vantage6.cli.node.common import find_running_node_names
10
10
 
11
11
 
@@ -23,40 +23,34 @@ def cli_node_list() -> None:
23
23
 
24
24
  running_node_names = find_running_node_names(client)
25
25
 
26
- header = \
27
- "\nName"+(21*" ") + \
28
- "Status"+(10*" ") + \
29
- "System/User"
26
+ header = "\nName" + (21 * " ") + "Status" + (10 * " ") + "System/User"
30
27
 
31
28
  click.echo(header)
32
- click.echo("-"*len(header))
29
+ click.echo("-" * len(header))
33
30
 
34
31
  running = Fore.GREEN + "Running" + Style.RESET_ALL
35
32
  stopped = Fore.RED + "Not running" + Style.RESET_ALL
36
33
 
37
34
  # system folders
38
- configs, f1 = NodeContext.available_configurations(
39
- system_folders=True)
35
+ configs, f1 = NodeContext.available_configurations(system_folders=True)
40
36
  for config in configs:
41
- status = running if f"{APPNAME}-{config.name}-system" in \
42
- running_node_names else stopped
43
- click.echo(
44
- f"{config.name:25}"
45
- f"{status:25}System "
37
+ status = (
38
+ running
39
+ if f"{APPNAME}-{config.name}-system" in running_node_names
40
+ else stopped
46
41
  )
42
+ click.echo(f"{config.name:25}" f"{status:25}System ")
47
43
 
48
44
  # user folders
49
- configs, f2 = NodeContext.available_configurations(
50
- system_folders=False)
45
+ configs, f2 = NodeContext.available_configurations(system_folders=False)
51
46
  for config in configs:
52
- status = running if f"{APPNAME}-{config.name}-user" in \
53
- running_node_names else stopped
54
- click.echo(
55
- f"{config.name:25}"
56
- f"{status:25}User "
47
+ status = (
48
+ running
49
+ if f"{APPNAME}-{config.name}-user" in running_node_names
50
+ else stopped
57
51
  )
52
+ click.echo(f"{config.name:25}" f"{status:25}User ")
58
53
 
59
- click.echo("-"*53)
60
- if len(f1)+len(f2):
61
- warning(
62
- f"{Fore.RED}Failed imports: {len(f1)+len(f2)}{Style.RESET_ALL}")
54
+ click.echo("-" * 53)
55
+ if len(f1) + len(f2):
56
+ warning(f"{Fore.RED}Failed imports: {len(f1)+len(f2)}{Style.RESET_ALL}")
vantage6/cli/node/new.py CHANGED
@@ -2,21 +2,28 @@ import click
2
2
  from colorama import Fore, Style
3
3
 
4
4
  from vantage6.common import error, info, check_config_writeable
5
- from vantage6.cli.context import NodeContext
6
- from vantage6.cli.globals import (
7
- DEFAULT_NODE_SYSTEM_FOLDERS as N_FOL
8
- )
5
+ from vantage6.cli.context.node import NodeContext
6
+ from vantage6.cli.globals import DEFAULT_NODE_SYSTEM_FOLDERS as N_FOL
9
7
  from vantage6.cli.configuration_wizard import configuration_wizard
10
8
  from vantage6.cli.utils import check_config_name_allowed, prompt_config_name
9
+ from vantage6.common.globals import InstanceType
11
10
 
12
11
 
13
12
  @click.command()
14
13
  @click.option("-n", "--name", default=None, help="Configuration name")
15
- @click.option('--system', 'system_folders', flag_value=True,
16
- help="Store this configuration in the system folders")
17
- @click.option('--user', 'system_folders', flag_value=False, default=N_FOL,
18
- help="Store this configuration in the user folders. This is the "
19
- "default")
14
+ @click.option(
15
+ "--system",
16
+ "system_folders",
17
+ flag_value=True,
18
+ help="Store this configuration in the system folders",
19
+ )
20
+ @click.option(
21
+ "--user",
22
+ "system_folders",
23
+ flag_value=False,
24
+ default=N_FOL,
25
+ help="Store this configuration in the user folders. This is the " "default",
26
+ )
20
27
  def cli_node_new_configuration(name: str, system_folders: bool) -> None:
21
28
  """
22
29
  Create a new node configuration.
@@ -40,7 +47,9 @@ def cli_node_new_configuration(name: str, system_folders: bool) -> None:
40
47
 
41
48
  # create config in ctx location
42
49
  flag = "--system" if system_folders else ""
43
- cfg_file = configuration_wizard("node", name, system_folders)
50
+ cfg_file = configuration_wizard(InstanceType.NODE, name, system_folders)
44
51
  info(f"New configuration created: {Fore.GREEN}{cfg_file}{Style.RESET_ALL}")
45
- info(f"You can start the node by running "
46
- f"{Fore.GREEN}v6 node start {flag}{Style.RESET_ALL}")
52
+ info(
53
+ f"You can start the node by running "
54
+ f"{Fore.GREEN}v6 node start {flag}{Style.RESET_ALL}"
55
+ )
@@ -8,33 +8,40 @@ from pathlib import Path
8
8
  from shutil import rmtree
9
9
 
10
10
  from vantage6.common import (
11
- error, info, debug,
11
+ error,
12
+ info,
13
+ debug,
12
14
  )
13
15
  from vantage6.common.globals import APPNAME
14
16
 
15
17
  from vantage6.common.globals import VPN_CONFIG_FILE
16
18
 
17
19
 
18
- from vantage6.cli.context import NodeContext
19
- from vantage6.cli.globals import (
20
- DEFAULT_NODE_SYSTEM_FOLDERS as N_FOL
21
- )
22
- from vantage6.cli.utils import (
23
- check_if_docker_daemon_is_running, remove_file
24
- )
20
+ from vantage6.cli.context.node import NodeContext
21
+ from vantage6.cli.globals import DEFAULT_NODE_SYSTEM_FOLDERS as N_FOL
22
+ from vantage6.cli.utils import check_if_docker_daemon_is_running, remove_file
25
23
  from vantage6.cli.node.common import select_node, find_running_node_names
26
24
 
27
25
 
28
26
  @click.command()
29
27
  @click.option("-n", "--name", default=None, help="Configuration name")
30
- @click.option('--system', 'system_folders', flag_value=True,
31
- help="Search for configuration in system folders rather than "
32
- "user folders")
33
- @click.option('--user', 'system_folders', flag_value=False, default=N_FOL,
34
- help="Search for configuration in user folders rather than "
35
- "system folders. This is the default")
36
- @click.option('-f', "--force", type=bool, flag_value=True,
37
- help='Don\'t ask for confirmation')
28
+ @click.option(
29
+ "--system",
30
+ "system_folders",
31
+ flag_value=True,
32
+ help="Search for configuration in system folders rather than " "user folders",
33
+ )
34
+ @click.option(
35
+ "--user",
36
+ "system_folders",
37
+ flag_value=False,
38
+ default=N_FOL,
39
+ help="Search for configuration in user folders rather than "
40
+ "system folders. This is the default",
41
+ )
42
+ @click.option(
43
+ "-f", "--force", type=bool, flag_value=True, help="Don't ask for confirmation"
44
+ )
38
45
  def cli_node_remove(name: str, system_folders: bool, force: bool) -> None:
39
46
  """
40
47
  Delete a node permanently.
@@ -54,14 +61,16 @@ def cli_node_remove(name: str, system_folders: bool, force: bool) -> None:
54
61
  post_fix = "system" if system_folders else "user"
55
62
  node_container_name = f"{APPNAME}-{name}-{post_fix}"
56
63
  if node_container_name in running_node_names:
57
- error(f"Node {name} is still running! Please stop the node before "
58
- "deleting it.")
64
+ error(
65
+ f"Node {name} is still running! Please stop the node before " "deleting it."
66
+ )
59
67
  exit(1)
60
68
 
61
69
  if not force:
62
70
  if not q.confirm(
63
71
  "This node will be deleted permanently including its "
64
- "configuration. Are you sure?", default=False
72
+ "configuration. Are you sure?",
73
+ default=False,
65
74
  ).ask():
66
75
  info("Node will not be deleted")
67
76
  exit(0)
@@ -82,11 +91,11 @@ def cli_node_remove(name: str, system_folders: bool, force: bool) -> None:
82
91
  vol.remove()
83
92
 
84
93
  # remove the VPN configuration file
85
- vpn_config_file = os.path.join(ctx.data_dir, 'vpn', VPN_CONFIG_FILE)
86
- remove_file(vpn_config_file, 'VPN configuration')
94
+ vpn_config_file = os.path.join(ctx.data_dir, "vpn", VPN_CONFIG_FILE)
95
+ remove_file(vpn_config_file, "VPN configuration")
87
96
 
88
97
  # remove the config file
89
- remove_file(ctx.config_file, 'configuration')
98
+ remove_file(ctx.config_file, "configuration")
90
99
 
91
100
  # remove the log file. As this process opens the log file above, the log
92
101
  # handlers need to be closed before deleting
@@ -2,7 +2,7 @@ import click
2
2
  import questionary as q
3
3
 
4
4
  from vantage6.common import error, info, check_config_writeable
5
- from vantage6.cli.context import NodeContext
5
+ from vantage6.cli.context.node import NodeContext
6
6
  from vantage6.cli.globals import DEFAULT_NODE_SYSTEM_FOLDERS as N_FOL
7
7
  from vantage6.cli.configuration_wizard import NodeConfigurationManager
8
8
  from vantage6.cli.node.common import select_node
@@ -11,14 +11,21 @@ from vantage6.cli.node.common import select_node
11
11
  @click.command()
12
12
  @click.option("-n", "--name", default=None, help="Configuration name")
13
13
  @click.option("--api-key", default=None, help="New API key")
14
- @click.option('--system', 'system_folders', flag_value=True,
15
- help="Search for configuration in system folders rather than "
16
- "user folders")
17
- @click.option('--user', 'system_folders', flag_value=False, default=N_FOL,
18
- help="Search for configuration in user folders rather than "
19
- "system folders. This is the default")
20
- def cli_node_set_api_key(name: str, api_key: str,
21
- system_folders: bool) -> None:
14
+ @click.option(
15
+ "--system",
16
+ "system_folders",
17
+ flag_value=True,
18
+ help="Search for configuration in system folders rather than " "user folders",
19
+ )
20
+ @click.option(
21
+ "--user",
22
+ "system_folders",
23
+ flag_value=False,
24
+ default=N_FOL,
25
+ help="Search for configuration in user folders rather than "
26
+ "system folders. This is the default",
27
+ )
28
+ def cli_node_set_api_key(name: str, api_key: str, system_folders: bool) -> None:
22
29
  """
23
30
  Put a new API key into the node configuration file
24
31
  """
@@ -38,8 +45,7 @@ def cli_node_set_api_key(name: str, api_key: str,
38
45
  conf_mgr = NodeConfigurationManager.from_file(ctx.config_file)
39
46
 
40
47
  # set new api key, and save the file
41
- ctx.config['api_key'] = api_key
48
+ ctx.config["api_key"] = api_key
42
49
  conf_mgr.put(ctx.config)
43
50
  conf_mgr.save(ctx.config_file)
44
- info("Your new API key has been uploaded to the config file "
45
- f"{ctx.config_file}.")
51
+ info("Your new API key has been uploaded to the config file " f"{ctx.config_file}.")
@@ -16,6 +16,7 @@ from vantage6.common.globals import (
16
16
  DEFAULT_DOCKER_REGISTRY,
17
17
  DEFAULT_NODE_IMAGE,
18
18
  DEFAULT_NODE_IMAGE_WO_TAG,
19
+ InstanceType,
19
20
  )
20
21
  from vantage6.common.docker.addons import (
21
22
  pull_if_newer,
@@ -23,7 +24,7 @@ from vantage6.common.docker.addons import (
23
24
  check_docker_running,
24
25
  )
25
26
 
26
- from vantage6.cli.context import NodeContext
27
+ from vantage6.cli.context.node import NodeContext
27
28
  from vantage6.cli.globals import DEFAULT_NODE_SYSTEM_FOLDERS as N_FOL
28
29
  from vantage6.cli.configuration_wizard import (
29
30
  configuration_wizard,
@@ -99,14 +100,14 @@ def cli_node_start(
99
100
  else:
100
101
  # in case no name is supplied, ask the user to select one
101
102
  if not name:
102
- name = select_configuration_questionaire("node", system_folders)
103
+ name = select_configuration_questionaire(InstanceType.NODE, system_folders)
103
104
 
104
105
  # check that config exists, if not a questionaire will be invoked
105
106
  if not NodeContext.config_exists(name, system_folders):
106
107
  warning(f"Configuration {Fore.RED}{name}{Style.RESET_ALL} does not exist.")
107
108
 
108
109
  if q.confirm("Create this configuration now?").ask():
109
- configuration_wizard("node", name, system_folders)
110
+ configuration_wizard(InstanceType.NODE, name, system_folders)
110
111
 
111
112
  else:
112
113
  error("Config file couldn't be loaded")
@@ -119,7 +120,7 @@ def cli_node_start(
119
120
 
120
121
  # check that this node is not already running
121
122
  running_nodes = docker_client.containers.list(
122
- filters={"label": f"{APPNAME}-type=node"}
123
+ filters={"label": f"{APPNAME}-type={InstanceType.NODE}"}
123
124
  )
124
125
 
125
126
  suffix = "system" if system_folders else "user"
@@ -266,12 +267,13 @@ def cli_node_start(
266
267
  info("Setting up databases")
267
268
  db_labels = [db["label"] for db in ctx.databases]
268
269
  for label in db_labels:
269
-
270
270
  # check that label contains only valid characters
271
271
  if not label.isidentifier():
272
- error(f"Database label {Fore.RED}{label}{Style.RESET_ALL} contains"
273
- " invalid characters. Only letters, numbers, and underscores"
274
- " are allowed, and it cannot start with a number.")
272
+ error(
273
+ f"Database label {Fore.RED}{label}{Style.RESET_ALL} contains"
274
+ " invalid characters. Only letters, numbers, and underscores"
275
+ " are allowed, and it cannot start with a number."
276
+ )
275
277
  exit(1)
276
278
 
277
279
  db_config = get_database_config(ctx.databases, label)
@@ -308,22 +310,44 @@ def cli_node_start(
308
310
  f" --dockerized {system_folders_option}"
309
311
  )
310
312
 
311
- info("Running Docker container")
312
313
  volumes = []
313
314
  for mount in mounts:
314
315
  volumes.append(f"{mount[1]}:{mount[0]}")
315
316
 
317
+ extra_mounts = ctx.config.get("node_extra_mounts", [])
318
+ for mount in extra_mounts:
319
+ volumes.append(mount)
320
+
321
+ extra_env = ctx.config.get("node_extra_env", {})
322
+ # all extra env var names should be valid identifiers
323
+ extra_env_invalid = [key for key in extra_env.keys() if not key.isidentifier()]
324
+ if extra_env_invalid:
325
+ error(
326
+ "Environment variable names should be valid identifiers. "
327
+ f"The following break this rule: {extra_env_invalid}"
328
+ )
329
+ exit(1)
330
+ # we won't accept overwrites of existing env vars
331
+ env_overwrites = extra_env.keys() & env.keys()
332
+ if env_overwrites:
333
+ error(
334
+ "Cannot overwrite existing node environment variables: " f"{env_overwrites}"
335
+ )
336
+ exit(1)
337
+ env.update(extra_env)
338
+
316
339
  remove_container_if_exists(
317
340
  docker_client=docker_client, name=ctx.docker_container_name
318
341
  )
319
342
 
343
+ info("Running Docker container")
320
344
  container = docker_client.containers.run(
321
345
  image,
322
346
  command=cmd,
323
347
  volumes=volumes,
324
348
  detach=True,
325
349
  labels={
326
- f"{APPNAME}-type": "node",
350
+ f"{APPNAME}-type": InstanceType.NODE,
327
351
  "system": str(system_folders),
328
352
  "name": ctx.config_file_name,
329
353
  },
@@ -349,5 +373,7 @@ def cli_node_start(
349
373
  )
350
374
  exit(0)
351
375
  else:
352
- info(f"To see the logs, run: {Fore.GREEN}v6 node attach --name "
353
- f"{ctx.name}{Style.RESET_ALL}")
376
+ info(
377
+ f"To see the logs, run: {Fore.GREEN}v6 node attach --name "
378
+ f"{ctx.name}{Style.RESET_ALL}"
379
+ )