From 0d042adcc87f21c77e90769446bad053c97e3c41 Mon Sep 17 00:00:00 2001 From: Sudeep Pillai Date: Mon, 9 Oct 2023 09:56:38 -0700 Subject: [PATCH] Support `workdir`, `entrypoint` and `command` in `agibuild.yaml` (#2) --- agipack/config.py | 16 ++++++++++++-- agipack/templates/Dockerfile.j2 | 17 +++++++++++++- agipack/templates/agibuild.sample.yaml | 1 + examples/generated/Dockerfile-base-cpu | 28 ++++++++++++++---------- examples/generated/Dockerfile-base-cu118 | 28 ++++++++++++++---------- 5 files changed, 63 insertions(+), 27 deletions(-) diff --git a/agipack/config.py b/agipack/config.py index 9542d22..8015cb0 100644 --- a/agipack/config.py +++ b/agipack/config.py @@ -77,8 +77,17 @@ class ImageConfig: add: Optional[List[str]] = field(default_factory=list) """List of files to copy into the image.""" + workdir: Optional[str] = field(default=None) + """Working directory for the image (defaults to /app/${AGIPACK_ENV} if not set).""" + run: Optional[List[str]] = field(default_factory=list) - """List of commands to run in the image.""" + """List of commands to run in the image under the workdir.""" + + entrypoint: Optional[List[str]] = field(default_factory=list) + """Entrypoint for the image.""" + + command: Optional[List[str]] = field(default_factory=lambda: ["bash"]) + """Command to run in the image.""" def additional_kwargs(self): """Additional kwargs to pass to the Jinja2 Dockerfile template.""" @@ -199,9 +208,12 @@ def save_yaml(self, filename: str) -> None: # Pre-process the config to remove empty lists, etc. data = asdict(self) for _, config in data["images"].items(): - for key in ["env", "system", "pip", "requirements", "add", "run"]: + for key in ["env", "system", "pip", "requirements", "add", "run", "entrypoint", "command"]: if not len(config[key]): del config[key] + for key in ["workdir"]: + if config.get(key) is None: + del config[key] # Save the YAML file with open(filename, "w") as f: yaml.safe_dump(data, f, sort_keys=False) diff --git a/agipack/templates/Dockerfile.j2 b/agipack/templates/Dockerfile.j2 index d20300e..81b6c2a 100644 --- a/agipack/templates/Dockerfile.j2 +++ b/agipack/templates/Dockerfile.j2 @@ -125,12 +125,17 @@ RUN echo "export CONDA_PATH=/opt/conda/envs/${AGIPACK_PYENV}" >> ~/.bashrc RUN echo "export PATH=/opt/conda/envs/${AGIPACK_PYENV}/bin:$PATH" >> ~/.bashrc RUN echo "export CONDA_DEFAULT_ENV=${AGIPACK_PYENV}" >> ~/.bashrc RUN echo "mamba activate ${AGIPACK_PYENV}" > ~/.bashrc -ENTRYPOINT ["/bin/bash", "-c"] {%- endif %} + # Setup working directory +{%- if workdir %} +WORKDIR {{ workdir }} +{%- else %} WORKDIR /app/$AGIPACK_PYENV +{%- endif %} + {%- if run|length > 0 %} @@ -142,3 +147,13 @@ RUN \ && echo "run commands complete" {%- endif %} + + +{%- if entrypoint|length > 0 %} +ENTRYPOINT [{%- for cmd in entrypoint %}"{{ cmd }}"{% if not loop.last %}, {% endif %}{%- endfor %}] +{%- endif %} + + +{%- if command %} +CMD [{{ command }}] +{%- endif %} diff --git a/agipack/templates/agibuild.sample.yaml b/agipack/templates/agibuild.sample.yaml index ea139c2..c197fe2 100644 --- a/agipack/templates/agibuild.sample.yaml +++ b/agipack/templates/agibuild.sample.yaml @@ -10,3 +10,4 @@ images: - ls -la env: MY_ENV_VAR: value + command: ["bash"] diff --git a/examples/generated/Dockerfile-base-cpu b/examples/generated/Dockerfile-base-cpu index 622cf83..88529b8 100644 --- a/examples/generated/Dockerfile-base-cpu +++ b/examples/generated/Dockerfile-base-cpu @@ -3,19 +3,22 @@ FROM debian:buster-slim AS base-cpu # Setup environment variables -ENV PROJECT agi -ENV PYENV agi-py38 +ENV AGIPACK_PROJECT agi +ENV AGIPACK_PYENV agi-py38 +ENV AGIPACK_VERSION 0.1.4 +ENV AGIPACK_PATH /opt/agi-pack + ENV PYTHON_VERSION 3.8 ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONUNBUFFERED 1 ENV PYTHONWARNINGS ignore # Setup conda paths -ENV CONDA_PATH=/opt/conda/envs/${PYENV} +ENV CONDA_PATH=/opt/conda/envs/${AGIPACK_PYENV} ENV CONDA_PREFIX=${CONDA_PATH} ENV CONDA_EXE=${CONDA_PATH}/bin/conda ENV PATH=${CONDA_PATH}/bin:/opt/conda/bin:$PATH -ENV CONDA_DEFAULT_ENV ${PYENV} +ENV CONDA_DEFAULT_ENV ${AGIPACK_PYENV} # Setup environment variables ENV MY_ENV_VAR=value @@ -35,7 +38,7 @@ RUN curl -sLo ~/mambaforge.sh "https://github.com/conda-forge/miniforge/releases && ~/mambaforge.sh -b -p /opt/conda \ && /opt/conda/bin/mamba init bash \ && /opt/conda/bin/mamba config --set pip_interop_enabled True \ - && /opt/conda/bin/mamba create -n ${PYENV} python=${PYTHON_VERSION} -y \ + && /opt/conda/bin/mamba create -n ${AGIPACK_PYENV} python=${PYTHON_VERSION} -y \ && rm ~/mambaforge.sh # Install pip packages, with cache mounting /opt/conda/pkgs for faster builds @@ -49,17 +52,18 @@ RUN --mount=type=cache,target=/opt/conda/pkgs/ \ && echo "pip install complete" # Export conda environment on login -RUN echo "export CONDA_PATH=/opt/conda/envs/${PYENV}" >> ~/.bashrc -RUN echo "export PATH=/opt/conda/envs/${PYENV}/bin:$PATH" >> ~/.bashrc -RUN echo "export CONDA_DEFAULT_ENV=${PYENV}" >> ~/.bashrc -RUN echo "mamba activate ${PYENV}" > ~/.bashrc -ENTRYPOINT ["/bin/bash", "-c"] +RUN echo "export CONDA_PATH=/opt/conda/envs/${AGIPACK_PYENV}" >> ~/.bashrc +RUN echo "export PATH=/opt/conda/envs/${AGIPACK_PYENV}/bin:$PATH" >> ~/.bashrc +RUN echo "export CONDA_DEFAULT_ENV=${AGIPACK_PYENV}" >> ~/.bashrc +RUN echo "mamba activate ${AGIPACK_PYENV}" > ~/.bashrc + # Setup working directory -WORKDIR /app/$PYENV +WORKDIR /app/$AGIPACK_PYENV # Run commands RUN \ python -c 'import cv2; print(cv2.__version__)' \ python -c 'import torch; print(torch.__version__)' \ - && echo "run commands complete" \ No newline at end of file + && echo "run commands complete" +CMD [['bash']] \ No newline at end of file diff --git a/examples/generated/Dockerfile-base-cu118 b/examples/generated/Dockerfile-base-cu118 index 0825127..2f843aa 100644 --- a/examples/generated/Dockerfile-base-cu118 +++ b/examples/generated/Dockerfile-base-cu118 @@ -3,19 +3,22 @@ FROM debian:buster-slim AS base-gpu # Setup environment variables -ENV PROJECT agi -ENV PYENV agi-py38 +ENV AGIPACK_PROJECT agi +ENV AGIPACK_PYENV agi-py38 +ENV AGIPACK_VERSION 0.1.4 +ENV AGIPACK_PATH /opt/agi-pack + ENV PYTHON_VERSION 3.8 ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONUNBUFFERED 1 ENV PYTHONWARNINGS ignore # Setup conda paths -ENV CONDA_PATH=/opt/conda/envs/${PYENV} +ENV CONDA_PATH=/opt/conda/envs/${AGIPACK_PYENV} ENV CONDA_PREFIX=${CONDA_PATH} ENV CONDA_EXE=${CONDA_PATH}/bin/conda ENV PATH=${CONDA_PATH}/bin:/opt/conda/bin:$PATH -ENV CONDA_DEFAULT_ENV ${PYENV} +ENV CONDA_DEFAULT_ENV ${AGIPACK_PYENV} # Setup environment variables ENV MY_ENV_VAR=value @@ -35,7 +38,7 @@ RUN curl -sLo ~/mambaforge.sh "https://github.com/conda-forge/miniforge/releases && ~/mambaforge.sh -b -p /opt/conda \ && /opt/conda/bin/mamba init bash \ && /opt/conda/bin/mamba config --set pip_interop_enabled True \ - && /opt/conda/bin/mamba create -n ${PYENV} python=${PYTHON_VERSION} -y \ + && /opt/conda/bin/mamba create -n ${AGIPACK_PYENV} python=${PYTHON_VERSION} -y \ && rm ~/mambaforge.sh # Install pip packages, with cache mounting /opt/conda/pkgs for faster builds @@ -53,14 +56,14 @@ RUN --mount=type=cache,target=/opt/conda/pkgs/ \ && echo "pip install complete" # Export conda environment on login -RUN echo "export CONDA_PATH=/opt/conda/envs/${PYENV}" >> ~/.bashrc -RUN echo "export PATH=/opt/conda/envs/${PYENV}/bin:$PATH" >> ~/.bashrc -RUN echo "export CONDA_DEFAULT_ENV=${PYENV}" >> ~/.bashrc -RUN echo "mamba activate ${PYENV}" > ~/.bashrc -ENTRYPOINT ["/bin/bash", "-c"] +RUN echo "export CONDA_PATH=/opt/conda/envs/${AGIPACK_PYENV}" >> ~/.bashrc +RUN echo "export PATH=/opt/conda/envs/${AGIPACK_PYENV}/bin:$PATH" >> ~/.bashrc +RUN echo "export CONDA_DEFAULT_ENV=${AGIPACK_PYENV}" >> ~/.bashrc +RUN echo "mamba activate ${AGIPACK_PYENV}" > ~/.bashrc + # Setup working directory -WORKDIR /app/$PYENV +WORKDIR /app/$AGIPACK_PYENV # Run commands RUN \ @@ -68,4 +71,5 @@ RUN \ echo 'cuda: ' && python -c 'import torch; print(torch.version.cuda)' \ echo 'cudnn: ' && python -c 'import torch; print(torch.backends.cudnn.version())' \ echo 'opencv:' && python -c 'import cv2; print(cv2.__version__)' \ - && echo "run commands complete" \ No newline at end of file + && echo "run commands complete" +CMD [['bash']] \ No newline at end of file