From a4aa01987b5cad61be8dd0cfed908db3f09e29fc Mon Sep 17 00:00:00 2001 From: "iamcristye@outlook.com" Date: Tue, 21 Jun 2022 08:37:24 +0800 Subject: [PATCH] improvement: compatibility with Docker Compose subcommand closes #641 --- CHANGELOG.md | 1 + docs/local.rst | 3 +++ tutor/utils.py | 24 +++++++++++++++++++----- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 447b03f..659f5e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ Every user-facing change should have an entry in this changelog. Please respect - [Bugfix] Fix smtp server port in `cms.yml` which was causing email sending failures in the Studio. (by @regisb) - [Improvement] Use `git am` instead of `cherry-pick` to simplify patching process. +- [Improvement] Tutor is now compatible with Docker Compose subcommand. ## v14.0.1 (2022-06-13) diff --git a/docs/local.rst b/docs/local.rst index c6a6a67..7ca2f0a 100644 --- a/docs/local.rst +++ b/docs/local.rst @@ -5,6 +5,9 @@ Local deployment This method is for deploying Open edX locally on a single server, where docker images are orchestrated with `docker-compose `_. +.. note:: + Tutor is compatible with the ``docker compose`` subcommand. However, this support is still in beta and we're not sure it will behave the same as the previous ``docker-compose`` command. So ``docker-compose`` will be preferred, unless you set an environment variable ``TUTOR_USE_COMPOSE_SUBCOMMAND`` to enforce using ``docker compose``. + .. _tutor_root: In the following, environment and data files will be generated in a user-specific project folder which will be referred to as the "**project root**". On Linux, the default project root is ``~/.local/share/tutor``. An alternative project root can be defined by passing the ``--root=...`` option to the ``tutor`` command, or defining the ``TUTOR_ROOT=...`` environment variable:: diff --git a/tutor/utils.py b/tutor/utils.py index 6175e6a..ac691ff 100644 --- a/tutor/utils.py +++ b/tutor/utils.py @@ -1,4 +1,5 @@ import base64 +from functools import lru_cache import json import os import random @@ -162,12 +163,25 @@ def docker(*command: str) -> int: return execute("docker", *command) +@lru_cache +def _docker_compose_command() -> Tuple[str, ...]: + """ + A helper function to determine which program to call when running docker compose + """ + if os.environ.get("TUTOR_USE_COMPOSE_SUBCOMMAND") is not None: + return ("docker", "compose") + if shutil.which("docker-compose") is not None: + return ("docker-compose",) + if shutil.which("docker") is not None: + if subprocess.run(["docker", "compose"], capture_output=True).returncode == 0: + return ("docker", "compose") + raise exceptions.TutorError( + "docker-compose is not installed. Please follow instructions from https://docs.docker.com/compose/install/" + ) + + def docker_compose(*command: str) -> int: - if shutil.which("docker-compose") is None: - raise exceptions.TutorError( - "docker-compose is not installed. Please follow instructions from https://docs.docker.com/compose/install/" - ) - return execute("docker-compose", *command) + return execute(*_docker_compose_command(), *command) def kubectl(*command: str) -> int: