diff --git a/.circleci/config.yml b/.circleci/config.yml index efa5aa20..4905a6dc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,7 +1,29 @@ version: 2 jobs: - build: + build-miniforge3: + docker: + - image: circleci/python:3.8.2 + steps: + - checkout + - setup_remote_docker + - run: + name: Build miniforge3 image + command: | + docker build -t condaforge/miniforge3 miniforge3/ubuntu + - run: + name: Run miniforge3 tests as root + command: | + docker build miniforge3/tests \ + --build-arg IMAGE_TO_TEST=condaforge/miniforge3 \ + -f miniforge3/tests/Dockerfile.root + - run: + name: Run miniforge3 tests as non-root + command: | + docker build miniforge3/tests \ + --build-arg IMAGE_TO_TEST=condaforge/miniforge3 \ + -f miniforge3/tests/Dockerfile.non-root + build-anvil: environment: DOCKERIMAGE: linux-anvil-comp7 working_directory: ~/test @@ -25,4 +47,5 @@ workflows: version: 2 build_and_test: jobs: - - build + - build-anvil + - build-miniforge3 diff --git a/miniforge3/tests/Dockerfile.non-root b/miniforge3/tests/Dockerfile.non-root new file mode 100644 index 00000000..7b66c1d5 --- /dev/null +++ b/miniforge3/tests/Dockerfile.non-root @@ -0,0 +1,18 @@ +ARG IMAGE_TO_TEST=miniforge3 +FROM ${IMAGE_TO_TEST} + +RUN useradd \ + --comment "Default user" \ + --create-home \ + --shell /bin/bash \ + --uid 1000 \ + conder + +USER conder + +COPY tests /tmp/tests +RUN set -e; \ + for f in /tmp/tests/*; do \ + echo "Executing $f"; \ + $f; \ + done diff --git a/miniforge3/tests/Dockerfile.root b/miniforge3/tests/Dockerfile.root new file mode 100644 index 00000000..0784506d --- /dev/null +++ b/miniforge3/tests/Dockerfile.root @@ -0,0 +1,9 @@ +ARG IMAGE_TO_TEST=miniforge3 +FROM ${IMAGE_TO_TEST} + +COPY tests /tmp/tests +RUN set -e; \ + for f in /tmp/tests/*; do \ + echo "Executing $f"; \ + $f; \ + done diff --git a/miniforge3/tests/tests/clean-homedir.py b/miniforge3/tests/tests/clean-homedir.py new file mode 100755 index 00000000..2a616f56 --- /dev/null +++ b/miniforge3/tests/tests/clean-homedir.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python3 +import os + +# .bash_logout could optionally be in $HOME, otherwise only .bashrc and .profile +home_contents = sorted(os.listdir(os.environ['HOME'])) +if len(home_contents) == 3: + assert home_contents == ['.bash_logout', '.bashrc', '.profile'], home_contents +else: + assert home_contents == ['.bashrc', '.profile'], home_contents diff --git a/miniforge3/tests/tests/ps1.py b/miniforge3/tests/tests/ps1.py new file mode 100755 index 00000000..e96ecc26 --- /dev/null +++ b/miniforge3/tests/tests/ps1.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python3 +import subprocess +import os + +# Interactive mode in bash should have (base) in PS1 +# -i requires stdin to be a tty, but we don't care. stderr is silenced to keep output clean. +assert subprocess.check_output([ + '/bin/bash', '-i', '-c', + 'echo $PS1' +], stderr=subprocess.DEVNULL).decode().startswith("(base)") diff --git a/miniforge3/ubuntu/Dockerfile b/miniforge3/ubuntu/Dockerfile new file mode 100644 index 00000000..62fc0b6d --- /dev/null +++ b/miniforge3/ubuntu/Dockerfile @@ -0,0 +1,44 @@ +FROM ubuntu:bionic + +ARG MINIFORGE_VERSION=4.8.2-1 +ARG TINI_VERSION=v0.18.0 + +ENV CONDA_DIR=/opt/conda +ENV LANG=C.UTF-8 LC_ALL=C.UTF-8 +ENV PATH=${CONDA_DIR}/bin:${PATH} + +# Install just enough for conda to work +RUN apt-get update > /dev/null && \ + apt-get install --no-install-recommends --yes \ + wget bzip2 ca-certificates \ + git > /dev/null && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Keep $HOME clean (no .wget-hsts file), since HSTS isn't useful in this context +RUN wget --no-hsts --quiet https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini -O /usr/local/bin/tini && \ + chmod +x /usr/local/bin/tini + +# 1. Install miniforge from GitHub releases +# 2. Apply some cleanup tips from https://jcrist.github.io/conda-docker-tips.html +# Particularly, we remove pyc and a files. The default install has no js, we can skip that +RUN wget --no-hsts --quiet https://github.com/conda-forge/miniforge/releases/download/${MINIFORGE_VERSION}/Miniforge3-${MINIFORGE_VERSION}-Linux-x86_64.sh -O /tmp/miniforge.sh && \ + /bin/bash /tmp/miniforge.sh -b -p ${CONDA_DIR} && \ + rm /tmp/miniforge.sh && \ + conda clean -tipsy && \ + find ${CONDA_DIR} -follow -type f -name '*.a' -delete && \ + find ${CONDA_DIR} -follow -type f -name '*.pyc' -delete && \ + conda clean -afy + +# Activate base by default when running as any *non-root* user as well +# Good security practice requires running most workloads as non-root +# This makes sure any non-root users created also have base activated +# for their interactive shells. +RUN echo ". ${CONDA_DIR}/etc/profile.d/conda.sh && conda activate base" >> /etc/skel/.bashrc + +# Activate base by default when running as root as well +# The root user is already created, so won't pick up changes to /etc/skel +RUN echo ". ${CONDA_DIR}/etc/profile.d/conda.sh && conda activate base" >> ~/.bashrc + +ENTRYPOINT ["tini", "--"] +CMD [ "/bin/bash" ]