Add support for Guile & Guix.
[?]
Aug 16, 2012, 5:07 PM
QMW24O5S43MYF5ZTBULUEZNDW2FKJ3QP2GL46P6B2SVGSQLVEACACDependencies
- [2]
R4MHON3Opass svn/bzr revisions as integers - [3]
KNJTTZ3ZPass the abbreviated Git revision - [4]
HQGXL4MXAdd validation for project and jobset names - [5]
INNOEHO6* Fix getBuildLog for bzip2'd files. - [6]
PXUCXYZI* Pass `-j 1' to hydra_eval_jobs to ensure that it can make progress - [7]
CHQEG6WYHydra/29: Added timeout to svn/git checkouts, job evaluation - [8]
BTOXLRG3* Record the input containing the Nix expression (release.nix) in the - [9]
LZO3C2KI* Hack around those SQLite timeouts: just retry the transaction. - [10]
5SHCWE7X* Prevent repeated evaluation of a jobset with the same inputs. This - [11]
FDE3BJAP* Refactoring. - [12]
SM5M2J3APass inputs to release expressions using -I - [13]
POPU2ATH* hydra_scheduler: use eval-jobs. - [14]
RFE6T5LG* Store jobset evaluations in the database explicitly. This includes - [15]
PDZD5QORhydra-evaluator: handle the case where there is no previous jobset eval - [16]
P5XCKTFDFix sysbuild input type handling - [17]
WRIU3S5E* UI for cloning builds (not functional yet). - [18]
OOQ2D3KC* Refactoring: move fetchInput out of hydra_scheduler into a separate - [19]
3XTHEUMP* Implemented the clone feature. - [20]
YFPZ46YK* hydra: added variant of build input type, 'build output (same system)' to allow better continous integration in one jobset for multiple system. it makes sure that the system of the build that is passed as input for a job has the same system as the job. - [21]
X27GNHDV* Basic job info in the database. - [22]
2WRTOU2ZCleanup - [23]
4FWDVNWAPass additional attributes for Git inputs - [24]
KN3VYE5P* Cleaned up the foreign key constraints. - [25]
2WUNXJGWHydra/26: Go back to using "svn export" as default for svn, added svn-checkout type for jobset which need .svn dirs. export is much more efficient - [26]
RXVJFQ5AEvaluator cleanups - [27]
JOYONH2KPrevent multiple builds with the same (job, outPath) tuple from being added - [28]
DDMYFZ5XFix the jobset unchanged check - [29]
O25D52TAinitial support for mercurial - [30]
ARD6Z67TDo incremental SVN checkouts - [31]
2YXO5ZGQHydra/28: Rename "scheduler" to "evaluator" - [32]
BSOLESYK* hydra: project members can do stuff that the owner can do - [33]
WVX47J4Eproperly pass bazaar inputs - [34]
PIMGMGAFRename hydra_eval_jobs to hydra-eval-jobs - [35]
JTRG7RDQadd support for git as jobinput - [*]
FV2M6MOThydra: use autoconf/-make - [*]
M3A5PZIHhydra: Clarify the dependency on BDW-GC. - [*]
FAIJDQKZ - [*]
LBNVQXUB* Build the /build stuff in a separate controller. - [*]
3HZY24CX* Make jobsets viewable under - [*]
ODNCGFQ5* Improved the navigation bar: don't include all projects (since that - [*]
FPK5LF53* Put the project-related actions in a separate controller. Put the - [*]
L4AI5YL6Rename hydra_*.pl to hydra-* - [*]
D5QIOJGP* Move everything up one directory. - [*]
N22GPKYT* Put info about logs / build products in the DB. - [*]
3ZCEPLNO
Change contents
- edit in configure.ac at line 78
PKG_CHECK_MODULES([GUILE], [guile-2.0], [HAVE_GUILE=yes], [HAVE_GUILE=no]) - edit in src/lib/Hydra/Controller/Build.pm at line 466
# When the expression is in a .scm file, assume it's a Guile + Guix# build expression.my $exprType =$c->request->params->{"nixexprpath"} =~ /.scm$/ ? "guile" : "nix"; - replacement in src/lib/Hydra/Controller/Build.pm at line 496
my ($jobs, $nixExprInput) = evalJobs($inputInfo, $nixExprInputName, $nixExprPath);my ($jobs, $nixExprInput) = evalJobs($inputInfo, $exprType, $nixExprInputName, $nixExprPath); - edit in src/lib/Hydra/Controller/Jobset.pm at line 226
# When the expression is in a .scm file, assume it's a Guile + Guix# build expression.my $exprType =$c->request->params->{"nixexprpath"} =~ /.scm$/ ? "guile" : "nix"; - edit in src/lib/Hydra/Controller/Project.pm at line 149
my $exprType =$c->request->params->{"nixexprpath"} =~ /.scm$/ ? "guile" : "nix"; - edit in src/lib/Hydra/Helper/AddBuilds.pm at line 644
}sub booleanToString {my ($exprType, $value) = @_;my $result;if ($exprType eq "guile") {if ($value eq "true") {$result = "#t";} else {$result = "#f";}$result = $value;} else {$result = $value;}return $result; - edit in src/lib/Hydra/Helper/AddBuilds.pm at line 663
sub buildInputToString {my ($exprType, $input) = @_;my $result;if ($exprType eq "guile") {$result = "'((file-name . \"" . ${input}->{storePath} . "\")" .(defined $input->{revision} ? "(revision . \"" . $input->{revision} . "\")" : "") .(defined $input->{revCount} ? "(revision-count . " . $input->{revCount} . ")" : "") .(defined $input->{gitTag} ? "(git-tag . \"" . $input->{gitTag} . "\")" : "") .(defined $input->{shortRev} ? "(short-revision . \"" . $input->{shortRev} . "\")" : "") .(defined $input->{version} ? "(version . \"" . $input->{version} . "\")" : "") .")";} else {$result = "{ outPath = builtins.storePath " . $input->{storePath} . "" .(defined $input->{revision} ? "; rev = \"" . $input->{revision} . "\"" : "") .(defined $input->{revCount} ? "; revCount = " . $input->{revCount} . "" : "") .(defined $input->{gitTag} ? "; gitTag = \"" . $input->{gitTag} . "\"" : "") .(defined $input->{shortRev} ? "; shortRev = \"" . $input->{shortRev} . "\"" : "") .(defined $input->{version} ? "; version = \"" . $input->{version} . "\"" : "") .";}";}return $result;} - replacement in src/lib/Hydra/Helper/AddBuilds.pm at line 687
my ($inputInfo) = @_;my ($inputInfo, $exprType) = @_; - replacement in src/lib/Hydra/Helper/AddBuilds.pm at line 700
push @res, "--arg", $input, $alt->{value};push @res, "--arg", $input, booleanToString($exprType, $alt->{value}); - replacement in src/lib/Hydra/Helper/AddBuilds.pm at line 703[2.68]→[6.1840:2074](∅→∅),[6.114]→[6.1840:2074](∅→∅),[6.553]→[6.1840:2074](∅→∅),[6.1709]→[6.1840:2074](∅→∅),[6.2668]→[6.1840:2074](∅→∅),[6.2766]→[6.1840:2074](∅→∅),[6.1840]→[6.1840:2074](∅→∅),[6.2074]→[6.487:685](∅→∅),[6.685]→[3.324:428](∅→∅),[3.428]→[6.2074:2227](∅→∅),[6.685]→[6.2074:2227](∅→∅),[6.2074]→[6.2074:2227](∅→∅)
push @res, "--arg", $input, ("{ outPath = builtins.storePath " . $alt->{storePath} . "" .(defined $alt->{revision} ? "; rev = \"" . $alt->{revision} . "\"" : "") .(defined $alt->{revCount} ? "; revCount = " . $alt->{revCount} . "" : "") .(defined $alt->{gitTag} ? "; gitTag = \"" . $alt->{gitTag} . "\"" : "") .(defined $alt->{shortRev} ? "; shortRev = \"" . $alt->{shortRev} . "\"" : "") .(defined $alt->{version} ? "; version = \"" . $alt->{version} . "\"" : "") .";}");push @res, "--arg", $input, buildInputToString($exprType, $alt); - replacement in src/lib/Hydra/Helper/AddBuilds.pm at line 745
my ($inputInfo, $nixExprInputName, $nixExprPath) = @_;my ($inputInfo, $exprType, $nixExprInputName, $nixExprPath) = @_; - edit in src/lib/Hydra/Helper/AddBuilds.pm at line 753
my $evaluator = ($exprType eq "guile") ? "hydra-eval-guile-jobs" : "hydra-eval-jobs";print STDERR "evaluator ${evaluator}\n"; - replacement in src/lib/Hydra/Helper/AddBuilds.pm at line 757
("hydra-eval-jobs", $nixExprFullPath, "--gc-roots-dir", getGCRootsDir, "-j", 1, inputsToArgs($inputInfo)));($evaluator, $nixExprFullPath, "--gc-roots-dir", getGCRootsDir, "-j", 1, inputsToArgs($inputInfo, $exprType))); - edit in src/script/Makefile.am at line 9
hydra-eval-guile-jobs \ - file addition: hydra-eval-guile-jobs[45.2543]
#!/bin/sh# Aside from this initial boilerplate, this is actually -*- scheme -*- code.main="(module-ref (resolve-interface '(hydra-eval-guile-jobs)) 'eval-guile-jobs)"# Make sure no undeclared dependency is leaked. Guix has to be# provided as an input through Hydra. Guix itself must thus be built via a# recipe written in the Nix language.unset GUILE_LOAD_PATHunset GUILE_LOAD_COMPILED_PATHexec ${GUILE:-guile} --no-auto-compile \-l "$0" -c "(apply $main (cdr (command-line)))" "$@"!#;;; Copyright (C) 2012 Ludovic Courtès <ludo@gnu.org>;;;;;; Hydra 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.;;;;;; Hydra 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 Hydra. If not, see <http://www.gnu.org/licenses/>.(define-module (hydra-eval-guile-jobs)#:use-module (sxml simple)#:use-module (ice-9 match)#:use-module (ice-9 regex)#:use-module (srfi srfi-1)#:use-module (srfi srfi-11)#:export (job-evaluations->xmleval-guile-jobs))(define (guix-variable module name)"Dynamically link variable NAME under Guix module MODULE and return it.Note: this is used instead of `@', because when using `@' in an uncompiledfile, Guile tries to load the module directly as it reads the source, whichfails in our case, leading to the creation of empty (guix ...) modules.";; TODO: fail with an XML error description(let ((m (resolve-interface `(guix ,module))))(module-ref m name)))(define (%derivation-system drv);; XXX: Awful hack to workaround the fact that `derivation-system', which;; is a macro, cannot be referred to dynamically.(struct-ref drv 3))(define strip-store-path(let ((store-path-rx(make-regexp "^.*/nix/store/[^-]+-(.+)$")))(lambda (path)(or (and=> (regexp-exec store-path-rx path)(lambda (match)(let ((path (match:substring match 1)))path)))path))))(define (derivation-path->name drv)"Return the base name of DRV, sans hash and `.drv' extension."(let ((d (strip-store-path drv)))(if (string-suffix? ".drv" d)(string-drop-right d 4)d)))(define (job-evaluations->sxml jobs)"Return the hydra-eval-jobs SXML form for the result of JOBS, a list ofsymbol/thunk pairs."`(*TOP*(*PI* xml "version='1.0' encoding='utf-8'")"\n"(jobs "\n",@(map (match-lambda(((? symbol? name) . (? thunk? thunk))(let* ((result (save-module-excursion(lambda ()(set-current-module %user-module)(with-output-to-port (%make-void-port "w")thunk))))(drv (assoc-ref result 'derivation)))(define (opt-attr xml-name name)(match (assoc name result)((_ . value)`((,xml-name ,value)))(_'())));; XXX: Add <arg ...> tags?`(job (@ (jobName ,name)(drvPath ,drv)(outPath;; Resolve Guix modules lazily.,((guix-variable 'derivations'derivation-path->output-path)drv)),@(opt-attr 'homepage 'home-page),@(opt-attr 'license 'license),@(opt-attr 'description 'description),@(opt-attr 'longDescription 'long-description)(maintainers,(string-join (or (assoc-ref result 'maintainers)'())", "))(maxSilent,(number->string (or (assoc-ref result'max-silent-time)3600)))(timeout,(number->string (or (assoc-ref result 'timeout)7200)))(nixName ,(derivation-path->name drv))(schedulingPriority,(number->string (or (assoc-ref result'scheduling-priority)10)))(system,(call-with-input-file drv(compose %derivation-system(guix-variable 'derivations'read-derivation)))))"\n"))))jobs))))(define (job-evaluations->xml jobs port)(set-port-encoding! port "UTF-8")(sxml->xml (job-evaluations->sxml jobs) port));;;;;; Command-line entry point.;;;(define (parse-arguments args)"Traverse ARGS, a list of command-line arguments compatible with`hydra-eval-jobs', and return the name of the file that defines the jobs, anexpression that returns the entry point in that file (a unary procedure), thelist of name/value pairs passed to that entry point, as well as a GC rootdirectory or #f."(define (module-directory dir)(let ((d (string-append dir "/share/guile/site/2.0")))(if (file-exists? d)ddir)))(let loop ((args args)(result '())(file #f)(entry 'hydra-jobs)(roots-dir #f))(match args(()(if (not file)(error "hydra-eval-guile-jobs: no expression file given")(values file entry (reverse result) roots-dir)))(("-I" name=dir rest ...)(let* ((dir (match (string-tokenize name=dir(char-set-complement (char-set#\=)))((_ dir) dir)((dir) dir)))(dir* (module-directory dir)))(format (current-error-port) "adding `~a' to the load path~%" dir*)(set! %load-path (cons dir* %load-path))(set! %load-compiled-path (cons dir* %load-compiled-path)))(loop rest result file entry roots-dir))(("--argstr" name value rest ...)(loop rest (alist-cons (string->symbol name) value result)file entry roots-dir))(("--arg" name expr rest ...)(let ((value (eval (call-with-input-string expr read)(current-module))))(loop rest (alist-cons (string->symbol name) value result)file entry roots-dir)))(("--gc-roots-dir" dir rest ...)(loop rest result file entry dir))(("-j" _ rest ...) ; XXX: what's this?(loop rest result file entry roots-dir))(("--entry" expr rest ...) ; entry point, like `guile -e'(let ((expr (call-with-input-string expr read)))(loop rest result file expr roots-dir)))((file rest ...) ; source file that defines the jobs(loop rest result file entry roots-dir))(_(error "hydra-eval-guile-jobs: invalid arguments" args)))))(define %user-module;; Hydra user module.;; TODO: Make it a sandbox.(let ((m (make-module)))(beautify-user-module! m)m))(define (eval-guile-jobs . args)(setlocale LC_ALL "")(let-values (((file entry args gc-roots-dir)(parse-arguments args)))(save-module-excursion(lambda ()(set-current-module %user-module);; The standard output must contain only XML.(with-output-to-port (%make-void-port "w")(lambda ()(primitive-load file)))))(let* ((entry (eval entry %user-module))(store ((guix-variable 'store 'open-connection)))(jobs (entry store args)))(job-evaluations->xml jobs (current-output-port))))) - edit in src/script/hydra-evaluator at line 103[6.3692][47.2021]
my $exprType = $jobset->nixexprpath =~ /.scm$/ ? "guile" : "nix"; - replacement in src/script/hydra-evaluator at line 113
my @args = ($jobset->nixexprinput, $jobset->nixexprpath, inputsToArgs($inputInfo));my @args = ($jobset->nixexprinput, $jobset->nixexprpath, inputsToArgs($inputInfo, $exprType)); - replacement in src/script/hydra-evaluator at line 126
my ($jobs, $nixExprInput) = evalJobs($inputInfo, $jobset->nixexprinput, $jobset->nixexprpath);my ($jobs, $nixExprInput) = evalJobs($inputInfo, $exprType, $jobset->nixexprinput, $jobset->nixexprpath); - replacement in src/sql/hydra.sql at line 52
nixExprInput text not null, -- name of the jobsetInput containing the Nix expressionnixExprPath text not null, -- relative path of the Nix expressionnixExprInput text not null, -- name of the jobsetInput containing the Nix or Guix expressionnixExprPath text not null, -- relative path of the Nix or Guix expression