Skip to content

Commit

Permalink
feat: tutor dev/local populate-mounts
Browse files Browse the repository at this point in the history
  • Loading branch information
kdmccormick committed Aug 31, 2023
1 parent b544f5b commit 8277e31
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 0 deletions.
76 changes: 76 additions & 0 deletions tutor/commands/compose.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from tutor.exceptions import TutorError
from tutor.tasks import BaseComposeTaskRunner
from tutor.types import Config
from tutor.utils import execute as execute_shell


class ComposeTaskRunner(BaseComposeTaskRunner):
Expand Down Expand Up @@ -365,6 +366,59 @@ def copyfrom(
)


@click.command(
help="TODO describe"
)
@click.argument(
"mount_paths",
metavar="mount_path",
nargs=-1,
type=click.Path(dir_okay=True, file_okay=False, resolve_path=True),
)
@click.pass_obj
def populate_mounts(context: BaseComposeContext, mount_paths: list[Path]) -> None:
"""
TODO write docstring
"""
config = tutor_config.load(context.root)
host_mount_paths: list[str] = [
os.path.abspath(os.path.expanduser(mount_path))
for mount_path
in mount_paths or bindmount.get_mounts(config)
]
copies_by_service: list[tuple[str, str]] = {}
for host_mount_path in host_mount_paths:
mount_name = os.path.basename(host_mount_path)
for service, container_mount_path in hooks.Filters.COMPOSE_MOUNTS.iterate(mount_name):
for path_in_mount in hooks.Filters.COMPOSE_MOUNT_POPULATORS.iterate(mount_name, service):
source = f"{container_mount_path}/{path_in_mount}"
target = f"{host_mount_path}/{path_in_mount}"
copies_by_service.setdefault(service, []).append((source, target))
container_name = "tutor_mounts_populate_temp" # TODO: improve name?
runner = context.job_runner(config)
for service, copies in copies_by_service.items():
execute_shell("docker", "rm", "-f", container_name)
runner.docker_compose(
"run",
"--detach",
"--rm",
"--no-deps",
"--user=0",
# TODO: Explain this next bit
*(f"--volume={source}" for source, target in copies),
"--name",
container_name,
service,
"sleep",
"infinity",
)
for source, target in copies:
execute_shell("rm", "-rf", target)
execute_shell("sh", "-c", f'mkdir -p "$(dirname "{target}")"')
execute_shell("docker", "cp", f"{container_name}:{source}", target)
execute_shell("sh", "-c", f"docker kill '{container_name}' || true")


@click.command(
short_help="Run a command in a running container",
help=(
Expand Down Expand Up @@ -447,6 +501,27 @@ def _mount_edx_platform(
return volumes


@hooks.Filters.COMPOSE_MOUNT_POPULATORS.add()
def _populate_edx_platform(
paths_to_copy: list[str], mount_name: str, service: str
) -> list[tuple[str, str]]:
"""
TODO describe
"""
if mount_name == "edx-platform" and service == "lms":
paths_to_copy += [
"Open_edX.egg-info",
"node_modules",
"lms/static/css",
"lms/static/certificates/css",
"cms/static/css",
"common/static/bundles",
"common/static/common/js/vendor",
"common/static/common/css/vendor",
]
return paths_to_copy


@hooks.Filters.APP_PUBLIC_HOSTS.add()
def _edx_platform_public_hosts(
hosts: list[str], context_name: t.Literal["local", "dev"]
Expand All @@ -471,6 +546,7 @@ def add_commands(command_group: click.Group) -> None:
command_group.add_command(dc_command)
command_group.add_command(run)
command_group.add_command(copyfrom)
command_group.add_command(populate_mounts)
command_group.add_command(execute)
command_group.add_command(logs)
command_group.add_command(status)
Expand Down
5 changes: 5 additions & 0 deletions tutor/hooks/catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,11 @@ def your_filter_callback(some_data):
#: conditionally add mounts.
COMPOSE_MOUNTS: Filter[list[tuple[str, str]], [str]] = Filter()

#: TODO describe
#:
#: :parameter populators: each item ``(service, mount_name, path_in_mount)`` tuple.
COMPOSE_MOUNT_POPULATORS: Filter[list[tuple[str, str, str]]] = Filter()

#: Declare new default configuration settings that don't necessarily have to be saved in the user
#: ``config.yml`` file. Default settings may be overridden with ``tutor config save --set=...``, in which
#: case they will automatically be added to ``config.yml``.
Expand Down

0 comments on commit 8277e31

Please sign in to comment.