;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2017 David Craven ;;; Copyright © 2017, 2020, 2022 Mathieu Othacehe ;;; Copyright © 2017 Leo Famulari ;;; Copyright © 2019, 2021, 2023 Ludovic Courtès ;;; Copyright © 2020 Jan (janneke) Nieuwenhuizen ;;; Copyright © 2022 Josselin Poiret ;;; Copyright © 2022 Reza Alizadeh Majd ;;; Copyright © 2024 Tomas Volf <~@wolfsden.cz> ;;; ;;; This file is part of GNU Guix. ;;; ;;; GNU Guix is free software; you can redistribute it and/or modify it ;;; under the terms of the GNU General Public License as published by ;;; the Free Software Foundation; either version 3 of the License, or (at ;;; your option) any later version. ;;; ;;; GNU Guix is distributed in the hope that it will be useful, but ;;; WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;; GNU General
aboutsummaryrefslogtreecommitdiff
blob: ca786437e99e454cb9eb217d9c696f3ea96d81f8 (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/bin/sh

# GNU Guix --- Functional package management for GNU
# Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2021 Ludovic Courtès <ludo@gnu.org>
#
# This file is part of GNU Guix.
#
# GNU Guix is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or (at
# your option) any later version.
#
# GNU Guix is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

# Usage: ./test-env COMMAND ARG...
#
# Run the daemon in the build directory, and run COMMAND within
# `pre-inst-env'.  This is used to run unit tests with the just-built
# daemon, unless `--disable-daemon' was passed at configure time.


# Make sure 'cd' behaves deterministically and doesn't write anything to
# stdout.
unset CDPATH

case "$1" in
    --quiet-stderr)
	# Silence the daemon's output, which is often useless, as well as that
	# of Bash (such as "Terminated" messages when 'guix-daemon' is
	# killed.)
	exec 2> /dev/null
	shift
	;;
esac

if [ -x "@abs_top_builddir@/guix-daemon" ]
then
    NIX_STORE_DIR="@GUIX_TEST_ROOT@/store"

    # Do that because store.scm calls `canonicalize-path' on it.
    mkdir -p "$NIX_STORE_DIR"

    # Canonicalize the store directory name in an attempt to avoid symlinks in
    # it or its parent directories.  See <http://bugs.gnu.org/17935>.
    NIX_STORE_DIR="`cd "@GUIX_TEST_ROOT@/store"; pwd -P`"

    GUIX_LOG_DIRECTORY="@GUIX_TEST_ROOT@/var/log/guix"
    GUIX_DATABASE_DIRECTORY="@GUIX_TEST_ROOT@/db"

    # Choose a PID-dependent name to allow for parallel builds.  Note
    # that the directory name must be chosen so that the socket's file
    # name is less than 108-char long (the size of `sun_path' in glibc).
    # Currently, in Nix builds, we're at ~106 chars...
    GUIX_STATE_DIRECTORY="@GUIX_TEST_ROOT@/var/$$"

    # We can't exit when we reach the limit, because perhaps the test doesn't
    # actually rely on the daemon, but at least warn.
    if test "`echo -n "$GUIX_STATE_DIRECTORY/daemon-socket/socket" | wc -c`" -ge 108
    then
	echo "warning: exceeding socket file name limit; test may fail!" >&2
    fi

    # The configuration directory, for import/export signing keys.
    GUIX_CONFIGURATION_DIRECTORY="@GUIX_TEST_ROOT@/etc"
    if [ ! -d "$GUIX_CONFIGURATION_DIRECTORY" ]
    then
	# Copy the keys so that the secret key has the right permissions (the
	# daemon errors out when this is not the case.)
	mkdir -p "$GUIX_CONFIGURATION_DIRECTORY"
	cp "@abs_top_srcdir@/tests/keys/signing-key.sec"	\
	   "@abs_top_srcdir@/tests/keys/signing-key.pub"	\
	   "$GUIX_CONFIGURATION_DIRECTORY"
	chmod 400 "$GUIX_CONFIGURATION_DIRECTORY/signing-key.sec"
    fi

    # A place to store data of the substituter.
    GUIX_BINARY_SUBSTITUTE_URL="file://$GUIX_STATE_DIRECTORY/substituter-data"
    rm -rf "$GUIX_STATE_DIRECTORY/substituter-data"
    mkdir -p "$GUIX_STATE_DIRECTORY/substituter-data"

    # For a number of tests, we want to allow unsigned narinfos, for
    # simplicity.
    GUIX_ALLOW_UNAUTHENTICATED_SUBSTITUTES=yes

    # Place for the substituter's cache.
    XDG_CACHE_HOME="$GUIX_STATE_DIRECTORY/cache-$$"

    export NIX_IGNORE_SYMLINK_STORE NIX_STORE_DIR		\
	GUIX_LOG_DIRECTORY GUIX_STATE_DIRECTORY GUIX_DATABASE_DIRECTORY	\
	GUIX_BINARY_SUBSTITUTE_URL				\
        GUIX_ALLOW_UNAUTHENTICATED_SUBSTITUTES			\
        GUIX_CONFIGURATION_DIRECTORY XDG_CACHE_HOME

    # Launch the daemon without chroot support because is may be
    # unavailable, for instance if we're not running as root.
    "@abs_top_builddir@/pre-inst-env"				\
	"@abs_top_builddir@/guix-daemon" --disable-chroot	\
	--substitute-urls="$GUIX_BINARY_SUBSTITUTE_URL" &

    daemon_pid=$!
    trap "kill $daemon_pid ; rm -rf $GUIX_STATE_DIRECTORY" EXIT

    # The test suite expects the 'guile-bootstrap' package to be available.
    # Normally the Guile bootstrap tarball is downloaded by a fixed-output
    # derivation but when network access is missing we allow users to drop
    # the tarball in 'gnu/packages/bootstrap/SYSTEM' and "intern" it here.
    bootstrap_directory="@abs_top_builddir@/gnu/packages/bootstrap/@guix_system@"
    if [ -d "$bootstrap_directory" ]
    then
	# Make sure 'guix-daemon' is listening before invoking 'guix
	# download'.
	"@abs_top_builddir@/pre-inst-env" "@GUILE@" -c \
	     '(use-modules (guix))
(let loop ((i 10))
  (catch #t
    (lambda () (open-connection))
    (lambda (key . args)
      (if (zero? i)
          (apply throw key args)
          (begin (usleep 500000) (loop (- i 1)))))))'

	for file in "$bootstrap_directory"/guile-*
	do
	    [ -f "$file" ] &&					\
	    "@abs_top_builddir@/pre-inst-env"			\
		guix download "file://$file" > /dev/null
	done
    fi
fi

# Avoid issues that could stem from l10n, such as language/encoding
# mismatches.
unset LANGUAGE
LC_MESSAGES=C
export LC_MESSAGES

# Disable grafts by default because they can cause things to be built
# regardless of '--dry-run'.
GUIX_BUILD_OPTIONS="--no-grafts"
export GUIX_BUILD_OPTIONS

# Ignore user settings.
unset GUIX_PACKAGE_PATH

storedir="@storedir@"
prefix="@prefix@"
datarootdir="@datarootdir@"
datadir="@datadir@"
localstatedir="@localstatedir@"
export storedir prefix datarootdir datadir localstatedir

"@abs_top_builddir@/pre-inst-env" "$@"
exit $?
#:select (scandir)) ((srfi srfi-1) #:select (append-map every remove)) ((srfi srfi-26) #:select (cut))) (define (symlink-to file directory transform) "Creates a symlink to FILE named (TRANSFORM FILE) in DIRECTORY." (symlink file (string-append directory "/" (transform file)))) (define (directory-content directory) "Creates a list of absolute path names inside DIRECTORY." (map (lambda (name) (string-append directory name)) (or (scandir directory (lambda (name) (not (member name '("." ".."))))) '()))) (define name-ends-with-/? (cut string-suffix? "/" <>)) (define (name-is-store-entry? name) "Return #t if NAME is a direct store entry and nothing inside." (not (string-index (strip-store-file-name name) #\/))) (let* ((files '#$files) (directories (filter name-ends-with-/? files)) (names-from-directories (append-map (lambda (directory) (directory-content directory)) directories)) (names (append names-from-directories (remove name-ends-with-/? files)))) (mkdir-p #$output) (if (every file-exists? names) (begin (for-each (lambda (name) (symlink-to name #$output (if (name-is-store-entry? name) strip-store-file-name basename))) names) #t) #f))))) (gexp->derivation "efi-bootloader-profile" build #:system system #:local-build? #t #:substitutable? #f #:properties `((type . profile-hook) (hook . efi-bootloader-profile-hook)))) (profile (content (packages->manifest packages)) (name "efi-bootloader-profile") (hooks (cons efi-bootloader-profile-hook hooks)) (locales? #f) (allow-collisions? #f) (relative-symlinks? #f))) (define* (efi-bootloader-chain final-bootloader #:key (packages '()) (files '()) (hooks '()) installer disk-image-installer) "Define a chain of bootloaders with the FINAL-BOOTLOADER, optional PACKAGES, and optional directories and files from the store given in the list of FILES. The package of the FINAL-BOOTLOADER and all PACKAGES and FILES will be placed in an efi-bootloader-profile, which will be passed to the INSTALLER. FILES may contain file-like objects produced by procedures like plain-file, local-file, etc., or package contents produced with file-append. If a directory name in FILES ends with '/', then the directory content instead of the directory itself will be symlinked into the efi-bootloader-profile. The procedures in the HOOKS list can be used to further modify the bootloader profile. It is possible to pass a single function instead of a list. If the INSTALLER argument is used, then this gexp procedure will be called to install the efi-bootloader-profile. Otherwise the installer of the FINAL-BOOTLOADER will be called. If the DISK-IMAGE-INSTALLER is used, then this gexp procedure will be called to install the efi-bootloader-profile into a disk image. Otherwise the disk-image-installer of the FINAL-BOOTLOADER will be called." (bootloader (inherit final-bootloader) (name "efi-bootloader-chain") (package (efi-bootloader-profile (cons (bootloader-package final-bootloader) packages) files (if (list? hooks) hooks (list hooks)))) (installer (or installer (bootloader-installer final-bootloader))) (disk-image-installer (or disk-image-installer (bootloader-disk-image-installer final-bootloader)))))