Skip to content

Commit ffd2ddf

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

File tree

20 files changed

+178
-0
lines changed

20 files changed

+178
-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
@@ -95,6 +96,7 @@ def _default_log_level(self):
9596
JuliaProjectTomlBuildPack,
9697
JuliaRequireBuildPack,
9798
NixBuildPack,
99+
GuixBuildPack,
98100
RBuildPack,
99101
CondaBuildPack,
100102
PipfileBuildPack,

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: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
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 a pinned version of Guix package manager,
20+
precised in guix-install.bash.
21+
"""
22+
return super().get_build_scripts() + [
23+
(
24+
"root",
25+
"""
26+
bash /tmp/.local/bin/guix-install.bash
27+
""",
28+
),
29+
30+
]
31+
32+
def get_build_script_files(self):
33+
34+
"""Copying guix installation script on the image"""
35+
return {
36+
"guix/guix-install.bash":
37+
"/tmp/.local/bin/guix-install.bash",
38+
}
39+
40+
def get_assemble_scripts(self):
41+
"""
42+
Launch Guix daemon with --disable-chroot to avoid the need
43+
of root privileges for the user.
44+
Make sure we never use Debian's python by error by renaming it
45+
then, as an user install packages listed in manifest.scm,
46+
use guix time-machine if channels.scm file exists.
47+
Finally set guix environment variables.
48+
"""
49+
assemble_script ="""
50+
/var/guix/profiles/per-user/root/current-guix/bin/guix-daemon \
51+
--build-users-group=guixbuild --disable-chroot & \
52+
mv /usr/bin/python /usr/bin/python.debian && \
53+
su - $NB_USER -c '{}' && \
54+
echo 'GUIX_PROFILE="/var/guix/profiles/per-user/$NB_USER/.guix-profile" ; \
55+
source "$GUIX_PROFILE/etc/profile"'>> /etc/profile.d/99-guix.sh
56+
"""
57+
58+
if os.path.exists(self.binder_path("channels.scm")):
59+
assemble_script = assemble_script.format(
60+
"guix time-machine -C " + self.binder_path("channels.scm") +
61+
" -- package -m " + self.binder_path("manifest.scm")
62+
)
63+
else:
64+
assemble_script = assemble_script.format(
65+
"guix package -m " + self.binder_path("manifest.scm")
66+
)
67+
return super().get_assemble_scripts() + [
68+
( "root",
69+
assemble_script,
70+
)
71+
]
72+
73+
def detect(self):
74+
"""Check if current repo should be built with the guix BuildPack"""
75+
return os.path.exists(self.binder_path("manifest.scm"))
76+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# This downloads and installs a pinned version of Guix using a pinned version of the installation script.
2+
# Here is the commit associated with Guix version 1.3.0 the latest version when this script was written.
3+
set -euxo pipefail
4+
5+
GUIX_COMMIT="a0178d34f582b50e9bdbb0403943129ae5b560ff"
6+
BIN_VER="1.3.0x86_64-linux"
7+
GUIX_SHA256="bcdeaa757cd42d2c9de4791272737e9ee0d518398403955f113611f4a893380a"
8+
9+
wget "https://git.savannah.gnu.org/cgit/guix.git/plain/etc/guix-install.sh?id=$GUIX_COMMIT"
10+
11+
echo "$GUIX_SHA256 guix-install.sh?id=$GUIX_COMMIT" | sha256sum -c
12+
13+
(yes || true) | BIN_VER=$BIN_VER bash guix-install.sh?id=$GUIX_COMMIT

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.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
(specifications->manifest
2+
'("jupyter"
3+
"python"
4+
"python-numpy"))
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
(specifications->manifest
2+
'("jupyter"))

tests/guix/ignore-outside/verify

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/usr/bin/env python3
2+
3+
import numpy

tests/guix/simple-channels/README.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
`manifest.scm` and `channels.scm` in main directory
2+
---------------------------------------------------
3+
4+
CHeck if we can use `manifest.scm` alongside a `channels.scm` file using `guix time-machine ...`
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
(list (channel
2+
(name 'guix)
3+
(url "https://git.savannah.gnu.org/git/guix.git")
4+
(commit
5+
"f1bfd9f1948a5ff336d737c0614b9a30c2bb3097")
6+
(introduction
7+
(make-channel-introduction
8+
"9edb3f66fd807b096b48283debdcddccfea34bad"
9+
(openpgp-fingerprint
10+
"BBB0 2DDF 2CEA F6A8 0D1D E643 A2A0 6DF2 A33A 54FA"))))
11+
(channel
12+
(name 'nonguix)
13+
(url "https://gitlab.com/nonguix/nonguix")
14+
(commit
15+
"46c1d8bcca674d3a71cd077c52dde9552a89873d")
16+
(introduction
17+
(make-channel-introduction
18+
"897c1a470da759236cc11798f4e0a5f7d4d59fbc"
19+
(openpgp-fingerprint
20+
"2A39 3FFF 68F4 EF7A 3D29 12AF 6F51 20A0 22FB B2D5")))))
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/simple-channels/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/simple/README.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
`manifest.scm` in the main directory
3+
----------------------------------
4+
5+
Check if we can find and use `manifest.scm` when it is in the main directory.

tests/guix/simple/manifest.scm

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/simple/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

0 commit comments

Comments
 (0)