Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions riocli/compose/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,24 @@
ROS_MASTER_IMAGE = "quay.io/rapyuta/ros-base-melodic:master"
ROS_MASTER_PORT = 1234
ROS_MASTER_CONTAINER_NAME = "roscore"
DEFAULT_VOLUME_MOUNTS = [
"/opt/rapyuta/configs:/opt/rapyuta/configs:rslave",
"/var/log/riouser:/var/log/riouser:rslave",
"/var/log/rapyuta/deployments:/var/log/rapyuta/deployments:rslave",
"/var/lib/docker/containers:/var/lib/docker/containers:rslave",
"/dev:/dev:rslave",
]
CONFIGS_DIR = "/opt/rapyuta/configs"


def get_default_volume_mounts(configs_path: str | None = None) -> list[str]:
"""
Returns the default volume mounts for a Docker Compose service.

Args:
configs_path: Host-side path to bind-mount at CONFIGS_DIR instead of
CONFIGS_DIR itself (i.e. an override for the `/opt/rapyuta/configs` host path).
"""
return [
f"{configs_path or CONFIGS_DIR}:{CONFIGS_DIR}:rslave",
"/var/log/riouser:/var/log/riouser:rslave",
"/var/log/rapyuta/deployments:/var/log/rapyuta/deployments:rslave",
"/var/lib/docker/containers:/var/lib/docker/containers:rslave",
"/dev:/dev:rslave",
]


def generate_roscore_service() -> Service:
Expand Down
30 changes: 29 additions & 1 deletion riocli/compose/down.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,28 @@
default=False,
help="Treat the argument as a chart name and resolve inputs from it.",
)
@click.option(
"--configs-path",
"configs_path",
default=None,
help="Host path to bind-mount in place of /opt/rapyuta/configs in the generated compose "
"file. Only takes effect when the compose file has to be (re)generated because it's "
"missing or empty -- pass the same value used with `rio compose up`/`generate` so a "
"regenerated file doesn't fall back to the device paths.",
type=click.Path(
exists=True, dir_okay=True, file_okay=False, path_type=Path, resolve_path=True
),
)
@click.option(
"--ignore-volume-source",
"ignore_volume_source",
multiple=True,
default=(),
help="gitignore-style pattern matched against a volume's full host-side path -- drops "
"the bind entirely instead of mounting it. Only takes effect when the compose file has "
"to be (re)generated; see --configs-path. Repeatable; evaluated in order, last match "
"wins; prefix with '!' to re-include a path an earlier pattern excluded.",
)
@click.argument("files", nargs=-1)
@click.pass_context
def down(
Expand All @@ -67,12 +89,16 @@ def down(
path: str,
use_chart: bool,
files: tuple[str, ...],
configs_path: Path | None = None,
ignore_volume_source: tuple[str, ...] = (),
):
"""
Stop and remove services defined in the Docker Compose file.

If the compose file does not exist, it will be generated using the provided manifest(s),
values, and secret files before bringing the services down.
values, and secret files before bringing the services down. Pass --configs-path and/or
--ignore-volume-source in that case if you used them with `up`/`generate`, so the
regenerated file doesn't fall back to the un-overridden device paths.

Examples:

Expand Down Expand Up @@ -113,6 +139,8 @@ def down(
values=values,
secrets=secrets,
files=files,
configs_path=configs_path.as_posix() if configs_path else None,
ignore_volume_source=ignore_volume_source,
)
write_compose_yaml(output_path=compose_path, compose_dict=compose_doc)

Expand Down
54 changes: 53 additions & 1 deletion riocli/compose/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,31 @@
default=False,
help="Merge new services into existing compose file instead of overwriting.",
)
@click.option(
"--configs-path",
"configs_path",
default=None,
help="Host path to bind-mount in place of /opt/rapyuta/configs in the generated compose "
"file. Volumes redirected here are skipped by the init-fixperms permission fixup, since "
"they now point at your own local files rather than the device.",
type=click.Path(
exists=True, dir_okay=True, file_okay=False, path_type=Path, resolve_path=True
),
)
@click.option(
"--ignore-volume-source",
"ignore_volume_source",
multiple=True,
default=(),
help="gitignore-style pattern matched against a volume's full host-side path, as declared "
"in the manifest's subPath (before any --configs-path rewrite) -- drops the bind entirely "
"instead of mounting it. Applies to deployment-declared volumes and to the default mounts "
"other than the /opt/rapyuta/configs bind, which --configs-path controls instead. "
"Repeatable; evaluated in order, last match wins; prefix with '!' to re-include a path an "
"earlier pattern excluded (e.g. --ignore-volume-source '/opt/rapyuta/configs/station/*' "
"--ignore-volume-source '!/opt/rapyuta/configs/station/sim-nginx.conf.template'). "
"Independent of --configs-path -- applies whether or not that flag is also given.",
)
@click.argument("files", nargs=-1)
@click.pass_context
def generate(
Expand All @@ -93,6 +118,8 @@ def generate(
append_services: bool,
files: tuple[str, ...],
branch: str = None,
configs_path: Path | None = None,
ignore_volume_source: tuple[str, ...] = (),
) -> None:
"""
Convert Rapyuta.io manifests into a Docker Compose YAML file.
Expand Down Expand Up @@ -122,6 +149,23 @@ def generate(

rio compose generate templates/
rio compose generate --chart --append ioconfig-syncer

Bind-mount a local directory in place of /opt/rapyuta/configs:

rio compose generate templates/ --configs-path ./local-configs

Bind-mount a local directory but drop binds under a sub-path entirely
(e.g. no local equivalent exists for it):

rio compose generate templates/ --configs-path ./local-configs \\
--ignore-volume-source '/opt/rapyuta/configs/auth/*' \\
--ignore-volume-source '/opt/rapyuta/configs/station/*' \\
--ignore-volume-source '!/opt/rapyuta/configs/station/sim-nginx.conf.template'

Drop a bind entirely without redirecting anything else (independent of
--configs-path):

rio compose generate templates/ --ignore-volume-source '/opt/rapyuta/configs/auth/*'
"""

if not path:
Expand Down Expand Up @@ -150,6 +194,8 @@ def generate(
values=values,
secrets=secrets,
files=files,
configs_path=configs_path.as_posix() if configs_path else None,
ignore_volume_source=ignore_volume_source,
)
if append_services and existing_services:
compose_doc["services"] = merge_compose_services(
Expand All @@ -166,6 +212,8 @@ def generate_compose_file(
values: tuple[str, ...],
secrets: tuple[str, ...],
files: tuple[str, ...],
configs_path: str | None = None,
ignore_volume_source: tuple[str, ...] = (),
) -> dict:
glob_files, abs_values, abs_secrets = process_files_values_secrets(
files, values, secrets
Expand All @@ -183,7 +231,11 @@ def generate_compose_file(

print_centered_text("Converting Manifests")
docker_compose_manifest = populate(
ctx=ctx, deployments=deployments, packages=packages
ctx=ctx,
deployments=deployments,
packages=packages,
configs_path=configs_path,
ignore_volume_source=ignore_volume_source,
)

return clean_dict(asdict(docker_compose_manifest))
Expand Down
Loading
Loading