aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2017-01-11 17:06:31 +0100
committerLudovic Courtès <ludo@gnu.org>2017-01-11 17:06:31 +0100
commit9b5364a3afb03414bd6e3ded2fbfdacabe4e8870 (patch)
tree82ff386c867e792cf8ca2d1cf3c1b68390d6d2de
parentaa042770da2fe6411089a965ea8b2219a99d3448 (diff)
downloadguix-9b5364a3afb03414bd6e3ded2fbfdacabe4e8870.tar
guix-9b5364a3afb03414bd6e3ded2fbfdacabe4e8870.tar.gz
daemon: Allow check builds of 'builtin:download' derivations.
Fixes <http://bugs.gnu.org/25089>. Reported by Leo Famulari <leo@famulari.name>. * nix/libstore/build.cc (DerivationGoal::runChild): In the 'isBuiltin' case, check whether DRV's output is in 'redirectedOutputs', and pass an 'output' argument to the built-in builder. (DerivationGoal::addHashRewrite): Add 'printMsg' call. * nix/libstore/builtins.hh (derivationBuilder): Add 'output' parameter. * nix/libstore/builtins.cc (builtinDownload): Likewise. Add OUTPUT to ARGV. * guix/scripts/perform-download.scm (perform-download): Add 'output' parameter. (guix-perform-download): Adjust 'match' clauses accordingly. * tests/derivations.scm ("'download' built-in builder, check mode"): New test.
-rw-r--r--guix/scripts/perform-download.scm21
-rw-r--r--nix/libstore/build.cc15
-rw-r--r--nix/libstore/builtins.cc10
-rw-r--r--nix/libstore/builtins.hh5
-rw-r--r--tests/derivations.scm27
5 files changed, 62 insertions, 16 deletions
diff --git a/guix/scripts/perform-download.scm b/guix/scripts/perform-download.scm
index 0d2e7089aa..58a7377141 100644
--- a/guix/scripts/perform-download.scm
+++ b/guix/scripts/perform-download.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2016, 2017 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -19,7 +19,7 @@
(define-module (guix scripts perform-download)
#:use-module (guix ui)
#:use-module (guix derivations)
- #:use-module ((guix store) #:select (derivation-path?))
+ #:use-module ((guix store) #:select (derivation-path? store-path?))
#:use-module (guix build download)
#:use-module (ice-9 match)
#:export (guix-perform-download))
@@ -41,10 +41,13 @@
(module-use! module (resolve-interface '(guix base32)))
module))
-(define (perform-download drv)
- "Perform the download described by DRV, a fixed-output derivation."
+(define (perform-download drv output)
+ "Perform the download described by DRV, a fixed-output derivation, to
+OUTPUT.
+
+Note: We don't read the value of 'out' in DRV since the actual output is
+different from that when we're doing a 'bmCheck' or 'bmRepair' build."
(derivation-let drv ((url "url")
- (output "out")
(executable "executable")
(mirrors "mirrors")
(content-addressed-mirrors "content-addressed-mirrors"))
@@ -93,18 +96,20 @@ of GnuTLS over HTTPS, before we have built GnuTLS. See
<http://bugs.gnu.org/22774>."
(with-error-handling
(match args
- (((? derivation-path? drv))
+ (((? derivation-path? drv) (? store-path? output))
;; This program must be invoked by guix-daemon under an unprivileged
;; UID to prevent things downloading from 'file:///etc/shadow' or
;; arbitrary code execution via the content-addressed mirror
;; procedures. (That means we exclude users who did not pass
;; '--build-users-group'.)
(assert-low-privileges)
- (perform-download (call-with-input-file drv read-derivation)))
+ (perform-download (call-with-input-file drv read-derivation)
+ output))
(("--version")
(show-version-and-exit))
(x
- (leave (_ "fixed-output derivation name expected~%"))))))
+ (leave
+ (_ "fixed-output derivation and output file name expected~%"))))))
;; Local Variables:
;; eval: (put 'derivation-let 'scheme-indent-function 2)
diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc
index 38048ceebc..cebc404d1c 100644
--- a/nix/libstore/build.cc
+++ b/nix/libstore/build.cc
@@ -2271,8 +2271,17 @@ void DerivationGoal::runChild()
logType = ltFlat;
auto buildDrv = lookupBuiltinBuilder(drv.builder);
- if (buildDrv != NULL)
- buildDrv(drv, drvPath);
+ if (buildDrv != NULL) {
+ /* Check what the output file name is. When doing a
+ 'bmCheck' build, the output file name is different from
+ that specified in DRV due to hash rewriting. */
+ Path output = drv.outputs["out"].path;
+ auto redirected = redirectedOutputs.find(output);
+ if (redirected != redirectedOutputs.end())
+ output = redirected->second;
+
+ buildDrv(drv, drvPath, output);
+ }
else
throw Error(format("unsupported builtin function '%1%'") % string(drv.builder, 8));
_exit(0);
@@ -2742,6 +2751,8 @@ Path DerivationGoal::addHashRewrite(const Path & path)
rewritesToTmp[h1] = h2;
rewritesFromTmp[h2] = h1;
redirectedOutputs[path] = p;
+ printMsg(lvlChatty, format("output '%1%' redirected to '%2%'")
+ % path % p);
return p;
}
diff --git a/nix/libstore/builtins.cc b/nix/libstore/builtins.cc
index 32af767dc4..7ed75e5079 100644
--- a/nix/libstore/builtins.cc
+++ b/nix/libstore/builtins.cc
@@ -1,5 +1,5 @@
/* GNU Guix --- Functional package management for GNU
- Copyright (C) 2016 Ludovic Courtès <ludo@gnu.org>
+ Copyright (C) 2016, 2017 Ludovic Courtès <ludo@gnu.org>
This file is part of GNU Guix.
@@ -25,7 +25,8 @@
namespace nix {
static void builtinDownload(const Derivation &drv,
- const std::string &drvPath)
+ const std::string &drvPath,
+ const std::string &output)
{
/* Invoke 'guix perform-download'. */
Strings args;
@@ -35,7 +36,10 @@ static void builtinDownload(const Derivation &drv,
/* Close all other file descriptors. */
closeMostFDs(set<int>());
- const char *const argv[] = { "download", drvPath.c_str(), NULL };
+ const char *const argv[] =
+ {
+ "download", drvPath.c_str(), output.c_str(), NULL
+ };
/* XXX: Hack our way to use the 'download' script from 'LIBEXECDIR/guix'
or just 'LIBEXECDIR', depending on whether we're running uninstalled or
diff --git a/nix/libstore/builtins.hh b/nix/libstore/builtins.hh
index 79171fcb6c..396ea14ebc 100644
--- a/nix/libstore/builtins.hh
+++ b/nix/libstore/builtins.hh
@@ -1,5 +1,5 @@
/* GNU Guix --- Functional package management for GNU
- Copyright (C) 2016 Ludovic Courtès <ludo@gnu.org>
+ Copyright (C) 2016, 2017 Ludovic Courtès <ludo@gnu.org>
This file is part of GNU Guix.
@@ -33,7 +33,8 @@ namespace nix {
/* Build DRV, which lives at DRVPATH. */
typedef void (*derivationBuilder) (const Derivation &drv,
- const std::string &drvPath);
+ const std::string &drvPath,
+ const std::string &output);
/* Return the built-in builder called BUILDER, or NULL if none was
found. */
diff --git a/tests/derivations.scm b/tests/derivations.scm
index 2b5aa796d4..3fbfec3793 100644
--- a/tests/derivations.scm
+++ b/tests/derivations.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -279,6 +279,27 @@
(build-derivations %store (list drv))
#f)))
+(unless (force %http-server-socket)
+ (test-skip 1))
+(test-assert "'download' built-in builder, check mode"
+ ;; Make sure rebuilding the 'builtin:download' derivation in check mode
+ ;; works. See <http://bugs.gnu.org/25089>.
+ (let* ((text (random-text))
+ (drv (derivation %store "world"
+ "builtin:download" '()
+ #:env-vars `(("url"
+ . ,(object->string (%local-url))))
+ #:hash-algo 'sha256
+ #:hash (sha256 (string->utf8 text)))))
+ (and (with-http-server 200 text
+ (build-derivations %store (list drv)))
+ (with-http-server 200 text
+ (build-derivations %store (list drv)
+ (build-mode check)))
+ (string=? (call-with-input-file (derivation->output-path drv)
+ get-string-all)
+ text))))
+
(test-equal "derivation-name"
"foo-0.0"
(let ((drv (derivation %store "foo-0.0" %bash '())))
@@ -1109,3 +1130,7 @@
(call-with-input-file out get-string-all))))
(test-end)
+
+;; Local Variables:
+;; eval: (put 'with-http-server 'scheme-indent-function 2)
+;; End: