Skip to content

Commit

Permalink
Suggestion: restore environment variable if found, and new exec_crate…
Browse files Browse the repository at this point in the history
…_command.sh (in contrast to run_crate_command.sh)
  • Loading branch information
RudolfCardinal committed Apr 16, 2024
1 parent dcf62c7 commit 1f8920e
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 22 deletions.
9 changes: 7 additions & 2 deletions installer/enter_crate_container.sh
Expand Up @@ -26,11 +26,16 @@

# Run a bash shell in the CRATE container

set -euxo pipefail
set -euo pipefail

# Activate Python virtual environment
CRATE_INSTALLER_VENV=${HOME}/.virtualenvs/crate-installer
source "${CRATE_INSTALLER_VENV}/bin/activate"

INSTALLER_HOME="$( cd "$( dirname "$0" )" && pwd )"
# Restore user's environment variables, if found
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
source "${SCRIPT_DIR}/restore_crate_envvars.sh"

# Run Python installer script with a command
INSTALLER_HOME="$( cd "$( dirname "$0" )" && pwd )"
python "${INSTALLER_HOME}/installer.py" shell "$@"
41 changes: 41 additions & 0 deletions installer/exec_crate_command.sh
@@ -0,0 +1,41 @@
#!/bin/bash

# installer/exec_crate_command.sh

# ==============================================================================
#
# Copyright (C) 2015, University of Cambridge, Department of Psychiatry.
# Created by Rudolf Cardinal (rnc1001@cam.ac.uk).
#
# This file is part of CRATE.
#
# CRATE is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# CRATE is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with CRATE. If not, see <https://www.gnu.org/licenses/>.
#
# ==============================================================================

# Runs a command in the CRATE container

set -euo pipefail

# Activate Python virtual environment
CRATE_INSTALLER_VENV=${HOME}/.virtualenvs/crate-installer
source "${CRATE_INSTALLER_VENV}/bin/activate"

# Restore user's environment variables, if found
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
source "${SCRIPT_DIR}/restore_crate_envvars.sh"

# Run Python installer script with a command
INSTALLER_HOME="$( cd "$( dirname "$0" )" && pwd )"
python "${INSTALLER_HOME}/installer.py" exec "$*"
37 changes: 24 additions & 13 deletions installer/installer.py
Expand Up @@ -254,6 +254,8 @@ class InstallerEnvVar(EnvVar):
# =============================================================================
# Ports
# =============================================================================


class Ports:
# In numeric order
MYSQL = "3306"
Expand All @@ -268,6 +270,8 @@ class Ports:
# =============================================================================
# Database Engines
# =============================================================================


class DatabaseEngine(
collections.namedtuple(
"DatabaseEngine", ["description", "sqlalchemy", "django"]
Expand Down Expand Up @@ -326,6 +330,8 @@ def validate(self, document: Document) -> None:
# =============================================================================
# Colours
# =============================================================================


class Colours:
# https://en.wikipedia.org/wiki/Solarized
# Background tones (dark theme)
Expand Down Expand Up @@ -538,7 +544,10 @@ def run_crate_command(
) -> Union[str, Container, Iterable[Tuple[str, bytes]]]:
# Run a command in a new instance of the crate_workers container.
# This goes through docker-entrypoint.sh so no need to source the
# virtualenv or call /bin/bash
# virtualenv or call /bin/bash.
# "Run" here means "without a terminal".
if not crate_command:
sys.exit("Error: no command specified")
os.chdir(HostPath.DOCKERFILES_DIR)
return self.docker.compose.run(
DockerComposeServices.CRATE_WORKERS,
Expand All @@ -550,9 +559,10 @@ def run_crate_command(
def exec_crate_command(
self, crate_command: str, as_root: bool = False
) -> None:
# Run a command in the existing instance of the crate_server
# container. This does not go through entrypoint.sh so we have to
# Execute a command in the existing instance of the crate_server
# container. This does not go through entrypoint.sh, so we have to
# source the virtualenv and call /bin/bash
# "Execute" here means "with a terminal".
venv_command = f'""source /crate/venv/bin/activate; {crate_command}""'

user = "root" if as_root else None
Expand Down Expand Up @@ -1789,16 +1799,14 @@ def get_installer_class() -> Type[Installer]:
return MacOsInstaller

if sys_info.system == "Windows":
print(
sys.exit(
"The installer cannot be run under native Windows. Please "
"install Windows Subsystem for Linux 2 (WSL2) and run the "
"installer from there. Alternatively follow the instructions "
"to install CRATE manually."
)
sys.exit(EXIT_FAILURE)

print(f"Sorry, the installer can't be run under {sys_info.system}.")
sys.exit(EXIT_FAILURE)
sys.exit(f"Sorry, the installer can't be run under {sys_info.system}.")


# =============================================================================
Expand Down Expand Up @@ -1832,28 +1840,31 @@ def main() -> None:
subparsers.required = True

subparsers.add_parser(
Command.INSTALL, help="Install CRATE into a Docker Compose environment"
Command.INSTALL,
help="Install CRATE into a Docker Compose environment.",
)

subparsers.add_parser(
Command.START, help="Start the Docker Compose application"
Command.START, help="Start the Docker Compose application."
)

subparsers.add_parser(
Command.STOP, help="Stop the Docker Compose application"
Command.STOP, help="Stop the Docker Compose application."
)

run_crate_command = subparsers.add_parser(
Command.RUN_COMMAND,
help=f"Run a command within the CRATE Docker environment, in the "
f"{DockerComposeServices.CRATE_WORKERS!r} service/container",
f"{DockerComposeServices.CRATE_WORKERS!r} service/container (without "
f"a terminal, so output will not be visible).",
)
run_crate_command.add_argument("crate_command", type=str)

exec_crate_command = subparsers.add_parser(
Command.EXEC_COMMAND,
help=f"Execute a command within the CRATE Docker environment, in the "
f"existing {DockerComposeServices.CRATE_SERVER!r} service/container",
f"existing {DockerComposeServices.CRATE_SERVER!r} service/container "
f"(with a terminal, so output is visible).",
)
exec_crate_command.add_argument("crate_command", type=str)
exec_crate_command.add_argument(
Expand All @@ -1867,7 +1878,7 @@ def main() -> None:
Command.SHELL,
help=f"Start a shell (command prompt) within a already-running CRATE "
f"Docker environment, in the "
f"{DockerComposeServices.CRATE_SERVER!r} container",
f"{DockerComposeServices.CRATE_SERVER!r} container.",
)
shell.add_argument(
"--as_root",
Expand Down
43 changes: 43 additions & 0 deletions installer/restore_crate_envvars.sh
@@ -0,0 +1,43 @@
# installer/restore_crate_envvars.sh

# ==============================================================================
#
# Copyright (C) 2015, University of Cambridge, Department of Psychiatry.
# Created by Rudolf Cardinal (rnc1001@cam.ac.uk).
#
# This file is part of CRATE.
#
# CRATE is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# CRATE is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with CRATE. If not, see <https://www.gnu.org/licenses/>.
#
# ==============================================================================

# When the installer first runs, it stores a copy of the relevant environment
# variables. To run other Docker commands, it's helpful to "source" them back,
# if found. Likewise, this file itself should be "sourced", not executed.

# The default is $HOME/crate/set_crate_docker_host_envvars (per HostPath in
# installer.py). We allow the user to pre-override this with environment
# variables.
CRATE_DIR=${CRATE_DIR:=$HOME/crate}
CRATE_CONFIG_DIR=${CRATE_CONFIG_DIR:=$CRATE_DIR/config}
CRATE_ENVVAR_FILE=${CRATE_CONFIG_DIR}/set_crate_docker_host_envvars
# ... filename itself not configurable, and written by installer.py

if [ -f "${CRATE_ENVVAR_FILE}" ]; then
echo "- Restoring user-supplied environment variables from: ${CRATE_ENVVAR_FILE}"
# shellcheck disable=SC1090
source "${CRATE_ENVVAR_FILE}"
else
echo "- No previous environment variable file found at: ${CRATE_ENVVAR_FILE}"
fi
11 changes: 8 additions & 3 deletions installer/run_crate_command.sh
Expand Up @@ -26,11 +26,16 @@

# Runs a command in the CRATE container

set -euxo pipefail
set -euo pipefail

# Activate Python virtual environment
CRATE_INSTALLER_VENV=${HOME}/.virtualenvs/crate-installer
source "${CRATE_INSTALLER_VENV}/bin/activate"

INSTALLER_HOME="$( cd "$( dirname "$0" )" && pwd )"
# Restore user's environment variables, if found
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
source "${SCRIPT_DIR}/restore_crate_envvars.sh"

python "${INSTALLER_HOME}/installer.py" run_crate_command "$*"
# Run Python installer script with a command
INSTALLER_HOME="$( cd "$( dirname "$0" )" && pwd )"
python "${INSTALLER_HOME}/installer.py" run "$*"
9 changes: 7 additions & 2 deletions installer/start_crate.sh
Expand Up @@ -26,11 +26,16 @@

# Starts CRATE

set -euxo pipefail
set -euo pipefail

# Activate Python virtual environment
CRATE_INSTALLER_VENV=${HOME}/.virtualenvs/crate-installer
source "${CRATE_INSTALLER_VENV}/bin/activate"

INSTALLER_HOME="$( cd "$( dirname "$0" )" && pwd )"
# Restore user's environment variables, if found
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
source "${SCRIPT_DIR}/restore_crate_envvars.sh"

# Run Python installer script with a command
INSTALLER_HOME="$( cd "$( dirname "$0" )" && pwd )"
python "${INSTALLER_HOME}/installer.py" start
9 changes: 7 additions & 2 deletions installer/stop_crate.sh
Expand Up @@ -26,11 +26,16 @@

# Stops CRATE

set -euxo pipefail
set -euo pipefail

# Activate Python virtual environment
CRATE_INSTALLER_VENV=${HOME}/.virtualenvs/crate-installer
source "${CRATE_INSTALLER_VENV}/bin/activate"

INSTALLER_HOME="$( cd "$( dirname "$0" )" && pwd )"
# Restore user's environment variables, if found
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
source "${SCRIPT_DIR}/restore_crate_envvars.sh"

# Run Python installer script with a command
INSTALLER_HOME="$( cd "$( dirname "$0" )" && pwd )"
python "${INSTALLER_HOME}/installer.py" stop

0 comments on commit 1f8920e

Please sign in to comment.