Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 12 additions & 95 deletions Dockerfile.sandbox
Original file line number Diff line number Diff line change
Expand Up @@ -55,21 +55,6 @@ WORKDIR /sandbox
# Pipenv installs to the default user site since PIP_USER is set.
RUN pipenv install --deploy --system

# This must come after the first pipenv command! From the docs:
# All RUN instructions following an ARG instruction use the ARG variable
# implicitly (as an environment variable), thus can cause a cache miss.

# TODO: refactor this, I don't like that pytest depends on a docker
# container

# ARG DEV

# Install numpy when in dev mode; one of the unit tests needs it.
# RUN if [ -n "${DEV}" ]; \
# then \
# pipenv install --deploy --system --dev \
# && PYTHONUSERBASE=/opt/python/diggy pip install numpy~=1.20; \
# fi

# ------------------------------------------------------------------------------
FROM venv as sandbox
Expand All @@ -79,96 +64,28 @@ RUN apt-get -y update \
&& apt-get install -y \
curl \
gnupg2 \
procps \
# Conda dependencies, see below
# bzip2 \
# ca-certificates \
# libglib2.0-0 \
# libsm6 \
# libxext6 \
# libxrender1 \
# mercurial \
# subversion \
# wget \
&& rm -rf /var/lib/apt/lists/*

# == Python

# NOTE: I could not make conda work with nsjail, i.e. numpy fails with
# this error: Intel MKL FATAL ERROR: Cannot load <mkl-loader>. I am
# stuck, and if you manage to get it up and running, please let me
# know.

# ARG CONDA_VERSION=py38_4.9.2
# ARG CONDA_MD5=122c8c9beb51e124ab32a0fa6426c656
procps

# ENV PATH /opt/conda/bin:$PATH
# 1. Python

# # Based on https://github.com/ContinuumIO/docker-images
# RUN wget --quiet https://repo.anaconda.com/miniconda/Miniconda3-${CONDA_VERSION}-Linux-x86_64.sh -O miniconda.sh && \
# echo "${CONDA_MD5} miniconda.sh" > miniconda.md5 && \
# if ! md5sum --status -c miniconda.md5; then exit 1; fi && \
# mkdir -p /opt && \
# sh miniconda.sh -b -p /opt/conda && \
# rm miniconda.sh miniconda.md5 && \
# ln -s /opt/conda/etc/profile.d/conda.sh /etc/profile.d/conda.sh && \
# echo ". /opt/conda/etc/profile.d/conda.sh" >> ~/.bashrc && \
# echo "conda activate base" >> ~/.bashrc && \
# find /opt/conda/ -follow -type f -name '*.a' -delete && \
# find /opt/conda/ -follow -type f -name '*.js.map' -delete && \
# /opt/conda/bin/conda clean -afy
# RUN conda config --add channels intel
# RUN conda create --name diggy intelpython3_core python=3.7

# Pre-install Python packages

# SHELL ["conda", "run", "-n", "diggy", "/bin/bash", "-c"]

# RUN yes | conda install numpy \
# matplotlib

# TODO: extract this to a post-install script, all additional packages
# TODO: Extract this to a post-install script, all additional packages
# must be living outside of the Dockerfile. e.g. docker exec -it
# <container> -v $(pwd)/post-install.sh:/post-install.sh
# /post-install.sh
RUN PYTHONUSERBASE=/opt/python/diggy pip install matplotlib \
numpy

# == Ruby
# Based on https://github.com/ms-ati/docker-rvm/blob/master/Dockerfile
# I am not sure whether I like RVM approach more than a native Ruby
# package, but I am giving it a try.
ARG RVM_VERSION=stable
ENV RVM_VERSION=${RVM_VERSION}

# 3.0.0-preview1 was the latest available binary at the time of
# writting this Dockerfile
ARG RVM_RUBY_VERSION="3.0.0-preview1"
ENV RVM_RUBY_VERSION=${RVM_RUBY_VERSION}
ENV RVM_RUBY_DEFAULT=${RVM_RUBY_VERSION}

RUN mkdir ~/.gnupg \
&& chmod 700 ~/.gnupg \
&& echo "disable-ipv6" >> ~/.gnupg/dirmngr.conf \
&& gpg2 --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 \
7D2BAF1CF37B13E2069D6956105BD0E739499BDB \
&& curl -sSL https://raw.githubusercontent.com/rvm/rvm/${RVM_VERSION}/binscripts/rvm-installer -o rvm-installer \
&& curl -sSL https://raw.githubusercontent.com/rvm/rvm/${RVM_VERSION}/binscripts/rvm-installer.asc -o rvm-installer.asc \
&& gpg2 --verify rvm-installer.asc rvm-installer \
&& bash rvm-installer \
&& rm rvm-installer rvm-installer.asc \
&& echo "rvm_autoupdate_flag=2" >> /etc/rvmrc \
&& echo "rvm_silence_path_mismatch_check_flag=1" >> /etc/rvmrc \
&& echo "install: --no-document" > /etc/gemrc
# 2. Ruby
RUN apt-get install -y \
ruby ruby-dev

SHELL ["/bin/bash", "--login", "-c"]
# 3. C/C++
RUN apt-get install -y \
clang

# Clean up
RUN rm -rf /var/lib/apt/lists/*

RUN echo "== docker-rvm: Installing ${RVM_RUBY_VERSION} ==" \
&& rvm install ${RVM_RUBY_VERSION} \
&& echo "== docker-rvm: Setting default ${RVM_RUBY_DEFAULT} ==" \
&& rvm use --default ${RVM_RUBY_DEFAULT} \
&& rvm cleanup all \
&& rm -rf /var/lib/apt/lists/*

# ------------------------------------------------------------------------------
FROM sandbox
Expand Down
135 changes: 125 additions & 10 deletions diggy-sandbox/config/sandbox.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ gidmap {
cgroup_mem_max: 52428800
cgroup_mem_mount: "/sys/fs/cgroup/memory"

cgroup_pids_max: 2
cgroup_pids_max: 3
cgroup_pids_mount: "/sys/fs/cgroup/pids"

iface_no_lo: true
Expand Down Expand Up @@ -91,7 +91,9 @@ mount {
rw: true
}

# == Python
envar: "PATH=/usr/bin"

# 1. Python
envar: "PYTHONIOENCODING=utf-8:strict"
envar: "PYTHONPATH=/opt/python/diggy/lib/python3.9/site-packages"
envar: "OMP_NUM_THREADS=1"
Expand All @@ -114,26 +116,139 @@ mount {
rw: false
}

# 2. Ruby
mount {
src: "/usr/local/bin/python3"
dst: "/usr/local/bin/python3"
src: "/usr/bin/ruby"
dst: "/usr/bin/ruby"
is_bind: true
rw: false
}

# 3. C/C++

mount {
src: "/usr/local/bin/python3.9"
dst: "/usr/local/bin/python3.9"
src: "/usr/bin/gcc"
dst: "/usr/bin/gcc"
is_bind: true
rw: false
}

# == Ruby
envar: "LD_LIBRARY_PATH=/usr/local/rvm/rubies/default/lib"
mount {
src: "/usr/include"
dst: "/usr/include"
is_bind: true
rw: false
}

# everything from binutils
mount {
src: "/usr/bin/ld"
dst: "/usr/bin/ld"
is_bind: true
rw: false
}

mount {
src: "/usr/bin/ld"
dst: "/usr/bin/ld"
is_bind: true
rw: false
}

mount {
src: "/usr/bin/as"
dst: "/usr/bin/as"
is_bind: true
rw: false
}

mount {
src: "/usr/bin/addr2line"
dst: "/usr/bin/addr2line"
is_bind: true
rw: false
}

mount {
src: "/usr/bin/ar"
dst: "/usr/bin/ar"
is_bind: true
rw: false
}

mount {
src: "/usr/bin/c++filt"
dst: "/usr/bin/c++filt"
is_bind: true
rw: false
}

mount {
src: "/usr/bin/gold"
dst: "/usr/bin/gold"
is_bind: true
rw: false
}

mount {
src: "/usr/bin/gprof"
dst: "/usr/bin/gprof"
is_bind: true
rw: false
}

mount {
src: "/usr/bin/nm"
dst: "/usr/bin/nm"
is_bind: true
rw: false
}

mount {
src: "/usr/bin/objcopy"
dst: "/usr/bin/objcopy"
is_bind: true
rw: false
}

mount {
src: "/usr/bin/objdump"
dst: "/usr/bin/objdump"
is_bind: true
rw: false
}

mount {
src: "/usr/bin/ranlib"
dst: "/usr/bin/ranlib"
is_bind: true
rw: false
}

mount {
src: "/usr/bin/readelf"
dst: "/usr/bin/readelf"
is_bind: true
rw: false
}

mount {
src: "/usr/bin/size"
dst: "/usr/bin/size"
is_bind: true
rw: false
}

mount {
src: "/usr/bin/strings"
dst: "/usr/bin/strings"
is_bind: true
rw: false
}

mount {
src: "/usr/local/rvm/rubies/default"
dst: "/usr/local/rvm/rubies/default"
src: "/usr/bin/strip"
dst: "/usr/bin/strip"
is_bind: true
rw: false
}
2 changes: 1 addition & 1 deletion diggy-sandbox/sandbox/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def main() -> None:
nsjail = NsJail(nsjail_config=NSJAIL_SYSTEM_CFG)
result = nsjail.system(args.command.split(' '))
else:
nsjail = Nsjail()
nsjail = NsJail()
result = nsjail.run(username=args.username, filename=args.filename)

print(result.stdout)
Expand Down
15 changes: 12 additions & 3 deletions diggy-sandbox/sandbox/langs.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
langs = {
".py": {"name": "Python", "path": "/usr/local/bin/python", "args": "-BSqu"},
".py": {
"name": "Python",
"run": "/usr/local/bin/python",
"run_args": ("-BSqu")
},
".rb": {
"name": "Ruby",
"path": "/usr/local/rvm/rubies/default/bin/ruby",
"args": "",
"run": "/usr/bin/ruby",
},
".c": {
"name": "C",
"compile": "/usr/bin/gcc",
"compile_args": ("-Wall", "-Wextra"),
"run": "/userland/a.out",
}
}
23 changes: 17 additions & 6 deletions diggy-sandbox/sandbox/nsjail.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,17 +202,28 @@ def run(self, filename: str, username: str) -> CompletedProcess:
if lang is None:
return CompletedProcess('', 0, "Language is not supported", None)

args = (
lang["path"],
lang["args"],
userland_resolve(filename),
)
compact_args = list(filter(None, args))
fullname = userland_resolve(filename)
nsjail_args = (
"--bindmount",
f"{USERLAND_PATH}/{username}:{USERLAND_PATH}",
)

if lang.get("compile"):
compile_args = (
lang["compile"],
*lang.get("compile_args", ()),
fullname,
)
compact_compile_args = list(filter(None, compile_args))
self.jail(args=compact_compile_args, nsjail_args=nsjail_args)

args = (
lang["run"],
*lang.get("args", ()),
fullname,
)
compact_args = list(filter(None, args))

return self.jail(args=compact_args, nsjail_args=nsjail_args)

def jail(
Expand Down
7 changes: 7 additions & 0 deletions userland_tpl/welcome/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include <stdio.h>

int main()
{
printf("Hello, world!");
return 0;
}