Merge pull request #407 from costrouc/costrouc/nix-buildpack

Adding support for nix buildpack in repo2docker
pull/465/head
Tim Head 2018-11-05 15:27:48 +01:00 zatwierdzone przez GitHub
commit 5cdd0ee371
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
10 zmienionych plików z 155 dodań i 2 usunięć

Wyświetl plik

@ -49,6 +49,7 @@ env:
- REPO_TYPE=stencila
- REPO_TYPE=julia
- REPO_TYPE=r
- REPO_TYPE=nix
- REPO_TYPE=dockerfile
- REPO_TYPE=external/*
- REPO_TYPE=**/*.py

Wyświetl plik

@ -164,7 +164,6 @@ used for installing libraries.
To see an example R repository, visit our `R
example in binder-examples <https://github.com/binder-examples/r/blob/master/runtime.txt>`_.
``Dockerfile`` - Advanced environments
======================================
@ -179,3 +178,26 @@ With Dockerfiles, a regular Docker build will be performed.
See the `Advanced Binder Documentation <https://mybinder.readthedocs.io/en/latest/tutorials/dockerfile.html>`_ for
best-practices with Dockerfiles.
.. _default.nix:
``default.nix``
~~~~~~~~~~~~~~~
This allows you to use the `nix package manager <https://github.com/NixOS/nixpkgs>`_. It is hard to explain what nix
is to new users and why it is usefull. If you are inclined please read
more at the `nix homepage <https://nixos.org/nix/>`_. It is currently
the largest package repository, offers reproducible builds, multiple
versions of same package coexisting, source and binary based, and
packages many languages such as python, R, go, javascript, haskell,
ruby, etc. .
A ``default.nix`` file allows you to use `nix-shell <https://nixos.org/nix/manual/#sec-nix-shell>`_
to evaluate a ``nix`` expression to define a reproducible nix environment.
The only requirement is that you expose a ``jupyter`` command within the shell
(since jupyterlab is currently what ``repo2docker`` is designed
around). While the ``nix`` environment does have ``NIX_PATH`` set with
``nixpkgs=...`` you should not rely on it and make sure to
`pin your nixpkgs <https://discourse.nixos.org/t/nixops-pinning-nixpkgs/734>`_.
By doing this you are truley producing a reproducible environment. To see an
example repository visit a `nix binder example <https://gitlab.com/costrouc/nix-binder-example>`_.

Wyświetl plik

@ -30,7 +30,8 @@ from traitlets.config import Application
from . import __version__
from .buildpacks import (
PythonBuildPack, DockerBuildPack, LegacyBinderDockerBuildPack,
CondaBuildPack, JuliaBuildPack, RBuildPack
CondaBuildPack, JuliaBuildPack, BaseImage,
RBuildPack, NixBuildPack
)
from . import contentproviders
from .utils import (
@ -77,6 +78,7 @@ class Repo2Docker(Application):
LegacyBinderDockerBuildPack,
DockerBuildPack,
JuliaBuildPack,
NixBuildPack,
RBuildPack,
CondaBuildPack,
PythonBuildPack,

Wyświetl plik

@ -5,3 +5,4 @@ from .julia import JuliaBuildPack
from .docker import DockerBuildPack
from .legacy import LegacyBinderDockerBuildPack
from .r import RBuildPack
from .nix import NixBuildPack

Wyświetl plik

@ -0,0 +1,70 @@
"""BuildPack for nixpkgs environments"""
import os
from ..base import BuildPack
class NixBuildPack(BuildPack):
"""A nix Package Manager BuildPack"""
def get_path(self):
"""Return paths to be added to PATH environemnt variable
"""
return super().get_path() + [
'/home/${NB_USER}/.nix-profile/bin'
]
def get_env(self):
"""Ordered list of environment variables to be set for this image"""
return super().get_env() + [
('NIX_PATH', "nixpkgs=/home/${NB_USER}/.nix-defexpr/channels/nixpkgs"),
('NIX_SSL_CERT_FILE', '/etc/ssl/certs/ca-certificates.crt'),
('GIT_SSL_CAINFO', '/etc/ssl/certs/ca-certificates.crt')
]
def get_build_scripts(self):
"""
Return series of build-steps common to all nix repositories.
Notice how only root privileges are needed for creating nix
directory.
- create nix directory for user nix installation
- install nix package manager for user
"""
return super().get_build_scripts() + [
("root", """
mkdir -m 0755 /nix && \
chown -R ${NB_USER}:${NB_USER} /nix /usr/local/bin/nix-shell-wrapper /home/${NB_USER}
"""),
("${NB_USER}", """
bash /home/${NB_USER}/.local/bin/install-nix.bash && \
rm /home/${NB_USER}/.local/bin/install-nix.bash
""")
]
def get_build_script_files(self):
"""Dict of files to be copied to the container image for use in building
"""
return {
"nix/install-nix.bash": "/home/${NB_USER}/.local/bin/install-nix.bash",
"nix/nix-shell-wrapper": "/usr/local/bin/nix-shell-wrapper"
}
def get_assemble_scripts(self):
"""Return series of build-steps specific to this source repository.
"""
return super().get_assemble_scripts() + [
('${NB_USER}', """
nix-channel --add https://nixos.org/channels/nixpkgs-unstable nixpkgs && \
nix-channel --update && \
nix-shell default.nix --command "command -v jupyter"
""")
]
def get_start_script(self):
"""The path to a script to be executed as ENTRYPOINT"""
return "/usr/local/bin/nix-shell-wrapper"
def detect(self):
"""Check if current repo should be built with the nix BuildPack"""
return os.path.exists(self.binder_path('default.nix'))

Wyświetl plik

@ -0,0 +1,12 @@
#!/bin/bash
# This downloads and installs a pinned version of nix
set -ex
NIX_VERSION="2.1.1"
NIX_SHA256="ad10b4da69035a585fe89d7330037c4a5d867a372bb0e52a1542ab95aec67999"
wget https://nixos.org/releases/nix/nix-$NIX_VERSION/nix-$NIX_VERSION-x86_64-linux.tar.bz2
echo "$NIX_SHA256 nix-2.1.1-x86_64-linux.tar.bz2" | sha256sum -c
tar xjf nix-*-x86_64-linux.tar.bz2
sh nix-*-x86_64-linux/install
rm -r nix-*-x86_64-linux*

Wyświetl plik

@ -0,0 +1,15 @@
#!/bin/bash
_term() {
echo "Caught SIGTERM signal!"
# kill -TERM "$PID" 2>/dev/null
exit 0
}
trap _term SIGTERM
echo "$*"
nix-shell default.nix --command "$*" &
PID=$!
wait "$PID"

Wyświetl plik

@ -0,0 +1,6 @@
Nix environment - default.nix
-----------------------------
You can install a nix shell environment using the traditional default.nix.
Documentation on the syntax and typical setup of a ``nix-shell`` environment can be found `here <https://nixos.org/nix/manual/#sec-nix-shell>`_.

Wyświetl plik

@ -0,0 +1,21 @@
let
# Pinning nixpkgs to specific release
# To get sha256 use "nix-prefetch-git <url> --rev <commit>"
commitRev="5574b6a152b1b3ae5f93ba37c4ffd1981f62bf5a";
nixpkgs = builtins.fetchTarball {
url = "https://github.com/NixOS/nixpkgs/archive/${commitRev}.tar.gz";
sha256 = "1pqdddp4aiz726c7qs1dwyfzixi14shp0mbzi1jhapl9hrajfsjg";
};
pkgs = import nixpkgs { config = { allowUnfree = true; }; };
in
pkgs.mkShell {
buildInputs = with pkgs; [
python36Packages.numpy
python36Packages.scipy
python36Packages.jupyterlab
];
shellHook = ''
export NIX_PATH="nixpkgs=${nixpkgs}:."
'';
}

Wyświetl plik

@ -0,0 +1,3 @@
#!/usr/bin/env python
import numpy
import scipy