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.
This commit is contained in:
parent
aa042770da
commit
9b5364a3af
|
@ -1,5 +1,5 @@
|
||||||
;;; GNU Guix --- Functional package management for GNU
|
;;; 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.
|
;;; This file is part of GNU Guix.
|
||||||
;;;
|
;;;
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
(define-module (guix scripts perform-download)
|
(define-module (guix scripts perform-download)
|
||||||
#:use-module (guix ui)
|
#:use-module (guix ui)
|
||||||
#:use-module (guix derivations)
|
#: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 (guix build download)
|
||||||
#:use-module (ice-9 match)
|
#:use-module (ice-9 match)
|
||||||
#:export (guix-perform-download))
|
#:export (guix-perform-download))
|
||||||
|
@ -41,10 +41,13 @@
|
||||||
(module-use! module (resolve-interface '(guix base32)))
|
(module-use! module (resolve-interface '(guix base32)))
|
||||||
module))
|
module))
|
||||||
|
|
||||||
(define (perform-download drv)
|
(define (perform-download drv output)
|
||||||
"Perform the download described by DRV, a fixed-output derivation."
|
"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")
|
(derivation-let drv ((url "url")
|
||||||
(output "out")
|
|
||||||
(executable "executable")
|
(executable "executable")
|
||||||
(mirrors "mirrors")
|
(mirrors "mirrors")
|
||||||
(content-addressed-mirrors "content-addressed-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>."
|
<http://bugs.gnu.org/22774>."
|
||||||
(with-error-handling
|
(with-error-handling
|
||||||
(match args
|
(match args
|
||||||
(((? derivation-path? drv))
|
(((? derivation-path? drv) (? store-path? output))
|
||||||
;; This program must be invoked by guix-daemon under an unprivileged
|
;; This program must be invoked by guix-daemon under an unprivileged
|
||||||
;; UID to prevent things downloading from 'file:///etc/shadow' or
|
;; UID to prevent things downloading from 'file:///etc/shadow' or
|
||||||
;; arbitrary code execution via the content-addressed mirror
|
;; arbitrary code execution via the content-addressed mirror
|
||||||
;; procedures. (That means we exclude users who did not pass
|
;; procedures. (That means we exclude users who did not pass
|
||||||
;; '--build-users-group'.)
|
;; '--build-users-group'.)
|
||||||
(assert-low-privileges)
|
(assert-low-privileges)
|
||||||
(perform-download (call-with-input-file drv read-derivation)))
|
(perform-download (call-with-input-file drv read-derivation)
|
||||||
|
output))
|
||||||
(("--version")
|
(("--version")
|
||||||
(show-version-and-exit))
|
(show-version-and-exit))
|
||||||
(x
|
(x
|
||||||
(leave (_ "fixed-output derivation name expected~%"))))))
|
(leave
|
||||||
|
(_ "fixed-output derivation and output file name expected~%"))))))
|
||||||
|
|
||||||
;; Local Variables:
|
;; Local Variables:
|
||||||
;; eval: (put 'derivation-let 'scheme-indent-function 2)
|
;; eval: (put 'derivation-let 'scheme-indent-function 2)
|
||||||
|
|
|
@ -2271,8 +2271,17 @@ void DerivationGoal::runChild()
|
||||||
logType = ltFlat;
|
logType = ltFlat;
|
||||||
|
|
||||||
auto buildDrv = lookupBuiltinBuilder(drv.builder);
|
auto buildDrv = lookupBuiltinBuilder(drv.builder);
|
||||||
if (buildDrv != NULL)
|
if (buildDrv != NULL) {
|
||||||
buildDrv(drv, drvPath);
|
/* 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
|
else
|
||||||
throw Error(format("unsupported builtin function '%1%'") % string(drv.builder, 8));
|
throw Error(format("unsupported builtin function '%1%'") % string(drv.builder, 8));
|
||||||
_exit(0);
|
_exit(0);
|
||||||
|
@ -2742,6 +2751,8 @@ Path DerivationGoal::addHashRewrite(const Path & path)
|
||||||
rewritesToTmp[h1] = h2;
|
rewritesToTmp[h1] = h2;
|
||||||
rewritesFromTmp[h2] = h1;
|
rewritesFromTmp[h2] = h1;
|
||||||
redirectedOutputs[path] = p;
|
redirectedOutputs[path] = p;
|
||||||
|
printMsg(lvlChatty, format("output '%1%' redirected to '%2%'")
|
||||||
|
% path % p);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* GNU Guix --- Functional package management for GNU
|
/* 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.
|
This file is part of GNU Guix.
|
||||||
|
|
||||||
|
@ -25,7 +25,8 @@
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
static void builtinDownload(const Derivation &drv,
|
static void builtinDownload(const Derivation &drv,
|
||||||
const std::string &drvPath)
|
const std::string &drvPath,
|
||||||
|
const std::string &output)
|
||||||
{
|
{
|
||||||
/* Invoke 'guix perform-download'. */
|
/* Invoke 'guix perform-download'. */
|
||||||
Strings args;
|
Strings args;
|
||||||
|
@ -35,7 +36,10 @@ static void builtinDownload(const Derivation &drv,
|
||||||
/* Close all other file descriptors. */
|
/* Close all other file descriptors. */
|
||||||
closeMostFDs(set<int>());
|
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'
|
/* XXX: Hack our way to use the 'download' script from 'LIBEXECDIR/guix'
|
||||||
or just 'LIBEXECDIR', depending on whether we're running uninstalled or
|
or just 'LIBEXECDIR', depending on whether we're running uninstalled or
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* GNU Guix --- Functional package management for GNU
|
/* 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.
|
This file is part of GNU Guix.
|
||||||
|
|
||||||
|
@ -33,7 +33,8 @@ namespace nix {
|
||||||
|
|
||||||
/* Build DRV, which lives at DRVPATH. */
|
/* Build DRV, which lives at DRVPATH. */
|
||||||
typedef void (*derivationBuilder) (const Derivation &drv,
|
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
|
/* Return the built-in builder called BUILDER, or NULL if none was
|
||||||
found. */
|
found. */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
;;; GNU Guix --- Functional package management for GNU
|
;;; 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.
|
;;; This file is part of GNU Guix.
|
||||||
;;;
|
;;;
|
||||||
|
@ -279,6 +279,27 @@
|
||||||
(build-derivations %store (list drv))
|
(build-derivations %store (list drv))
|
||||||
#f)))
|
#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"
|
(test-equal "derivation-name"
|
||||||
"foo-0.0"
|
"foo-0.0"
|
||||||
(let ((drv (derivation %store "foo-0.0" %bash '())))
|
(let ((drv (derivation %store "foo-0.0" %bash '())))
|
||||||
|
@ -1109,3 +1130,7 @@
|
||||||
(call-with-input-file out get-string-all))))
|
(call-with-input-file out get-string-all))))
|
||||||
|
|
||||||
(test-end)
|
(test-end)
|
||||||
|
|
||||||
|
;; Local Variables:
|
||||||
|
;; eval: (put 'with-http-server 'scheme-indent-function 2)
|
||||||
|
;; End:
|
||||||
|
|
Loading…
Reference in New Issue