Skip to content

Commit fc4cc45

Browse files
author
Hugo Lecomte
committed
Add Guix buildpack
1 parent 73ab48a commit fc4cc45

File tree

20 files changed

+172
-0
lines changed

20 files changed

+172
-0
lines changed

docs/source/config_files.rst

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,27 @@ to produce a reproducible environment.
231231
To see an example repository visit
232232
`nix binder example <https://github.com/binder-examples/nix>`_.
233233

234+
.. _manifest.scm:
235+
236+
``manifest.scm`` - the Guix package manager
237+
===========================================
238+
239+
Specify packages to be installed by the `Guix package manager <https://guix.gnu.org/>`_.
240+
All packages specified in |manifest|_ will be installed in a container using |guix_package|_. In addition, you can use different `channels <https://guix.gnu.org/manual/en/html_node/Channels.html>`_ rather
241+
than the ones available by default (official channels of GNU Guix 1.3.0).
242+
You must describe such channels in a ``channels.scm`` file which will be used
243+
alongside ``manifest.scm`` with the |guix_time-machine|_ command. Furthermore, using a ``channels.scm`` file lets you `pin a specific revision <https://guix.gnu.org/manual/en/html_node/Replicating-Guix.html>`_ of Guix, allowing you to unambiguously specific the software environment to reproduce.
244+
245+
For more information about Guix please read the `manual <https://guix.gnu.org/manual/en/guix.html>`_.
246+
247+
.. |manifest| replace:: ``manifest.scm``
248+
.. _manifest: https://guix.gnu.org/manual/en/html_node/Invoking-guix-package.html#index-profile-manifesthy
249+
250+
.. |guix_package| replace:: ``guix package``
251+
.. _guix_package: https://guix.gnu.org/manual/en/html_node/Invoking-guix-package.html#Invoking-guix-package
252+
253+
.. |guix_time-machine| replace:: ``guix time-machine``
254+
.. _guix_time-machine: https://guix.gnu.org/manual/en/html_node/Invoking-guix-time_002dmachine.html
234255

235256
``Dockerfile`` - Advanced environments
236257
======================================

repo2docker/app.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
PipfileBuildPack,
3838
PythonBuildPack,
3939
RBuildPack,
40+
GuixBuildPack,
4041
)
4142
from . import contentproviders
4243
from .utils import ByteSpecification, chdir
@@ -99,6 +100,7 @@ def _default_log_level(self):
99100
CondaBuildPack,
100101
PipfileBuildPack,
101102
PythonBuildPack,
103+
GuixBuildPack,
102104
],
103105
config=True,
104106
help="""

repo2docker/buildpacks/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@
88
from .legacy import LegacyBinderDockerBuildPack
99
from .r import RBuildPack
1010
from .nix import NixBuildPack
11+
from .guix import GuixBuildPack

repo2docker/buildpacks/base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,3 +718,4 @@ def get_start_script(self):
718718
# the only path evaluated at container start time rather than build time
719719
return os.path.join("${REPO_DIR}", start)
720720
return None
721+
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
"""BuildPack for guix environments"""
2+
import os
3+
4+
from ..base import BuildPack, BaseImage
5+
6+
7+
class GuixBuildPack(BaseImage):
8+
"""A guix Package Manager BuildPack"""
9+
10+
def get_path(self):
11+
"""Return paths to be added to PATH environment variable"""
12+
return super().get_path() + [
13+
"/var/guix/profiles/per-user/$NB_USER/.guix-profile/bin"
14+
]
15+
16+
17+
def get_build_scripts(self):
18+
"""
19+
Install guix package manager version 1.3.0.x86_64-linux, using
20+
an unmodified installation script found at
21+
https://git.savannah.gnu.org/cgit/guix.git/plain/etc/guix-install.sh?id=a0178d34f582b50e9bdbb0403943129ae5b560ff
22+
"""
23+
return super().get_build_scripts() + [
24+
(
25+
"root",
26+
"""
27+
bash /tmp/.local/bin/guix-install.bash
28+
""",
29+
),
30+
31+
]
32+
33+
def get_build_script_files(self):
34+
35+
"""Copying guix installation script on the image"""
36+
return {
37+
"guix/guix-install.bash":
38+
"/tmp/.local/bin/guix-install.bash",
39+
}
40+
41+
def get_assemble_scripts(self):
42+
"""
43+
Wake up the guix daemon with root permission, set guix environnement
44+
variables, make sure we never use debian's python by error by
45+
renaming it, then, as an user install packages listed in
46+
manifest.scm, use guix time-machine if channels.scm file exists
47+
"""
48+
assemble_script ="""
49+
/var/guix/profiles/per-user/root/current-guix/bin/guix-daemon \
50+
--build-users-group=guixbuild --disable-chroot & \
51+
mv /usr/bin/python /usr/bin/python.debian && \
52+
su - $NB_USER -c '{}' && \
53+
echo 'GUIX_PROFILE="/var/guix/profiles/per-user/$NB_USER/.guix-profile" ; \
54+
source "$GUIX_PROFILE/etc/profile"'>> ~/.bash_profile
55+
"""
56+
57+
if os.path.exists(self.binder_path("channels.scm")):
58+
assemble_script = assemble_script.format(
59+
"guix time-machine -C " + self.binder_path("channels.scm") +
60+
" -- package -m " + self.binder_path("manifest.scm")
61+
)
62+
else:
63+
assemble_script = assemble_script.format(
64+
"guix package -m " + self.binder_path("manifest.scm")
65+
)
66+
return super().get_assemble_scripts() + [
67+
( "root",
68+
assemble_script,
69+
)
70+
]
71+
72+
def detect(self):
73+
"""Check if current repo should be built with the guix BuildPack"""
74+
return os.path.exists(self.binder_path("manifest.scm"))
75+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/bin/bash
2+
# This downloads and installs a pinned version of Guix
3+
set -ex
4+
5+
wget https://git.savannah.gnu.org/cgit/guix.git/plain/etc/guix-install.sh?id=a0178d34f582b50e9bdbb0403943129ae5b560ff
6+
7+
yes | BIN_VER=1.3.0x86_64-linux \
8+
bash guix-install.sh?id=a0178d34f582b50e9bdbb0403943129ae5b560ff

tests/guix/binder-dir/README.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
`manifest.scm` in a binder/ directory
2+
-------------------------------------
3+
4+
Check if we can find and use `manifest.scm` when it is ina `binder/` sub-directory.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
(specifications->manifest
2+
'("jupyter"
3+
"hello"))

tests/guix/binder-dir/verify

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/sh
2+
3+
hello

tests/guix/ignore-outside/README.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
`manifest.scm` in main directory and in `binder/`
2+
-------------------------------------------------
3+
4+
Check if `manifest.scm` located in the `binder/` sub-directory is prefered to the one in the main directory.

0 commit comments

Comments
 (0)