Skip to content

Commit

Permalink
Run each taskrunner in a separate docker container
Browse files Browse the repository at this point in the history
- Add WebUI for managing containers
- Merge server.py and frontend.py
- Fix tests
  • Loading branch information
oysols committed Aug 27, 2020
1 parent a73dd6e commit 296cd7f
Show file tree
Hide file tree
Showing 13 changed files with 651 additions and 393 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ RUN apt-get update && apt-get install -y docker.io
COPY server/requirements.txt .
RUN pip3 install -r requirements.txt

WORKDIR /workdir
WORKDIR /temp
COPY . ./
RUN pip3 install .

Expand Down
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ build:
test:
python3 tests/test_executors.py
python3 tests/test_taskrunner.py
python3 tests/test_failed_import.py
python3 tests/test_statesnapshot.py

tasks:
python3 tasks.py
python3 -m minimalci.taskrunner

check:
mypy minimalci --strict
Expand Down
6 changes: 2 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ services:
minimalci:
build: .
volumes:
- /srv/minimalci/repo:/server/repo
- /srv/minimalci/logs:/server/logs
- /srv/minimalci/secrets:/server/secrets
- /srv/minimalci/ssh:/root/.ssh
- /srv/minimalci:/server/data
- /srv/minimalci/ssh:/root/.ssh:ro
- /var/run/docker.sock:/var/run/docker.sock
ports:
- 80:8000
Expand Down
46 changes: 41 additions & 5 deletions server/config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from pathlib import Path
import json
import os
import subprocess
from typing import Optional

import oauth

Expand Down Expand Up @@ -39,9 +41,43 @@


# Advanced
REPO_PATH = Path("./repo")
LOGS_PATH = Path("./logs")
SECRETS_PATH = Path("./secrets")
WORK_PATH = Path("./workspaces")
DATA_PATH = Path("data")
REPO_PATH = DATA_PATH / "repo"
LOGS_PATH = DATA_PATH / "logs"
SECRETS_PATH = DATA_PATH / "secrets"
WORK_PATH = DATA_PATH / "workspaces"
LOGFILE = "output.log"
STATEFILE = "taskstate.json"
STATEFILE = "state.json"


# Introspection when running in docker
def get_self_container_id() -> Optional[str]:
cpuset = Path("/proc/1/cpuset").read_text().strip()
if cpuset.startswith("/docker/"):
_, _, container_id = cpuset.split("/")
return container_id
else:
return None


def get_image_name_from_container_id(container_id: str) -> str:
data = json.loads(subprocess.check_output(["docker", "inspect", container_id]).decode())
assert len(data) == 1
_, image_name = data[0]["Image"].split(":")
return str(image_name)


def get_external_mount_point(container_id: str, internal_path: str) -> Path:
data = json.loads(subprocess.check_output(["docker", "inspect", container_id]).decode())
assert len(data) == 1
mounts = data[0]["Mounts"]
for mount in mounts:
if mount.get("Destination") == internal_path:
return Path(mount["Source"])
raise Exception(f"External mount point not found for {internal_path}")


SELF_CONTAINER_ID = get_self_container_id()
TASKRUNNER_IMAGE = get_image_name_from_container_id(SELF_CONTAINER_ID) if SELF_CONTAINER_ID else "minimalci:latest"
EXTERNAL_DATA_MOUNT_POINT = get_external_mount_point(SELF_CONTAINER_ID, str(DATA_PATH.absolute())) if SELF_CONTAINER_ID else DATA_PATH.absolute()
EXTERNAL_SSH_MOUNT_POINT = get_external_mount_point(SELF_CONTAINER_ID, str(Path("~/.ssh").expanduser())) if SELF_CONTAINER_ID else Path("~/.ssh").expanduser()
262 changes: 0 additions & 262 deletions server/frontend.py

This file was deleted.

Loading

0 comments on commit 296cd7f

Please sign in to comment.