vantage6 5.0.0a34__py3-none-any.whl → 5.0.0a36__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 (69) hide show
  1. vantage6/cli/algorithm/generate_algorithm_json.py +9 -9
  2. vantage6/cli/algorithm/update.py +1 -1
  3. vantage6/cli/algostore/attach.py +1 -0
  4. vantage6/cli/algostore/files.py +3 -2
  5. vantage6/cli/algostore/list.py +0 -3
  6. vantage6/cli/algostore/new.py +83 -2
  7. vantage6/cli/algostore/remove.py +18 -34
  8. vantage6/cli/algostore/start.py +10 -7
  9. vantage6/cli/algostore/stop.py +12 -50
  10. vantage6/cli/auth/attach.py +60 -0
  11. vantage6/cli/auth/files.py +16 -0
  12. vantage6/cli/auth/list.py +13 -0
  13. vantage6/cli/auth/new.py +80 -0
  14. vantage6/cli/auth/remove.py +31 -0
  15. vantage6/cli/auth/start.py +80 -0
  16. vantage6/cli/auth/stop.py +64 -0
  17. vantage6/cli/cli.py +67 -37
  18. vantage6/cli/common/new.py +28 -3
  19. vantage6/cli/common/remove.py +54 -0
  20. vantage6/cli/common/start.py +31 -2
  21. vantage6/cli/common/stop.py +79 -1
  22. vantage6/cli/common/utils.py +47 -4
  23. vantage6/cli/configuration_manager.py +57 -13
  24. vantage6/cli/configuration_wizard.py +18 -397
  25. vantage6/cli/context/__init__.py +3 -0
  26. vantage6/cli/context/auth.py +107 -0
  27. vantage6/cli/context/base_server.py +0 -4
  28. vantage6/cli/context/node.py +10 -17
  29. vantage6/cli/dev/clean.py +28 -0
  30. vantage6/cli/dev/common.py +34 -0
  31. vantage6/cli/dev/rebuild.py +39 -0
  32. vantage6/cli/dev/start.py +36 -0
  33. vantage6/cli/dev/stop.py +23 -0
  34. vantage6/cli/globals.py +24 -1
  35. vantage6/cli/node/attach.py +1 -0
  36. vantage6/cli/node/files.py +12 -25
  37. vantage6/cli/node/list.py +5 -4
  38. vantage6/cli/node/new.py +348 -28
  39. vantage6/cli/node/remove.py +14 -90
  40. vantage6/cli/node/restart.py +30 -51
  41. vantage6/cli/node/start.py +81 -304
  42. vantage6/cli/node/stop.py +36 -96
  43. vantage6/cli/node/version.py +5 -4
  44. vantage6/cli/prometheus/monitoring_manager.py +5 -3
  45. vantage6/cli/rabbitmq/queue_manager.py +13 -11
  46. vantage6/cli/server/attach.py +1 -0
  47. vantage6/cli/server/common/__init__.py +1 -27
  48. vantage6/cli/server/import_.py +1 -1
  49. vantage6/cli/server/new.py +83 -2
  50. vantage6/cli/server/remove.py +12 -33
  51. vantage6/cli/server/start.py +8 -6
  52. vantage6/cli/server/stop.py +10 -39
  53. vantage6/cli/template/algo_store_config.j2 +1 -1
  54. vantage6/cli/template/auth_config.j2 +230 -0
  55. vantage6/cli/template/node_config.j2 +336 -33
  56. vantage6/cli/template/node_config_nonk8s.j2 +33 -0
  57. vantage6/cli/test/common/diagnostic_runner.py +5 -3
  58. vantage6/cli/use/namespace.py +2 -1
  59. vantage6/cli/utils.py +0 -2
  60. {vantage6-5.0.0a34.dist-info → vantage6-5.0.0a36.dist-info}/METADATA +3 -3
  61. vantage6-5.0.0a36.dist-info/RECORD +86 -0
  62. vantage6/cli/dev/create.py +0 -693
  63. vantage6/cli/dev/data/km_dataset.csv +0 -2401
  64. vantage6/cli/dev/remove.py +0 -112
  65. vantage6/cli/node/clean.py +0 -46
  66. vantage6/cli/server/shell.py +0 -54
  67. vantage6-5.0.0a34.dist-info/RECORD +0 -75
  68. {vantage6-5.0.0a34.dist-info → vantage6-5.0.0a36.dist-info}/WHEEL +0 -0
  69. {vantage6-5.0.0a34.dist-info → vantage6-5.0.0a36.dist-info}/entry_points.txt +0 -0
@@ -1,112 +1,36 @@
1
- import click
2
- import questionary as q
3
- import docker
4
- import os.path
5
- import itertools
6
-
7
1
  from pathlib import Path
8
2
  from shutil import rmtree
9
3
 
10
- from vantage6.common import (
11
- error,
12
- info,
13
- debug,
14
- )
15
- from vantage6.common.globals import APPNAME
4
+ import click
16
5
 
6
+ from vantage6.common.globals import InstanceType
17
7
 
8
+ from vantage6.cli.common.decorator import click_insert_context
9
+ from vantage6.cli.common.remove import execute_remove
18
10
  from vantage6.cli.context.node import NodeContext
19
- from vantage6.cli.globals import DEFAULT_NODE_SYSTEM_FOLDERS as N_FOL
20
- from vantage6.cli.utils import check_if_docker_daemon_is_running, remove_file
21
- from vantage6.cli.node.common import select_node, find_running_node_names
22
-
23
- # TODO v5+ remove this - just a dummy to prevent import issues from v4 CLI
24
- # from vantage6.common.globals import VPN_CONFIG_FILE
25
- VPN_CONFIG_FILE = "vpn.conf"
11
+ from vantage6.cli.globals import InfraComponentName
26
12
 
27
13
 
28
14
  @click.command()
29
- @click.option("-n", "--name", default=None, help="Configuration name")
30
- @click.option(
31
- "--system",
32
- "system_folders",
33
- flag_value=True,
34
- help="Search for configuration in system folders rather than " "user folders",
35
- )
36
- @click.option(
37
- "--user",
38
- "system_folders",
39
- flag_value=False,
40
- default=N_FOL,
41
- help="Search for configuration in user folders rather than "
42
- "system folders. This is the default",
43
- )
44
15
  @click.option(
45
16
  "-f", "--force", type=bool, flag_value=True, help="Don't ask for confirmation"
46
17
  )
47
- def cli_node_remove(name: str, system_folders: bool, force: bool) -> None:
18
+ @click_insert_context(
19
+ type_=InstanceType.NODE, include_name=True, include_system_folders=True
20
+ )
21
+ def cli_node_remove(
22
+ ctx: NodeContext, name: str, system_folders: bool, force: bool
23
+ ) -> None:
48
24
  """
49
25
  Delete a node permanently.
50
26
 
51
27
  Remove the configuration file, log file, and docker volumes attached to
52
28
  the node.
53
29
  """
54
- # select configuration name if none supplied
55
- name = select_node(name, system_folders)
56
-
57
- client = docker.from_env()
58
- check_if_docker_daemon_is_running(client)
59
-
60
- # check if node is still running, otherwise don't allow deleting it
61
- running_node_names = find_running_node_names(client)
62
-
63
- post_fix = "system" if system_folders else "user"
64
- node_container_name = f"{APPNAME}-{name}-{post_fix}"
65
- if node_container_name in running_node_names:
66
- error(
67
- f"Node {name} is still running! Please stop the node before " "deleting it."
68
- )
69
- exit(1)
70
-
71
- if not force:
72
- if not q.confirm(
73
- "This node will be deleted permanently including its "
74
- "configuration. Are you sure?",
75
- default=False,
76
- ).ask():
77
- info("Node will not be deleted")
78
- exit(0)
79
-
80
- # create node context
81
- ctx = NodeContext(name, system_folders=system_folders)
82
-
83
- # remove the docker volume and any temporary volumes
84
- debug("Deleting docker volumes")
85
- volumes = client.volumes.list()
86
- for vol in volumes:
87
- if vol.name.startswith(ctx.docker_volume_name): # includes tmp volumes
88
- info(f"Deleting docker volume {vol.name}")
89
- vol.remove()
90
- # remove docker vpn volume
91
- if vol.name == ctx.docker_vpn_volume_name:
92
- info(f"Deleting VPN docker volume {vol.name}")
93
- vol.remove()
94
-
95
- # remove the VPN configuration file
96
- vpn_config_file = os.path.join(ctx.data_dir, "vpn", VPN_CONFIG_FILE)
97
- remove_file(vpn_config_file, "VPN configuration")
98
-
99
- # remove the config file
100
- remove_file(ctx.config_file, "configuration")
101
30
 
102
- # remove the log file. As this process opens the log file above, the log
103
- # handlers need to be closed before deleting
104
- log_dir = Path(ctx.log_file.parent)
105
- info(f"Removing log file {log_dir}")
106
- for handler in itertools.chain(ctx.log.handlers, ctx.log.root.handlers):
107
- handler.close()
108
- # remove the whole folder with all the log files
109
- rmtree(log_dir)
31
+ execute_remove(
32
+ ctx, InstanceType.NODE, InfraComponentName.NODE, name, system_folders, force
33
+ )
110
34
 
111
35
  # remove the folder: if it hasn't been started yet this won't exist...
112
36
  if Path.exists(ctx.config_dir / name):
@@ -1,23 +1,29 @@
1
1
  import subprocess
2
+
2
3
  import click
3
4
  import questionary as q
4
- import docker
5
5
 
6
- from vantage6.common import warning, error
7
- from vantage6.common.docker.addons import check_docker_running
8
- from vantage6.cli.common.utils import get_name_from_container_name
9
- from vantage6.cli.node.stop import cli_node_stop
10
- from vantage6.cli.node.common import find_running_node_names
6
+ from vantage6.common import error, warning
7
+ from vantage6.common.globals import InstanceType
8
+
9
+ from vantage6.cli.common.utils import (
10
+ find_running_service_names,
11
+ get_config_name_from_service_name,
12
+ select_context_and_namespace,
13
+ )
11
14
  from vantage6.cli.globals import DEFAULT_NODE_SYSTEM_FOLDERS as N_FOL
15
+ from vantage6.cli.node.stop import cli_node_stop
12
16
 
13
17
 
14
18
  @click.command()
15
19
  @click.option("-n", "--name", default=None, help="Configuration name")
20
+ @click.option("--context", default=None, help="Kubernetes context to use")
21
+ @click.option("--namespace", default=None, help="Kubernetes namespace to use")
16
22
  @click.option(
17
23
  "--system",
18
24
  "system_folders",
19
25
  flag_value=True,
20
- help="Search for configuration in system folders instead of " "user folders",
26
+ help="Search for configuration in system folders instead of user folders",
21
27
  )
22
28
  @click.option(
23
29
  "--user",
@@ -27,53 +33,35 @@ from vantage6.cli.globals import DEFAULT_NODE_SYSTEM_FOLDERS as N_FOL
27
33
  help="Search for configuration in the user folders instead of "
28
34
  "system folders. This is the default.",
29
35
  )
30
- @click.option("-i", "--image", default=None, help="Node Docker image to use")
31
- @click.option(
32
- "--keep/--auto-remove",
33
- default=False,
34
- help="Keep node container after finishing. Useful for debugging",
35
- )
36
- @click.option(
37
- "--force-db-mount",
38
- is_flag=True,
39
- help="Always mount node databases; skip the check if they are existing files.",
40
- )
41
36
  @click.option(
42
37
  "--attach/--detach",
43
38
  default=False,
44
- help="Show node logs on the current console after starting the " "node",
45
- )
46
- @click.option(
47
- "--mount-src",
48
- default="",
49
- help="Override vantage6 source code in container with the source"
50
- " code in this path",
39
+ help="Show node logs on the current console after starting the node",
51
40
  )
52
41
  @click.option("--all", "all_nodes", flag_value=True, help="Stop all running nodes")
53
- @click.option(
54
- "--force",
55
- "force",
56
- flag_value=True,
57
- help="Kill nodes instantly; don't wait for them to shut down",
58
- )
59
42
  @click.pass_context
60
43
  def cli_node_restart(
61
44
  click_ctx: click.Context,
62
45
  name: str,
46
+ context: str,
47
+ namespace: str,
63
48
  system_folders: bool,
64
- image: str,
65
- keep: bool,
66
- mount_src: str,
67
49
  attach: bool,
68
- force_db_mount: bool,
69
50
  all_nodes: bool,
70
- force: bool,
71
51
  ) -> None:
72
52
  """Restart the node"""
73
- check_docker_running()
74
- client = docker.from_env()
53
+ context, namespace = select_context_and_namespace(
54
+ context=context,
55
+ namespace=namespace,
56
+ )
75
57
 
76
- running_node_names = find_running_node_names(client)
58
+ running_node_names = find_running_service_names(
59
+ instance_type=InstanceType.NODE,
60
+ only_system_folders=system_folders,
61
+ only_user_folders=not system_folders,
62
+ context=context,
63
+ namespace=namespace,
64
+ )
77
65
  if not running_node_names:
78
66
  warning("No nodes are currently running. No action taken.")
79
67
  return
@@ -87,19 +75,19 @@ def cli_node_restart(
87
75
 
88
76
  if all_nodes:
89
77
  names = [
90
- get_name_from_container_name(container_name)
78
+ get_config_name_from_service_name(container_name)
91
79
  for container_name in running_node_names
92
80
  ]
93
81
  else:
94
82
  if not name:
95
83
  try:
96
- container_name = q.select(
84
+ helm_name = q.select(
97
85
  "Select the node you wish to restart:", choices=running_node_names
98
86
  ).unsafe_ask()
99
87
  except KeyboardInterrupt:
100
88
  error("Aborted by user!")
101
89
  return
102
- names = [get_name_from_container_name(container_name)]
90
+ names = [get_config_name_from_service_name(helm_name)]
103
91
  else:
104
92
  names = [name]
105
93
 
@@ -109,20 +97,11 @@ def cli_node_restart(
109
97
  name=node_name,
110
98
  system_folders=system_folders,
111
99
  all_nodes=False,
112
- force=force,
113
100
  )
114
101
 
115
102
  cmd = ["v6", "node", "start", "--name", node_name]
116
103
  if system_folders:
117
104
  cmd.append("--system")
118
- if image:
119
- cmd.extend(["--image", image])
120
- if keep:
121
- cmd.append("--keep")
122
- if mount_src:
123
- cmd.extend(["--mount-src", mount_src])
124
105
  if attach:
125
106
  cmd.append("--attach")
126
- if force_db_mount:
127
- cmd.append("--force-db-mount")
128
107
  subprocess.run(cmd, check=True)
@@ -1,334 +1,111 @@
1
- import os.path
2
- import time
3
- from pathlib import Path
4
- from threading import Thread
5
-
6
1
  import click
7
- import docker
8
- from colorama import Fore, Style
9
2
 
10
- from vantage6.common import debug, error, info, warning
11
- from vantage6.common.dataclass import TaskDB
12
- from vantage6.common.docker.addons import (
13
- check_docker_running,
14
- remove_container_if_exists,
15
- )
16
- from vantage6.common.globals import (
17
- APPNAME,
18
- DEFAULT_DOCKER_REGISTRY,
19
- DEFAULT_NODE_IMAGE,
20
- DEFAULT_NODE_IMAGE_WO_TAG,
21
- InstanceType,
22
- )
3
+ from vantage6.common import info
4
+ from vantage6.common.globals import InstanceType
23
5
 
24
- from vantage6.cli import __version__
25
6
  from vantage6.cli.common.decorator import click_insert_context
26
- from vantage6.cli.common.start import pull_infra_image
27
- from vantage6.cli.common.utils import print_log_worker
7
+ from vantage6.cli.common.start import (
8
+ helm_install,
9
+ prestart_checks,
10
+ start_port_forward,
11
+ )
12
+ from vantage6.cli.common.utils import (
13
+ attach_logs,
14
+ create_directory_if_not_exists,
15
+ )
28
16
  from vantage6.cli.context.node import NodeContext
29
- from vantage6.cli.node.common import create_client
30
- from vantage6.cli.utils import check_config_name_allowed
17
+ from vantage6.cli.globals import ChartName
18
+
19
+ from vantage6.node.globals import DEFAULT_PROXY_SERVER_PORT
31
20
 
32
21
 
33
22
  @click.command()
34
- @click.option("-i", "--image", default=None, help="Node Docker image to use")
35
- @click.option(
36
- "--keep/--auto-remove",
37
- default=False,
38
- help="Keep node container after finishing. Useful for debugging",
39
- )
40
- @click.option(
41
- "--force-db-mount",
42
- is_flag=True,
43
- help="Always mount node databases; skip the check if they are existing files.",
44
- )
23
+ @click.option("--context", default=None, help="Kubernetes context to use")
24
+ @click.option("--namespace", default=None, help="Kubernetes namespace to use")
45
25
  @click.option(
46
26
  "--attach/--detach",
47
27
  default=False,
48
28
  help="Show node logs on the current console after starting the node",
49
29
  )
50
- @click.option(
51
- "--mount-src",
52
- default="",
53
- help="Override vantage6 source code in container with the source code in this path",
54
- )
55
30
  @click_insert_context(InstanceType.NODE, include_name=True, include_system_folders=True)
56
31
  def cli_node_start(
57
32
  ctx: NodeContext,
58
33
  name: str,
59
34
  system_folders: bool,
60
- image: str,
61
- keep: bool,
62
- mount_src: str,
35
+ context: str,
36
+ namespace: str,
63
37
  attach: bool,
64
- force_db_mount: bool,
65
38
  ) -> None:
66
39
  """
67
40
  Start the node.
68
41
  """
69
- check_docker_running()
70
42
  info("Starting node...")
71
- info("Finding Docker daemon")
72
- docker_client = docker.from_env()
73
- NodeContext.LOGGING_ENABLED = False
74
-
75
- # check if config name is allowed docker name, else exit
76
- check_config_name_allowed(ctx.name)
77
-
78
- # check that this node is not already running
79
- running_nodes = docker_client.containers.list(
80
- filters={"label": f"{APPNAME}-type={InstanceType.NODE.value}"}
81
- )
82
-
83
- suffix = "system" if system_folders else "user"
84
- for node in running_nodes:
85
- if node.name == f"{APPNAME}-{name}-{suffix}":
86
- error(f"Node {Fore.RED}{name}{Style.RESET_ALL} is already running")
87
- exit(1)
88
-
89
- # make sure the (host)-task and -log dir exists
90
- info("Checking that data and log dirs exist")
91
- ctx.data_dir.mkdir(parents=True, exist_ok=True)
92
- ctx.log_dir.mkdir(parents=True, exist_ok=True)
93
-
94
- # Determine image-name. First we check if the option --image has been used.
95
- # Then we check if the image has been specified in the config file, and
96
- # finally we use the default settings from the package.
97
- if not image:
98
- custom_images: dict = ctx.config.get("images")
99
- if custom_images:
100
- image = custom_images.get("node")
101
- else:
102
- # if no custom image is specified, find the server version and use
103
- # the latest images from that minor version
104
- client = create_client(ctx)
105
- major_minor = None
106
- try:
107
- # try to get server version, skip if can't get a connection
108
- version = client.util.get_server_version(attempts_on_timeout=3)[
109
- "version"
110
- ]
111
- major_minor = ".".join(version.split(".")[:2])
112
- image = (
113
- f"{DEFAULT_DOCKER_REGISTRY}/"
114
- f"{DEFAULT_NODE_IMAGE_WO_TAG}"
115
- f":{major_minor}"
116
- )
117
- except Exception:
118
- warning("Could not determine server version. Using default node image")
119
-
120
- if major_minor and not __version__.startswith(major_minor):
121
- warning(
122
- "Version mismatch between CLI and server/node. CLI is "
123
- f"running on version {__version__}, while node and server "
124
- f"are on version {major_minor}. This might cause "
125
- f"unexpected issues; changing to {major_minor}.<latest> "
126
- "is recommended."
127
- )
128
-
129
- # fail safe, in case no custom image is specified and we can't get the
130
- # server version
131
- if not image:
132
- image = f"{DEFAULT_DOCKER_REGISTRY}/{DEFAULT_NODE_IMAGE}"
133
-
134
- info(f"Pulling latest node image '{image}'")
135
- pull_infra_image(docker_client, image, InstanceType.NODE)
136
-
137
- data_volume = docker_client.volumes.create(ctx.docker_volume_name)
138
- vpn_volume = docker_client.volumes.create(ctx.docker_vpn_volume_name)
139
- ssh_volume = docker_client.volumes.create(ctx.docker_ssh_volume_name)
140
- squid_volume = docker_client.volumes.create(ctx.docker_squid_volume_name)
141
-
142
- info("Creating file & folder mounts")
143
- # FIXME: should obtain mount points from DockerNodeContext
144
- mounts = [
145
- # (target, source)
146
- ("/mnt/log", str(ctx.log_dir)),
147
- ("/mnt/data", data_volume.name),
148
- ("/mnt/vpn", vpn_volume.name),
149
- ("/mnt/ssh", ssh_volume.name),
150
- ("/mnt/squid", squid_volume.name),
151
- ("/mnt/config", str(ctx.config_dir)),
152
- ("/var/run/docker.sock", "/var/run/docker.sock"),
153
- ]
154
-
155
- if mount_src:
156
- # If mount_src is a relative path, docker will consider it a volume.
157
- mount_src = os.path.abspath(mount_src)
158
- mounts.append(("/vantage6", mount_src))
159
-
160
- # FIXME: Code duplication: Node.__init__() (vantage6/node/__init__.py)
161
- # uses a lot of the same logic. Suggest moving this to
162
- # ctx.get_private_key()
163
- filename = ctx.config.get("encryption", {}).get("private_key")
164
- # filename may be set to an empty string
165
- if not filename:
166
- filename = "private_key.pem"
167
-
168
- # Location may be overridden by the environment
169
- filename = os.environ.get("PRIVATE_KEY", filename)
170
-
171
- # If ctx.get_data_file() receives an absolute path, it is returned as-is
172
- fullpath = Path(ctx.get_data_file(filename))
173
- if fullpath:
174
- if Path(fullpath).exists():
175
- mounts.append(("/mnt/private_key.pem", str(fullpath)))
176
- else:
177
- warning(f"Private key file is provided {fullpath}, but does not exist")
178
-
179
- # Mount private keys for ssh tunnels
180
- ssh_tunnels = ctx.config.get("ssh-tunnels", [])
181
- for ssh_tunnel in ssh_tunnels:
182
- hostname = ssh_tunnel.get("hostname")
183
- key_path = ssh_tunnel.get("ssh", {}).get("identity", {}).get("key")
184
- if not key_path:
185
- error(
186
- f"SSH tunnel identity {Fore.RED}{hostname}{Style.RESET_ALL} "
187
- "key not provided. Continuing to start without this tunnel."
188
- )
189
- key_path = Path(key_path)
190
- if not key_path.exists():
191
- error(
192
- f"SSH tunnel identity {Fore.RED}{hostname}{Style.RESET_ALL} "
193
- "key does not exist. Continuing to start without this "
194
- "tunnel."
195
- )
196
-
197
- info(f" Mounting private key for {hostname} at {key_path}")
198
-
199
- # we remove the .tmp in the container, this is because the file is
200
- # mounted in a volume mount point. Somehow the file is than empty in
201
- # the volume but not for the node instance. By removing the .tmp we
202
- # make sure that the file is not empty in the volume.
203
- mounts.append((f"/mnt/ssh/{hostname}.pem.tmp", str(key_path)))
204
-
205
- env = {
206
- "DATA_VOLUME_NAME": data_volume.name,
207
- "VPN_VOLUME_NAME": vpn_volume.name,
208
- "PRIVATE_KEY": "/mnt/private_key.pem",
209
- }
210
-
211
- # only mount the DB if it is a file
212
- info("Setting up databases")
213
- dbs = [TaskDB.from_dict(db) for db in ctx.databases]
214
- for db in dbs:
215
- # check that label contains only valid characters
216
- if not db.label.isidentifier():
217
- error(
218
- f"Database label {Fore.RED}{db.label}{Style.RESET_ALL} contains"
219
- " invalid characters. Only letters, numbers, and underscores"
220
- " are allowed, and it cannot start with a number."
221
- )
222
- exit(1)
223
-
224
- info(
225
- f" Processing {Fore.GREEN}{db.type}{Style.RESET_ALL} database "
226
- f"{Fore.GREEN}{db.label}:{db.uri}{Style.RESET_ALL}"
227
- )
228
- label_capitals = db.label.upper()
229
-
230
- try:
231
- db_file_exists = Path(db.uri).exists()
232
- except Exception:
233
- # If the database uri cannot be parsed, it is definitely not a
234
- # file. In case of http servers or sql servers, checking the path
235
- # of the the uri will lead to an OS-dependent error, which is why
236
- # we catch all exceptions here.
237
- db_file_exists = False
238
-
239
- if db.type.is_file_based() and not db_file_exists:
240
- error(
241
- f"Database {Fore.RED}{db.uri}{Style.RESET_ALL} not found. Databases of "
242
- f"type '{db.type}' must be present on the harddrive. Please "
243
- "update your node configuration file."
244
- )
245
- exit(1)
246
-
247
- if not db_file_exists and not force_db_mount:
248
- debug(" - non file-based database added")
249
- env[f"{label_capitals}_DATABASE_URI"] = db.uri
250
- else:
251
- debug(" - file-based database added")
252
- suffix = Path(db.uri).suffix
253
- env[f"{label_capitals}_DATABASE_URI"] = f"{db.label}{suffix}"
254
- mounts.append((f"/mnt/{db.label}{suffix}", str(db.uri)))
255
-
256
- system_folders_option = "--system" if system_folders else "--user"
257
- cmd = (
258
- f"vnode-local start -c /mnt/config/{name}.yaml -n {name} "
259
- f" --dockerized {system_folders_option}"
260
- )
261
-
262
- volumes = []
263
- for mount in mounts:
264
- volumes.append(f"{mount[1]}:{mount[0]}")
265
-
266
- extra_mounts = ctx.config.get("node_extra_mounts", [])
267
- for mount in extra_mounts:
268
- volumes.append(mount)
269
-
270
- extra_env = ctx.config.get("node_extra_env", {})
271
- # all extra env var names should be valid identifiers
272
- extra_env_invalid = [key for key in extra_env.keys() if not key.isidentifier()]
273
- if extra_env_invalid:
274
- error(
275
- "Environment variable names should be valid identifiers. "
276
- f"The following break this rule: {extra_env_invalid}"
277
- )
278
- exit(1)
279
- # we won't accept overwrites of existing env vars
280
- env_overwrites = extra_env.keys() & env.keys()
281
- if env_overwrites:
282
- error(f"Cannot overwrite existing node environment variables: {env_overwrites}")
283
- exit(1)
284
- env.update(extra_env)
285
-
286
- # Add extra hosts to the environment
287
- extra_hosts = ctx.config.get("node_extra_hosts", {})
288
-
289
- remove_container_if_exists(
290
- docker_client=docker_client, name=ctx.docker_container_name
291
- )
292
43
 
293
- info("Running Docker container")
294
- container = docker_client.containers.run(
295
- image,
296
- command=cmd,
297
- volumes=volumes,
298
- detach=True,
299
- labels={
300
- f"{APPNAME}-type": InstanceType.NODE.value,
301
- "system": str(system_folders),
302
- "name": ctx.config_file_name,
303
- },
304
- environment=env,
305
- name=ctx.docker_container_name,
306
- auto_remove=not keep,
307
- tty=True,
308
- extra_hosts=extra_hosts,
44
+ prestart_checks(ctx, InstanceType.NODE, name, system_folders, context, namespace)
45
+
46
+ create_directory_if_not_exists(ctx.log_dir)
47
+ create_directory_if_not_exists(ctx.data_dir)
48
+
49
+ # TODO issue #2256 - run same version node as server
50
+ # # Determine image-name. First we check if the option --image has been used.
51
+ # # Then we check if the image has been specified in the config file, and
52
+ # # finally we use the default settings from the package.
53
+ # if not image:
54
+ # custom_images: dict = ctx.config.get("images")
55
+ # if custom_images:
56
+ # image = custom_images.get("node")
57
+ # else:
58
+ # # if no custom image is specified, find the server version and use
59
+ # # the latest images from that minor version
60
+ # client = create_client(ctx)
61
+ # major_minor = None
62
+ # try:
63
+ # # try to get server version, skip if can't get a connection
64
+ # version = client.util.get_server_version(attempts_on_timeout=3)[
65
+ # "version"
66
+ # ]
67
+ # major_minor = ".".join(version.split(".")[:2])
68
+ # image = (
69
+ # f"{DEFAULT_DOCKER_REGISTRY}/"
70
+ # f"{DEFAULT_NODE_IMAGE_WO_TAG}"
71
+ # f":{major_minor}"
72
+ # )
73
+ # except Exception:
74
+ # warning("Could not determine server version. Using default node image")
75
+
76
+ # if major_minor and not __version__.startswith(major_minor):
77
+ # warning(
78
+ # "Version mismatch between CLI and server/node. CLI is "
79
+ # f"running on version {__version__}, while node and server "
80
+ # f"are on version {major_minor}. This might cause "
81
+ # f"unexpected issues; changing to {major_minor}.<latest> "
82
+ # "is recommended."
83
+ # )
84
+
85
+ # # fail safe, in case no custom image is specified and we can't get the
86
+ # # server version
87
+ # if not image:
88
+ # image = f"{DEFAULT_DOCKER_REGISTRY}/{DEFAULT_NODE_IMAGE}"
89
+
90
+ # info(f"Pulling latest node image '{image}'")
91
+ # pull_infra_image(docker_client, image, InstanceType.NODE)
92
+
93
+ helm_install(
94
+ release_name=ctx.helm_release_name,
95
+ chart_name=ChartName.NODE,
96
+ values_file=ctx.config_file,
97
+ context=context,
98
+ namespace=namespace,
309
99
  )
310
100
 
311
- info("Node container was started!")
312
- info(
313
- "Please check the node logs to see if the node successfully connects to the "
314
- "server."
101
+ # start port forward for the node proxy server
102
+ start_port_forward(
103
+ service_name=f"{ctx.helm_release_name}-node-service",
104
+ service_port=ctx.config["node"].get("port", DEFAULT_PROXY_SERVER_PORT),
105
+ port=ctx.config["node"].get("port", DEFAULT_PROXY_SERVER_PORT),
106
+ context=context,
107
+ namespace=namespace,
315
108
  )
316
109
 
317
110
  if attach:
318
- logs = container.attach(stream=True, logs=True)
319
- Thread(target=print_log_worker, args=(logs,), daemon=True).start()
320
- while True:
321
- try:
322
- time.sleep(1)
323
- except KeyboardInterrupt:
324
- info("Closing log file. Keyboard Interrupt.")
325
- info(
326
- "Note that your node is still running! Shut it down with "
327
- f"'{Fore.RED}v6 node stop{Style.RESET_ALL}'"
328
- )
329
- exit(0)
330
- else:
331
- info(
332
- f"To see the logs, run: {Fore.GREEN}v6 node attach --name "
333
- f"{ctx.name}{Style.RESET_ALL}"
334
- )
111
+ attach_logs("app=node")