lookout-cli 1.0.0__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.
@@ -0,0 +1,43 @@
1
+ Metadata-Version: 2.1
2
+ Name: lookout_cli
3
+ Version: 1.0.0
4
+ Summary: A CLI for interacting with Lookout+
5
+ Home-page: https://github.com/Greenroom-Robotics/lookout
6
+ Author: Greenroom Robotics
7
+ Author-email: team@greenroomrobotics.com
8
+ Maintainer: David Revay
9
+ Maintainer-email: david.revay@greenroomrobotics.com
10
+ License: Copyright (C) 2023, Greenroom Robotics
11
+ Keywords: colcon
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Plugins
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Programming Language :: Python
16
+ Classifier: Topic :: Software Development :: Build Tools
17
+ Description-Content-Type: text/markdown
18
+ Requires-Dist: toml~=0.10
19
+ Requires-Dist: setuptools
20
+ Requires-Dist: colorama
21
+ Requires-Dist: click
22
+ Requires-Dist: lookout-config
23
+ Requires-Dist: python-on-whales
24
+ Requires-Dist: PyYAML
25
+
26
+ # Lookout CLI
27
+
28
+ Publicly available on [PyPi](https://pypi.org/project/lookout-cli/) for convenience but if you don't work at Greenroom Robotics, you probably don't want to use this.
29
+
30
+ ## Install
31
+
32
+ * For development:
33
+ * `pip install -e ./libs/lookout_config`
34
+ * `pip install -e ./tools/lookout_cli`
35
+ * For production: `pip install lookout-cli`
36
+ * You may also need to `export PATH=$PATH:~/.local/bin` if you don't have `~/.local/bin` in your path
37
+ * Install autocomplete:
38
+ * bash: `echo 'eval "$(_lookout_COMPLETE=bash_source lookout)"' >> ~/.bashrc`
39
+ * zsh: `echo 'eval "$(_lookout_COMPLETE=zsh_source lookout)"' >> ~/.zshrc` (this is much nicer)
40
+
41
+ ## Usage
42
+
43
+ * `lookout --help` to get help with the CLI
@@ -0,0 +1,18 @@
1
+ # Lookout CLI
2
+
3
+ Publicly available on [PyPi](https://pypi.org/project/lookout-cli/) for convenience but if you don't work at Greenroom Robotics, you probably don't want to use this.
4
+
5
+ ## Install
6
+
7
+ * For development:
8
+ * `pip install -e ./libs/lookout_config`
9
+ * `pip install -e ./tools/lookout_cli`
10
+ * For production: `pip install lookout-cli`
11
+ * You may also need to `export PATH=$PATH:~/.local/bin` if you don't have `~/.local/bin` in your path
12
+ * Install autocomplete:
13
+ * bash: `echo 'eval "$(_lookout_COMPLETE=bash_source lookout)"' >> ~/.bashrc`
14
+ * zsh: `echo 'eval "$(_lookout_COMPLETE=zsh_source lookout)"' >> ~/.zshrc` (this is much nicer)
15
+
16
+ ## Usage
17
+
18
+ * `lookout --help` to get help with the CLI
File without changes
@@ -0,0 +1,16 @@
1
+ import click
2
+
3
+
4
+ def get_banner(mode: str, version: str):
5
+ return "\n".join(
6
+ [
7
+ "\b",
8
+ click.style("Lookout+ CLI", fg="black", bg="green"),
9
+ "\b",
10
+ "Mode: "
11
+ + click.style(mode, fg="green")
12
+ + " - Version: "
13
+ + click.style(version, fg="yellow"),
14
+ "Powered by: " + click.style("Greenroom Robotics", fg="green"),
15
+ ]
16
+ )
@@ -0,0 +1,40 @@
1
+ import lookout_cli.groups.misc as misc
2
+ import lookout_cli.groups.setup as setup
3
+ from lookout_cli.helpers import is_dev_version, get_version
4
+ from lookout_cli.banner import get_banner
5
+ import click
6
+ import os
7
+
8
+
9
+ def cli():
10
+ dev_mode = is_dev_version()
11
+ version = get_version()
12
+ mode = "Developer" if dev_mode else "User"
13
+ banner = get_banner(mode, version)
14
+
15
+ os.environ["LOOKOUT_CLI_DEV_MODE"] = "true" if dev_mode else "false"
16
+
17
+ @click.group(help=banner)
18
+ def lookout_cli():
19
+ pass
20
+
21
+ lookout_cli.add_command(misc.authenticate)
22
+ lookout_cli.add_command(misc.upgrade)
23
+ lookout_cli.add_command(misc.build)
24
+ lookout_cli.add_command(misc.down)
25
+ lookout_cli.add_command(misc.up)
26
+ lookout_cli.add_command(misc.configure)
27
+ lookout_cli.add_command(misc.config)
28
+
29
+ if dev_mode:
30
+ lookout_cli.add_command(misc.lint)
31
+ lookout_cli.add_command(misc.bake)
32
+ lookout_cli.add_command(misc.type_generate)
33
+ lookout_cli.add_command(setup.setup)
34
+ setup.setup.add_command(setup.secrets)
35
+
36
+ lookout_cli()
37
+
38
+
39
+ if __name__ == "__main__":
40
+ cli()
@@ -0,0 +1,76 @@
1
+ version: "3.8"
2
+ name: lookout
3
+
4
+ services:
5
+ lookout_core:
6
+ build:
7
+ context: ./
8
+ dockerfile: projects/lookout_core/Dockerfile
9
+ args:
10
+ GPU: ${GPU:-false}
11
+ secrets:
12
+ - apt_conf
13
+ - API_TOKEN_GITHUB
14
+ volumes:
15
+ - ./projects/lookout_core/src:/home/ros/lookout_core/src
16
+ - ./projects/lookout_core/data:/home/ros/lookout_core/data
17
+ - ./projects/lookout_core/ros-ts-generator-config.json:/home/ros/lookout_core/ros-ts-generator-config.json
18
+ - ./projects/lookout_ui/src/generated/ros:/home/ros/lookout_core/generated/ros
19
+ - ./logs/rosbags:/home/ros/rosbags
20
+ - ./logs/scripts:/home/ros/rosbag_scripts
21
+ - ./.secrets/apt.conf:/etc/apt/auth.conf.d/greenroom-robotics.conf
22
+
23
+ lookout_ui:
24
+ image: ghcr.io/greenroom-robotics/lookout_ui:${LOOKOUT_VERSION:-latest}
25
+ build:
26
+ context: ./projects/lookout_ui
27
+ secrets:
28
+ - API_TOKEN_GITHUB
29
+ args:
30
+ VITE_LOOKOUT_NAMESPACE_VESSEL: $LOOKOUT_NAMESPACE_VESSEL
31
+ environment:
32
+ VITE_LOOKOUT_NAMESPACE_VESSEL: $LOOKOUT_NAMESPACE_VESSEL
33
+ volumes:
34
+ - ./projects/lookout_ui/.eslintrc.js:/app/.eslintrc.js
35
+ - ./projects/lookout_ui/.nvmrc:/app/.nvmrc
36
+ - ./projects/lookout_ui/.prettierrc:/app/.prettierrc
37
+ - ./projects/lookout_ui/.yarnrc:/app/.yarnrc
38
+ - ./projects/lookout_ui/index.html:/app/index.html
39
+ - ./projects/lookout_ui/package.json:/app/package.json
40
+ - ./projects/lookout_ui/public:/app/public
41
+ - ./projects/lookout_ui/src:/app/src
42
+ - ./projects/lookout_ui/tsconfig.json:/app/tsconfig.json
43
+ - ./projects/lookout_ui/typings:/app/typings
44
+ - ./projects/lookout_ui/vite.config.ts:/app/vite.config.ts
45
+ command: yarn dev
46
+
47
+ lookout_greenstream:
48
+ build:
49
+ context: .
50
+ dockerfile: projects/lookout_greenstream/Dockerfile
51
+ secrets:
52
+ - apt_conf
53
+ - API_TOKEN_GITHUB
54
+ volumes:
55
+ - ./projects/lookout_greenstream:/home/greenstream
56
+
57
+ lookout_docs:
58
+ build:
59
+ context: ./
60
+ dockerfile: projects/lookout_docs/Dockerfile
61
+ volumes:
62
+ - ./projects/lookout_docs/src:/app/src
63
+ - ./projects/lookout_docs/static:/app/static
64
+ - ./projects/lookout_docs/package.json:/app/package.json
65
+ - ./projects/lookout_docs/yarn.lock:/app/yarn.lock
66
+ - ./projects/lookout_docs/sidebars.js:/app/sidebars.js
67
+ - ./projects/lookout_docs/docusaurus.config.js:/app/docusaurus.config.js
68
+ - ./projects/lookout_docs/tsconfig.json:/app/tsconfig.json
69
+ - ./docs:/app/docs
70
+ command: yarn start
71
+
72
+ secrets:
73
+ API_TOKEN_GITHUB:
74
+ file: ./.secrets/API_TOKEN_GITHUB
75
+ apt_conf:
76
+ file: ./.secrets/apt.conf
@@ -0,0 +1,15 @@
1
+ version: "3.8"
2
+ name: lookout
3
+
4
+ services:
5
+ lookout_core:
6
+ build:
7
+ args:
8
+ GPU: ${GPU:-true}
9
+ deploy:
10
+ resources:
11
+ reservations:
12
+ devices:
13
+ - driver: nvidia
14
+ count: 1
15
+ capabilities: [gpu]
@@ -0,0 +1,18 @@
1
+ version: "3.8"
2
+ name: lookout
3
+
4
+ services:
5
+ lookout_core:
6
+ network_mode: host
7
+
8
+ lookout_ui:
9
+ ports:
10
+ - "4000:4000"
11
+
12
+ lookout_greenstream:
13
+ network_mode: host
14
+
15
+ lookout_docs:
16
+ ports:
17
+ - "4010:3000"
18
+
@@ -0,0 +1,33 @@
1
+ version: "3.8"
2
+ name: lookout
3
+
4
+ services:
5
+ lookout_core:
6
+ ports:
7
+ - 4001:4001
8
+ networks:
9
+ - vessel
10
+
11
+ lookout_ui:
12
+ ports:
13
+ - "4000:4000"
14
+ networks:
15
+ - vessel
16
+
17
+ lookout_greenstream:
18
+ ports:
19
+ - 8000:8000
20
+ - 8443:8443
21
+ networks:
22
+ - vessel
23
+
24
+ lookout_docs:
25
+ ports:
26
+ - "4010:3000"
27
+ networks:
28
+ - vessel
29
+
30
+ networks:
31
+ vessel:
32
+ external: true
33
+ name: gama_vessel
@@ -0,0 +1,37 @@
1
+ version: "3.8"
2
+ name: lookout
3
+
4
+ services:
5
+ lookout_core:
6
+ container_name: lookout_core
7
+ image: ghcr.io/greenroom-robotics/lookout_core:${LOOKOUT_VERSION:-latest}
8
+ volumes:
9
+ - /dev:/dev
10
+ - ~/.config/greenroom:/home/ros/.config/greenroom
11
+ command: ${LOOKOUT_CORE_COMMAND:-tail -f /dev/null}
12
+ privileged: true
13
+ ipc: host
14
+ pid: host
15
+ environment:
16
+ - ROS_DOMAIN_ID
17
+
18
+ lookout_ui:
19
+ container_name: lookout_ui
20
+ image: ghcr.io/greenroom-robotics/lookout_ui:${LOOKOUT_VERSION:-latest}
21
+
22
+ lookout_greenstream:
23
+ container_name: lookout_greenstream
24
+ image: ghcr.io/greenroom-robotics/lookout_greenstream
25
+ volumes:
26
+ - /dev:/dev
27
+ - ~/.config/greenroom:/home/ros/.config/greenroom
28
+ privileged: true
29
+ ipc: host
30
+ pid: host
31
+ environment:
32
+ - ROS_DOMAIN_ID
33
+
34
+ lookout_docs:
35
+ container_name: lookout_docs
36
+ image: ghcr.io/greenroom-robotics/lookout_docs:${LOOKOUT_VERSION:-latest}
37
+
File without changes
@@ -0,0 +1,267 @@
1
+ import click
2
+ from typing import List
3
+ from lookout_cli.helpers import (
4
+ docker_compose_path,
5
+ get_project_root,
6
+ docker_bake,
7
+ call,
8
+ get_version,
9
+ )
10
+
11
+ from python_on_whales.docker_client import DockerClient
12
+ from python_on_whales.utils import ValidPath
13
+ import lookout_config
14
+ from lookout_config import LookoutConfig, LogLevel, Mode, Network
15
+ import os
16
+
17
+ DOCKER_GS = docker_compose_path("./docker-compose.yaml")
18
+ DOCKER_GS_DEV = docker_compose_path("./docker-compose.dev.yaml")
19
+ DOCKER_NETWORK_SHARED = docker_compose_path("./docker-compose.network-shared.yaml")
20
+ DOCKER_NETWORK_HOST = docker_compose_path("./docker-compose.network-host.yaml")
21
+ DOCKER_GPU = docker_compose_path("./docker-compose.gpu.yaml")
22
+
23
+
24
+ def _get_compose_files(
25
+ prod: bool = False, network: Network = Network.HOST, gpu=False
26
+ ) -> List[ValidPath]:
27
+ compose_files: List[ValidPath] = [DOCKER_GS]
28
+
29
+ if not prod:
30
+ compose_files.append(DOCKER_GS_DEV)
31
+
32
+ if network == Network.SHARED:
33
+ compose_files.append(DOCKER_NETWORK_SHARED)
34
+
35
+ if network == Network.HOST:
36
+ compose_files.append(DOCKER_NETWORK_HOST)
37
+
38
+ if gpu:
39
+ compose_files.append(DOCKER_GPU)
40
+
41
+ return compose_files
42
+
43
+
44
+ def log_config(config: LookoutConfig):
45
+ click.echo(click.style("[+] Lookout Config:", fg="green"))
46
+ for attr, value in config.__dict__.items():
47
+ click.echo(
48
+ click.style(f" ⠿ {attr}: ".ljust(27), fg="white") + click.style(str(value), fg="green")
49
+ )
50
+
51
+
52
+ @click.command(name="up")
53
+ @click.option(
54
+ "--build",
55
+ type=bool,
56
+ default=False,
57
+ is_flag=True,
58
+ help="Should we rebuild the docker containers? Default: False",
59
+ )
60
+ @click.argument("args", nargs=-1)
61
+ def up(
62
+ build: bool,
63
+ args: List[str],
64
+ ):
65
+ """Starts lookout"""
66
+ config = lookout_config.read()
67
+ log_config(config)
68
+
69
+ os.environ["ROS_DOMAIN_ID"] = str(config.ros_domain_id)
70
+ os.environ["LOOKOUT_NAMESPACE_VESSEL"] = config.namespace_vessel
71
+ os.environ[
72
+ "LOOKOUT_CORE_COMMAND"
73
+ ] = "platform ros launch lookout_bringup lookout.launch.py --build --watch"
74
+ if not args:
75
+ services = ["lookout_docs", "lookout_core", "lookout_ui", "lookout_greenstream"]
76
+ else:
77
+ services = [arg for arg in args]
78
+
79
+ docker = DockerClient(
80
+ compose_files=_get_compose_files(False, config.network, config.gpu),
81
+ compose_project_directory=get_project_root(),
82
+ )
83
+ docker.compose.up(services, detach=True, build=build)
84
+
85
+ click.echo(click.style("UI started: http://localhost:4000", fg="green"))
86
+
87
+
88
+ @click.command(name="down")
89
+ @click.argument("args", nargs=-1)
90
+ def down(args: List[str]):
91
+ """Stops lookout"""
92
+
93
+ docker = DockerClient(
94
+ compose_files=_get_compose_files(),
95
+ compose_project_directory=get_project_root(),
96
+ )
97
+ docker.compose.down()
98
+
99
+
100
+ @click.command(name="build")
101
+ @click.option(
102
+ "--no-cache",
103
+ type=bool,
104
+ default=False,
105
+ is_flag=True,
106
+ help="Should we rebuild without the docker cache?",
107
+ )
108
+ @click.argument("services", nargs=-1)
109
+ def build(no_cache: bool, services: List[str]):
110
+ """Builds the Lookout docker containers"""
111
+ config = lookout_config.read()
112
+ os.environ["LOOKOUT_NAMESPACE_VESSEL"] = config.namespace_vessel
113
+
114
+ docker = DockerClient(
115
+ compose_files=_get_compose_files(gpu=config.gpu),
116
+ compose_project_directory=get_project_root(),
117
+ )
118
+ docker.compose.build(services=services, cache=not no_cache)
119
+
120
+
121
+ @click.command(name="bake")
122
+ @click.option(
123
+ "--version",
124
+ type=str,
125
+ required=True,
126
+ help="The version to bake. Default: latest",
127
+ )
128
+ @click.option(
129
+ "--push",
130
+ type=bool,
131
+ default=False,
132
+ is_flag=True,
133
+ help="Should we push the images to the registry? Default: False",
134
+ )
135
+ @click.argument("services", nargs=-1)
136
+ def bake(version: str, push: bool, services: List[str]): # type: ignore
137
+ """Bakes the docker containers"""
138
+ compose_files = _get_compose_files()
139
+ docker_bake(
140
+ version=version,
141
+ services=services,
142
+ push=push,
143
+ compose_files=compose_files,
144
+ )
145
+
146
+
147
+ @click.command(name="lint")
148
+ def lint():
149
+ """Lints all the things"""
150
+ call("pre-commit run --all")
151
+
152
+
153
+ @click.command(name="type-generate")
154
+ def type_generate(): # type: ignore
155
+ """Generates typescript types for all ros messages"""
156
+ docker = DockerClient(
157
+ compose_files=_get_compose_files(),
158
+ compose_project_directory=get_project_root(),
159
+ )
160
+ docker.compose.run("lookout_core", ["npx", "ros-typescript-generator"])
161
+
162
+
163
+ @click.command(name="upgrade")
164
+ @click.option("--version", help="The version to upgrade to.")
165
+ def upgrade(version: str):
166
+ """Upgrade Lookout CLI"""
167
+ click.echo(f"Current version: {get_version()}")
168
+ result = click.prompt(
169
+ "Are you sure you want to upgrade?", default="y", type=click.Choice(["y", "n"])
170
+ )
171
+ if result == "n":
172
+ return
173
+
174
+ if version:
175
+ call(f"pip install --upgrade lookout-cli=={version}")
176
+ else:
177
+ call("pip install --upgrade lookout-cli")
178
+
179
+ click.echo(click.style("Upgrade of Lookout CLI complete.", fg="green"))
180
+
181
+
182
+ @click.command(name="authenticate")
183
+ @click.option(
184
+ "--username",
185
+ help="The username to use for authentication.",
186
+ required=True,
187
+ prompt=True,
188
+ )
189
+ @click.option("--token", help="The token to use for authentication.", required=True, prompt=True)
190
+ def authenticate(username: str, token: str):
191
+ """
192
+ Authenticate with the package repository so that you can pull images.
193
+
194
+ To get a username and token you'll need to contact a Greenroom Robotics employee.
195
+ """
196
+ call(f"echo {token} | docker login ghcr.io -u {username} --password-stdin")
197
+
198
+
199
+ @click.command(name="config")
200
+ def config(): # type: ignore
201
+ """Read Config"""
202
+ config = lookout_config.read()
203
+ log_config(config)
204
+
205
+
206
+ @click.command(name="configure")
207
+ @click.option("--default", is_flag=True, help="Use default values")
208
+ def configure(default: bool): # type: ignore
209
+ """Configure Lookout"""
210
+
211
+ if default:
212
+ config = LookoutConfig()
213
+ lookout_config.write(config)
214
+ else:
215
+ # Check if the file exists
216
+ if os.path.exists(lookout_config.get_path()):
217
+ click.echo(
218
+ click.style(
219
+ f"Lookout config already exists: {lookout_config.get_path()}",
220
+ fg="yellow",
221
+ )
222
+ )
223
+ result = click.prompt(
224
+ "Do you want to overwrite it?", default="y", type=click.Choice(["y", "n"])
225
+ )
226
+ if result == "n":
227
+ return
228
+
229
+ try:
230
+ config_current = lookout_config.read()
231
+ except Exception:
232
+ config_current = LookoutConfig()
233
+
234
+ config = LookoutConfig(
235
+ ros_domain_id=click.prompt(
236
+ "ROS Domain ID", default=config_current.ros_domain_id, type=int
237
+ ),
238
+ namespace_vessel=click.prompt(
239
+ "Namespace Vessel", default=config_current.namespace_vessel
240
+ ),
241
+ mode=click.prompt(
242
+ "Mode",
243
+ default=config_current.mode,
244
+ type=click.Choice([item.value for item in Mode]),
245
+ ),
246
+ gama_vessel=click.prompt(
247
+ "Is this running on a Gama Vessel?",
248
+ default=config_current.gama_vessel,
249
+ type=bool,
250
+ ),
251
+ log_level=click.prompt(
252
+ "Log level",
253
+ default=config_current.log_level,
254
+ type=click.Choice([item.value for item in LogLevel]),
255
+ ),
256
+ network=click.prompt(
257
+ "Network",
258
+ default=config_current.network,
259
+ type=click.Choice([item.value for item in Network]),
260
+ ),
261
+ gpu=click.prompt(
262
+ "Should we use the GPU?",
263
+ default=config_current.gpu,
264
+ type=bool,
265
+ ),
266
+ )
267
+ lookout_config.write(config)
@@ -0,0 +1,32 @@
1
+ import click
2
+
3
+ from lookout_cli.helpers import get_project_root
4
+ from pathlib import Path
5
+
6
+
7
+ def write_file(path: str, content: str):
8
+ project_root = get_project_root() or Path()
9
+ click.echo(f"Writing file {project_root / path}")
10
+ with open(project_root / path, "w") as f:
11
+ f.write(content)
12
+
13
+
14
+ @click.group(help="Setup commands")
15
+ def setup():
16
+ pass
17
+
18
+
19
+ @click.command(name="secrets")
20
+ @click.argument("pat")
21
+ def secrets(pat: str): # type: ignore
22
+ """Setup the .secrets files as docker secrets needs these to build containers"""
23
+ write_file(".secrets/API_TOKEN_GITHUB", pat)
24
+
25
+ greenroom_apt_conf = "\n".join(
26
+ [
27
+ "machine raw.githubusercontent.com/Greenroom-Robotics",
28
+ f"login {pat}",
29
+ "password",
30
+ ]
31
+ )
32
+ write_file(".secrets/apt.conf", greenroom_apt_conf)
@@ -0,0 +1,117 @@
1
+ from typing import List, Dict, Any, Optional
2
+ import click
3
+ import os
4
+ from pathlib import Path
5
+ import subprocess
6
+ import yaml
7
+ import platform
8
+ from python_on_whales.utils import ValidPath
9
+ import pkg_resources
10
+
11
+
12
+ def get_project_root() -> Path:
13
+ current_file_dir = Path(__file__).parent
14
+ return current_file_dir.parent.parent.parent
15
+
16
+
17
+ def get_version():
18
+ """version is latest if it is a dev version otherwise it is the CLI version"""
19
+ version = pkg_resources.require("lookout-cli")[0].version
20
+ if version == "0.0.0":
21
+ version = "latest"
22
+ return version
23
+
24
+
25
+ def is_dev_version():
26
+ if os.environ.get("LOOKOUT_CLI_DEV_MODE") == "false":
27
+ return False
28
+
29
+ if os.environ.get("LOOKOUT_CLI_DEV_MODE") == "true":
30
+ return True
31
+ return pkg_resources.require("lookout_cli")[0].version == "0.0.0"
32
+
33
+
34
+ def docker_compose_path(path: str) -> Path:
35
+ current_file_dir = Path(__file__).parent
36
+ return current_file_dir / "docker" / path
37
+
38
+
39
+ def call(command: str, abort: bool = True, env: Optional[Dict[str, Any]] = None):
40
+ click.echo(click.style(f"Running: {command}", fg="blue"))
41
+ if env:
42
+ env = {**os.environ, **env}
43
+
44
+ prj_root = get_project_root()
45
+ error = subprocess.call(command, shell=True, executable="/bin/bash", cwd=prj_root, env=env)
46
+ if error and abort:
47
+ raise click.ClickException("Failed")
48
+
49
+
50
+ def get_arch():
51
+ arch = platform.machine()
52
+ if arch == "x86_64":
53
+ return "amd64"
54
+ elif arch == "aarch64":
55
+ return "arm64"
56
+ else:
57
+ print(f"Unsupported arch: {arch}")
58
+ exit(1)
59
+
60
+
61
+ def docker_bake(version: str, compose_files: List[ValidPath], push: bool, services: List[str]):
62
+ compose_args: list[str] = []
63
+ for f in compose_files:
64
+ compose_args.append(f"--file {f}")
65
+
66
+ # Load the compose config
67
+ file_args = " ".join(compose_args)
68
+ command_get_config = f"docker compose {file_args} config"
69
+ print("Running command: ", command_get_config)
70
+ config = subprocess.run(
71
+ command_get_config, shell=True, check=True, cwd=get_project_root(), capture_output=True
72
+ )
73
+ config = config.stdout.decode("utf-8")
74
+ config = yaml.safe_load(config)
75
+
76
+ # Create the bake command args
77
+ bake_args = compose_args
78
+ bake_args.append(
79
+ "--provenance=false"
80
+ ) # this allows us to create a multi-arch manifest at a later stage
81
+
82
+ # Get the arch
83
+ arch = get_arch()
84
+
85
+ # Get all services we should build and set their tags and arch
86
+ services_actual: list[str] = []
87
+ for service, service_config in config["services"].items():
88
+ if "image" in service_config and "build" in service_config:
89
+ # If we have a list of services to build, only build those
90
+ if len(services) == 0 or service in services:
91
+ image = service_config["image"]
92
+ image = image.split(":")[0]
93
+ bake_args.append(f"--set {service}.platform=linux/{arch}")
94
+ bake_args.append(f"--set {service}.tags={image}:{version}-{arch}")
95
+ bake_args.append(f"--set {service}.tags={image}:latest-{arch}")
96
+ services_actual.append(service)
97
+
98
+ # Add other args
99
+ if push:
100
+ bake_args.append("--push")
101
+
102
+ print(f"Baking services: {', '.join(services_actual)}...")
103
+ bake_command = " ".join(
104
+ [
105
+ "docker buildx bake",
106
+ " ".join(bake_args),
107
+ " ".join(services_actual),
108
+ ]
109
+ )
110
+
111
+ print("Running bake command: ", bake_command)
112
+ subprocess.run(
113
+ bake_command,
114
+ shell=True,
115
+ check=True,
116
+ cwd=get_project_root(),
117
+ )
@@ -0,0 +1,3 @@
1
+ def test_lookout_cli():
2
+ # TODO: Add tests
3
+ assert True is True
@@ -0,0 +1,43 @@
1
+ Metadata-Version: 2.1
2
+ Name: lookout_cli
3
+ Version: 1.0.0
4
+ Summary: A CLI for interacting with Lookout+
5
+ Home-page: https://github.com/Greenroom-Robotics/lookout
6
+ Author: Greenroom Robotics
7
+ Author-email: team@greenroomrobotics.com
8
+ Maintainer: David Revay
9
+ Maintainer-email: david.revay@greenroomrobotics.com
10
+ License: Copyright (C) 2023, Greenroom Robotics
11
+ Keywords: colcon
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Plugins
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Programming Language :: Python
16
+ Classifier: Topic :: Software Development :: Build Tools
17
+ Description-Content-Type: text/markdown
18
+ Requires-Dist: toml~=0.10
19
+ Requires-Dist: setuptools
20
+ Requires-Dist: colorama
21
+ Requires-Dist: click
22
+ Requires-Dist: lookout-config
23
+ Requires-Dist: python-on-whales
24
+ Requires-Dist: PyYAML
25
+
26
+ # Lookout CLI
27
+
28
+ Publicly available on [PyPi](https://pypi.org/project/lookout-cli/) for convenience but if you don't work at Greenroom Robotics, you probably don't want to use this.
29
+
30
+ ## Install
31
+
32
+ * For development:
33
+ * `pip install -e ./libs/lookout_config`
34
+ * `pip install -e ./tools/lookout_cli`
35
+ * For production: `pip install lookout-cli`
36
+ * You may also need to `export PATH=$PATH:~/.local/bin` if you don't have `~/.local/bin` in your path
37
+ * Install autocomplete:
38
+ * bash: `echo 'eval "$(_lookout_COMPLETE=bash_source lookout)"' >> ~/.bashrc`
39
+ * zsh: `echo 'eval "$(_lookout_COMPLETE=zsh_source lookout)"' >> ~/.zshrc` (this is much nicer)
40
+
41
+ ## Usage
42
+
43
+ * `lookout --help` to get help with the CLI
@@ -0,0 +1,23 @@
1
+ README.md
2
+ setup.cfg
3
+ setup.py
4
+ lookout_cli/__init__.py
5
+ lookout_cli/banner.py
6
+ lookout_cli/cli.py
7
+ lookout_cli/helpers.py
8
+ lookout_cli.egg-info/PKG-INFO
9
+ lookout_cli.egg-info/SOURCES.txt
10
+ lookout_cli.egg-info/dependency_links.txt
11
+ lookout_cli.egg-info/entry_points.txt
12
+ lookout_cli.egg-info/requires.txt
13
+ lookout_cli.egg-info/top_level.txt
14
+ lookout_cli.egg-info/zip-safe
15
+ lookout_cli/docker/docker-compose.dev.yaml
16
+ lookout_cli/docker/docker-compose.gpu.yaml
17
+ lookout_cli/docker/docker-compose.network-host.yaml
18
+ lookout_cli/docker/docker-compose.network-shared.yaml
19
+ lookout_cli/docker/docker-compose.yaml
20
+ lookout_cli/groups/__init__.py
21
+ lookout_cli/groups/misc.py
22
+ lookout_cli/groups/setup.py
23
+ lookout_cli/test/lookout_cli_test.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ lookout = lookout_cli.cli:cli
@@ -0,0 +1,7 @@
1
+ toml~=0.10
2
+ setuptools
3
+ colorama
4
+ click
5
+ lookout-config
6
+ python-on-whales
7
+ PyYAML
@@ -0,0 +1 @@
1
+ lookout_cli
@@ -0,0 +1,48 @@
1
+ [metadata]
2
+ name = lookout_cli
3
+ version = 1.0.0
4
+ url = https://github.com/Greenroom-Robotics/lookout
5
+ author = Greenroom Robotics
6
+ author_email = team@greenroomrobotics.com
7
+ maintainer = David Revay
8
+ maintainer_email = david.revay@greenroomrobotics.com
9
+ classifiers =
10
+ Development Status :: 3 - Alpha
11
+ Environment :: Plugins
12
+ Intended Audience :: Developers
13
+ Programming Language :: Python
14
+ Topic :: Software Development :: Build Tools
15
+ license = Copyright (C) 2023, Greenroom Robotics
16
+ license_files = LICENSE
17
+ description = A CLI for interacting with Lookout+
18
+ long_description = file: README.md
19
+ long_description_content_type = text/markdown
20
+ keywords = colcon
21
+
22
+ [options]
23
+ packages = find:
24
+ install_requires =
25
+ toml~=0.10
26
+ setuptools
27
+ colorama
28
+ click
29
+ lookout-config
30
+ python-on-whales
31
+ PyYAML
32
+ zip_safe = true
33
+
34
+ [options.package_data]
35
+ lookout_cli =
36
+ **/*.json
37
+ **/*.py
38
+ **/**/*.yaml
39
+ **/**/*.yml
40
+
41
+ [options.entry_points]
42
+ console_scripts =
43
+ lookout = lookout_cli.cli:cli
44
+
45
+ [egg_info]
46
+ tag_build =
47
+ tag_date = 0
48
+
@@ -0,0 +1,3 @@
1
+ from setuptools import setup
2
+
3
+ setup()