diff --git a/README.md b/README.md index aba3f16..0d5f2ae 100755 --- a/README.md +++ b/README.md @@ -130,12 +130,13 @@ https://github.com/containers/podman/blob/main/troubleshooting.md#symptom-23 | `STOREBASE` | where job data is stored, valid when `STORAGE_TYPE=host`, conflicts with `VOLUME_NAME` | | `VOLUME_NAME` | name of data volume, valid when `STORAGE_TYPE=docker_local_volume` or `STORAGE_TYPE=kubernetes_pvc` | | `PFCON_SELECTOR` | label on the pfcon container, may be specified for pman to self-discover `VOLUME_NAME` (default: `org.chrisproject.role=pfcon`) | -| `CONTAINER_USER` | Set job container user in the form `UID:GID`, may be a range for random values | +| `CONTAINER_USER` | Set job container user in the form `UID:GID`, may be a range for random values | | `ENABLE_HOME_WORKAROUND` | If set to "yes" then set job environment variable `HOME=/tmp` | | `SHM_SIZE` | Size of `/dev/shm` in mebibytes. (Supported only in Docker, Podman, and Kubernetes.) | | `JOB_LABELS` | CSV list of key=value pairs, labels to apply to container jobs | | `JOB_LOGS_TAIL` | (int) maximum size of job logs | | `IGNORE_LIMITS` | If set to "yes" then do not set resource limits on container jobs (for making things work without effort) | +| `DOCKER_NETWORKS` | Comma-separated list of Docker networks to connect containers to (e.g., "network1,network2") | | `REMOVE_JOBS` | If set to "no" then pman will not delete jobs (for debugging) | [flask docs]: https://flask.palletsprojects.com/en/2.1.x/config/#SECRET_KEY @@ -162,6 +163,14 @@ PersistentVolumeClaim configured as ReadWriteMany. In cases where the volume is only writable to a specific UNIX user, such as a NFS-backed volume, `CONTAINER_USER` can be used as a workaround. +### Docker-Specific Options + +Applicable when `CONTAINER_ENV=docker` + +| Environment Variable | Description | +|---------------------------|-------------------------------------------------| +| `DOCKER_NETWORKS` | Comma-separated list of Docker networks to connect containers to (e.g., "network1,network2") | + ### Kubernetes-Specific Options Applicable when `CONTAINER_ENV=kubernetes` diff --git a/pman/config.py b/pman/config.py index 20d1f9b..408ae18 100755 --- a/pman/config.py +++ b/pman/config.py @@ -1,12 +1,11 @@ +from importlib.metadata import Distribution from logging.config import dictConfig from environs import Env -from importlib.metadata import Distribution - -from pman.memsize import Memsize from pman._helpers import get_storebase_from_docker +from pman.memsize import Memsize pkg = Distribution.from_name(__package__) @@ -32,6 +31,9 @@ def __init__(self): shm_size = env.int('SHM_SIZE', None) self.SHM_SIZE = None if shm_size is None else Memsize(shm_size) + # Docker networks configuration + self.DOCKER_NETWORKS = env('DOCKER_NETWORKS', None) + self.CONTAINER_ENV = env('CONTAINER_ENV', 'docker') if self.CONTAINER_ENV == 'podman': # podman is just an alias for docker self.CONTAINER_ENV = 'docker' diff --git a/pman/dockermgr.py b/pman/dockermgr.py index a6ff4db..b8b2245 100755 --- a/pman/dockermgr.py +++ b/pman/dockermgr.py @@ -1,13 +1,14 @@ import shlex -from typing import List, Optional, AnyStr +from typing import AnyStr, List, Optional +import docker from docker import DockerClient -from docker.types import DeviceRequest from docker.models.containers import Container +from docker.types import DeviceRequest -from pman.abstractmgr import (AbstractManager, Image, JobName, ResourcesDict, - MountsDict, JobInfo, TimeStamp, ManagerException, JobStatus) -import docker +from pman.abstractmgr import (AbstractManager, Image, JobInfo, JobName, + JobStatus, ManagerException, MountsDict, + ResourcesDict, TimeStamp) class DockerManager(AbstractManager[Container]): @@ -67,7 +68,12 @@ def schedule_job(self, image: Image, command: List[str], name: JobName, if (s := self.config.get('SHM_SIZE')) is not None: shm_size['shm_size'] = s.as_mb() - return self.__docker.containers.run( + # Docker networks configuration + networks = {} + if docker_network := self.config.get('DOCKER_NETWORKS'): + networks['network'] = docker_network + + container = self.__docker.containers.run( image=image, command=command, name=name, @@ -78,9 +84,12 @@ def schedule_job(self, image: Image, command: List[str], name: JobName, **limits, **user_spec, **shm_size, - **volumes + **volumes, + **networks ) + return container + def get_job(self, name: JobName) -> Container: try: return self.__docker.containers.get(name)