diff --git a/.devcontainer/apt-devel.txt b/.devcontainer/apt-devel.txt new file mode 100644 index 0000000..786114f --- /dev/null +++ b/.devcontainer/apt-devel.txt @@ -0,0 +1,19 @@ +build-essential +sudo +git +apt-transport-https +vim +htop +sysstat +lsof +nmap +ca-certificates +curl +gnupg +lsb-release +software-properties-common +apt-file +util-linux +iproute2 +iputils-ping +procps \ No newline at end of file diff --git a/.devcontainer/config.toml b/.devcontainer/config.toml new file mode 100644 index 0000000..4df98cf --- /dev/null +++ b/.devcontainer/config.toml @@ -0,0 +1,17 @@ +[sqlalchemy] +database_url = "sqlite:///./quetz.sqlite" + +[session] +# openssl rand -hex 32 +secret = "d859fc0c3554e47bdd6a8c1c27971f397dda673dbf263d30c349fb870ef7cd43" +https_only = false + +[logging] +level = "DEBUG" +file = "quetz.log" + +[users] +admins = ["dummy:alice"] + +[profiling] +enable_sampling = false \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..7406954 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,52 @@ +{ + "name": "quetz/frontend", + "containerEnv": { + "TZ": "Europe/Paris", + "LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}" + }, + "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind", + "workspaceFolder": "/workspace", + "updateRemoteUserUID": true, + + "build": { + "dockerfile": "../Dockerfile", + "context": "../", + "args": { + // "CONTAINER_WORKSPACE_FOLDER": "/workspace", + // "NEW_MAMBA_USER": "jovian", + // "NEW_MAMBA_USER_ID": "1010", + // "NEW_MAMBA_USER_GID": "1010", + }, + }, + "extensions": [ + "ms-python.python", + "ms-python.vscode-pylance", + "ms-toolsai.jupyter", + "ms-azuretools.vscode-docker", + "ms-vscode.makefile-tools", + "ms-vscode-remote.remote-containers", + "ms-vscode-remote.vscode-remote-extensionpack", + "GitHub.copilot", + "GitHub.copilot-chat", + ], + "remoteUser": "jovian", + "settings": { + "terminal.integrated.shell.linux": "/bin/bash", + "terminal.integrated.shellArgs.linux": ["-c"], + "terminal.integrated.defaultProfile.linux": "bash", + "terminal.integrated.profiles.linux": { + "bash": { + "path": "/bin/bash" + } + }, + "files.autoSave": "afterDelay", + "python.pythonPath": "/opt/conda/bin/python", + "python.defaultInterpreterPath": "/opt/conda/bin/python", + "jupyter.interactiveWindow.textEditor.magicCommandsAsComments": true, + "python.terminal.activateEnvironment": false + }, + "mounts": [ + "source=${localWorkspaceFolder}/.devcontainer/.cache,target=/home/jovian/.cache,type=bind,consistency=cached" + ], + "postCreateCommand": "sh /usr/local/bin/startup.sh" +} diff --git a/.devcontainer/fix-permissions.sh b/.devcontainer/fix-permissions.sh new file mode 100755 index 0000000..2dc884b --- /dev/null +++ b/.devcontainer/fix-permissions.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# Check if the user can execute commands with sudo +if sudo -l &>/dev/null; then + echo "User has sudo privileges. Proceeding with file and directory checks." + + # Get the current user's UID and GID + USER_UID=$(id -u) + USER_GID=$(id -g) + + sudo chown -R $USER_UID:$USER_GID /data + sudo chown -R $USER_UID:$USER_GID $MAMBA_ROOT_PREFIX + +else + echo "User does not have sudo privileges. Exiting script." +fi diff --git a/.devcontainer/startup.sh b/.devcontainer/startup.sh new file mode 100755 index 0000000..a39cd3c --- /dev/null +++ b/.devcontainer/startup.sh @@ -0,0 +1,2 @@ +#!/bin/bash +cd /data/quetz && quetz start . --port 8000 --host 0.0.0.0 --proxy-headers --reload --log-level=trace \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f9a5618 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,102 @@ +# syntax=docker/dockerfile:1.2 + +ARG BASE_IMAGE=debian:bookworm-slim +FROM --platform=$BUILDPLATFORM $BASE_IMAGE AS fetch +ARG VERSION=1.5.3 + +RUN rm -f /etc/apt/apt.conf.d/docker-* +RUN --mount=type=cache,target=/var/cache/apt,id=apt-deb12 apt-get update && apt-get install -y --no-install-recommends bzip2 ca-certificates curl + +RUN if [ "$BUILDPLATFORM" = 'linux/arm64' ]; then \ + export ARCH='aarch64'; \ + else \ + export ARCH='64'; \ + fi; \ + curl -L "https://micro.mamba.pm/api/micromamba/linux-${ARCH}/${VERSION}" | \ + tar -xj -C "/tmp" "bin/micromamba" + + +FROM --platform=$BUILDPLATFORM $BASE_IMAGE as micromamba + +ARG MAMBA_ROOT_PREFIX="/opt/conda" +ARG MAMBA_EXE="/bin/micromamba" + +ENV LANG=C.UTF-8 LC_ALL=C.UTF-8 +ENV MAMBA_ROOT_PREFIX=$MAMBA_ROOT_PREFIX +ENV MAMBA_EXE=$MAMBA_EXE +ENV PATH="${PATH}:${MAMBA_ROOT_PREFIX}/bin" + +COPY --from=fetch /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt +COPY --from=fetch /tmp/bin/micromamba "$MAMBA_EXE" + +ARG MAMBA_USER=jovian +ARG MAMBA_USER_ID=1000 +ARG MAMBA_USER_GID=1000 + +ENV MAMBA_USER=$MAMBA_USER +ENV MAMBA_USER_ID=$MAMBA_USER_ID +ENV MAMBA_USER_GID=$MAMBA_USER_GID + +RUN groupadd -g "${MAMBA_USER_GID}" "${MAMBA_USER}" && \ + useradd -m -u "${MAMBA_USER_ID}" -g "${MAMBA_USER_GID}" -s /bin/bash "${MAMBA_USER}" +RUN mkdir -p "${MAMBA_ROOT_PREFIX}/environments" && \ + chown "${MAMBA_USER}:${MAMBA_USER}" "${MAMBA_ROOT_PREFIX}" + +ARG CONTAINER_WORKSPACE_FOLDER=/workspace +RUN mkdir -p "${CONTAINER_WORKSPACE_FOLDER}" +WORKDIR "${CONTAINER_WORKSPACE_FOLDER}" + +USER $MAMBA_USER +RUN micromamba shell init --shell bash --prefix=$MAMBA_ROOT_PREFIX +SHELL ["/bin/bash", "--rcfile", "/$MAMBA_USER/.bashrc", "-c"] + + +FROM micromamba AS core + +COPY --chown=$MAMBA_USER:$MAMBA_USER environment.yml /opt/conda/environments/environment.yml +RUN --mount=type=cache,target=$MAMBA_ROOT_PREFIX/pkgs,id=mamba-pkgs micromamba install -y --override-channels -c conda-forge -n base -f /opt/conda/environments/environment.yml + + +FROM core as core-devel + +USER root +COPY --chown=$MAMBA_USER:$MAMBA_USER .devcontainer/apt-devel.txt /opt/conda/environments/apt-devel.txt +RUN --mount=type=cache,target=/var/cache/apt,id=apt-deb12 apt-get update && xargs apt-get install -y < /opt/conda/environments/apt-devel.txt + +RUN usermod -aG sudo $MAMBA_USER +RUN echo "$MAMBA_USER ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers + +COPY .devcontainer/fix-permissions.sh /bin/fix-permissions.sh +RUN chmod +x /bin/fix-permissions.sh && \ + echo 'export MAMBA_USER_ID=$(id -u)' >> /home/$MAMBA_USER/.bashrc && \ + echo 'export MAMBA_USER_GID=$(id -g)' >> /home/$MAMBA_USER/.bashrc && \ + echo "/bin/fix-permissions.sh" >> /home/$MAMBA_USER/.bashrc && \ + echo "micromamba activate" >> /home/$MAMBA_USER/.bashrc + +RUN mkdir -p /code && chown -R $MAMBA_USER:$MAMBA_USER /code +RUN mkdir -p /data && chown -R $MAMBA_USER:$MAMBA_USER /data + +COPY .devcontainer/startup.sh /usr/local/bin/startup.sh +RUN chmod +x /usr/local/bin/startup.sh +ENTRYPOINT ["startup.sh"] + +USER $MAMBA_USER + +RUN cd /code && git clone https://github.com/mamba-org/quetz.git +RUN cd /code/quetz/plugins/quetz_runexports && pip install . --no-cache +RUN cd /code/quetz/plugins/quetz_repodata_patching && pip install . --no-cache +RUN cd /code/quetz/plugins/quetz_current_repodata && pip install . --no-cache +RUN cd /code/quetz/plugins/quetz_repodata_zchunk && pip install . --no-cache +RUN cd /code/quetz/plugins/quetz_transmutation && pip install . --no-cache +RUN pip install git+https://git@github.com/regro/libcflib@master --no-deps +RUN cd /code/quetz/plugins/quetz_harvester && pip install . --no-cache --no-deps +RUN cd /code/quetz/plugins/quetz_tos && pip install . --no-cache --no-deps + +COPY --chown=$MAMBA_USER:$MAMBA_USER . /code/quetz-frontend +RUN pip install -e /code/quetz-frontend +RUN quetz-frontend link-frontend --development + +COPY --chown=$MAMBA_USER:$MAMBA_USER .devcontainer/config.toml /data +RUN cd /data && quetz create --create-conf /data/quetz + +EXPOSE 8000 \ No newline at end of file diff --git a/environment.yml b/environment.yml index 21ddff0..76e1ab8 100644 --- a/environment.yml +++ b/environment.yml @@ -5,3 +5,8 @@ dependencies: - quetz - nodejs=16 - yarn=1.22 + - sqlalchemy + - sqlalchemy-utils + - conda-build + - psycopg2 + - xattr \ No newline at end of file