X6Y72FHOSRZA5RM5NOEUIJNJ5DIGBSXYJZENUXH45W3OKYIVUMMAC FIWFPVURRED7UXTYJYAX3ZS77FROKIAFUGC5VK7DFINWWCHO2GQQC AVU7BQ7WFER5ADSYQDHZVTVPSJPQYFRIHZ7CWTSEEHYIKALXJMSAC 5WCR3MKUB62I4B27L6LQGOX7UMDABRZZYFD6KMPS3H5NN54QR2HQC MTH54QGHQBKKQPHCAT64TRP4P5COYGNEYPYTQWPADTFXZB3WPLDAC AUFJYCESTQOINIBMZZI53Y6HJUTMIPRXQUS67UIX456ZCYDA7SNQC CPMO4LIVLJU7ECSD5RGEASCAVWXGOEZJXK5QV5537YUVA45YK2YQC GZI3X3IWTCO3G5YOUKEUF3PMPWRTJDGVZ7NAYCDYY4GCMO2T5PQAC 72DKPSKU7ZANRFNLBA2R3T5VUWMH2EMLWPK3EENQL2GEFPW4M2VAC 3VYGFEHJJXQQYJX2DZTYE6CPHZ23COROFFKK7VXV2IATNMJQGPZAC N74SRHS6XG3M4II7HDCJZKFF6RFXEVGBUN3DN4FUEMELHYCGMHLQC BCFAS6VOEDLANURVQYMHK4FQY5JMBD6U2KMRZKS2T73LBP4T3QIAC BZ7R536TG57J2BQ46FCV4TBSQPFODY7VACT3KW5J2IYKGTYUMURQC 6A6CZ7SC2VGEGRC5LSNTDDM3LFWVYO6Z6QNDF74SBJWO5P6T3ARQC SPGPFOT4D27K7RRUQKVNYSUKA4TER3FXGGFSYEUUANXP2OT4MTZAC X7IAG7JTV4W6JH34JBC6KOVUGBAG643V4Y5MX4GTJL2BV5PP5VIQC 5AKAE3R6RZMDWN2UMNYCB73Z2FEE5WJUCEY4YAAOHGAKHVJQPO7QC CPQQFQMZ3W7ISBF6L6WP2BWQYUZ6HQQI2VANQNRRBWT6JRIKR3KAC DWQCLOPQCZENDPZ3JKIL4T2XU3IPT5BU6VKTOMS3PXZDUL3KDZSQC 3PNG7NIBQQURUUPRVQXYL342OT7JUUYOMY2JJNP6YDX7SYJDZMYAC PKE6I67S7TDGKEFCKIQZOZ5PSDZXCSPOQGSKDAE5NST3NOOLRUXAC GRMV5GEWXL5HRCQ5AST22ATEPO3VNF4TSJWLYT3J5GPCM2CGRK4AC KBW3FDZ2PK7YCH3ICSHFWP22CWXYAXIPULP6LEN3S3K22UT4WSVQC GYPHTT4MZS75JYMQES2DZPV2D47EJW5HTQWYWDYXE7YJ6FFHPAYAC EKNK5AHQNJDKGLFPEX6CQXNPVIOWX3JXEP2H5YUZ4UFWCZ3HEJLQC 6ZHQKBZP3ZWFXEGYR3TYRQANRLVO6PBM7X5DK6Z7JMNMPY6A6Z7AC IUMG7IKREGB65LQUIP3XHRE4LPEZQTPGZC5MGXBVOPJ4RQIFWSKQC AMFMXR52JXHUOWWG4VZ5DHQGLF4F7H7XSJRLX5XNEXOCCWYLDQOAC UXRNODRJJU7A33F4PG24WOHKTJFI3XQMZGT2MUOBRAH2MPQ7NZ2AC W5GW4E225F3CYJQXFPKJ5W5O2E73U6ZGWFL2N3GS2LKJX2RTGYDQC HN7JDKV3DG4KYJHD6YWWRWGCNLUJQFI7EHRQBXZXWOM4QFGH275AC RCKZG7CANDEQNOMY5CCDMWL6RMDGZOYJNKKONE77JEAM27VQ7T6QC XHOZT4WTBN3Y7Q2MBANFS65X4HYL6SGPA7JNB7T7OD726SU2ACWAC A6EKITA6BJRM4PDOT5GDTN6EKVFFD2S4AFJWKMIKEB7NKN52ZJ2AC 3463ZP55AVXWRCCITGBFGBZ6NQ5ZRNAUK4H3PZVSWFJEER5ZXXTQC VDT6CUITZL2M3DSFHKAD7VYSW354AU4GDMJ7PWTFLTPUCFKTJSZAC 75BCCX2TABRXQFYV73D6QU3VCT7LZUZEOWUK4X5USPWWTBTVJTLQC 2LTNY56W6QEDRSI6IWRZGQPTJTAFQSGIQO6FBTU7M4VQCTF6OVNAC YKD7OW6TMFSUWBTWBMVCVFVHIOTTAUPVLK23MXE4GZUOWEYCKWJQC W4LDVLQFV4NARA2L7OY6X2DIO4IDGBFK72L2HSB52WGA6EGM5FDQC NXO2ZIBUSCY5RSM6IFVU2PDHM3X66F3TH6PI6DSJGUQ3DTBJEWRAC MULEHDQKGUFOKRDVFJY5A7UOPMLT32LMF2UXW6VJEDJWEY47PDPAC EE53ECTSDLDTGK6RHSEZHZ42FKK2IIEMXQM5ZMDTQNFWZLR4RAIQC LW755CJKCIPO7NR7D5TP5WZNGCP5UWLBMA7KJXMHJEB6XIJJGO3QC <appendix xmlns="http://docbook.org/ns/docbook"xmlns:xlink="http://www.w3.org/1999/xlink"xml:id="chap-hacking"><title>Hacking</title><para>This section provides some notes on how to hack on Hydra. Toget the latest version of Hydra from GitHub:<screen>$ git clone git://github.com/NixOS/hydra.git$ cd hydra</screen></para><para>To build it and its dependencies:<screen>$ nix-build release.nix -A build.x86_64-linux</screen></para><para>To build all dependencies and start a shell in which allenvironment variables (such as <envar>PERL5LIB</envar>) are set up sothat those dependencies can be found:<screen>$ nix-shell</screen>To build Hydra, you should then do:<screen>[nix-shell]$ ./bootstrap[nix-shell]$ configurePhase[nix-shell]$ make</screen>You can run the Hydra web server in your source tree as follows:<screen>$ ./src/script/hydra-server</screen></para></appendix>
<book xmlns="http://docbook.org/ns/docbook"xmlns:xi="http://www.w3.org/2001/XInclude"><info><title>Hydra User's Guide</title><subtitle>Draft</subtitle><authorgroup><author><personname><firstname>Eelco</firstname><surname>Dolstra</surname></personname><affiliation><orgname>Delft University of Technology</orgname><orgdiv>Department of Software Technology</orgdiv></affiliation><contrib>Author</contrib></author><author><personname><firstname>Rob</firstname><surname>Vermaas</surname></personname><affiliation><orgname>Delft University of Technology</orgname><orgdiv>Department of Software Technology</orgdiv></affiliation><contrib>Author</contrib></author><author><personname><firstname>Eelco</firstname><surname>Visser</surname></personname><affiliation><orgname>Delft University of Technology</orgname><orgdiv>Department of Software Technology</orgdiv></affiliation><contrib>Author</contrib></author><author><personname><firstname>Ludovic</firstname><surname>Courtès</surname></personname><contrib>Author</contrib></author></authorgroup><copyright><year>2009-2013</year><holder>Eelco Dolstra</holder></copyright><date>March 2010</date></info><xi:include href="introduction.xml" /><xi:include href="installation.xml" /><xi:include href="projects.xml" /><xi:include href="api.xml" /><xi:include href="hacking.xml" /></book>
<chapter xmlns="http://docbook.org/ns/docbook"xmlns:xlink="http://www.w3.org/1999/xlink"xml:id="chap-installation"><para>This chapter explains how to install Hydra on your own build farm server.</para><section><title>Prerequisites</title><para>To install and use Hydra you need to have installed the following dependencies:<itemizedlist><listitem><para>Nix</para></listitem><listitem><para>PostgreSQL</para></listitem><listitem><para>many Perl packages, notably Catalyst, EmailSender,and NixPerl (see the <linkxlink:href="https://github.com/NixOS/hydra/blob/master/release.nix">Hydraexpression in Nixpkgs</link> for the completelist)</para></listitem></itemizedlist>At the moment, Hydra runs only on GNU/Linux(<emphasis>i686-linux</emphasis> and<emphasis>x86_64_linux</emphasis>).</para><para>For small projects, Hydra can be run on any reasonably modernmachine. For individual projects you can even run Hydra on alaptop. However, the charm of a buildfarm server is usually thatit operates without disturbing the developer's workingenvironment and can serve releases over the internet. Inconjunction you should typically have your source codeadministered in a version management system, such assubversion. Therefore, you will probably want to install aserver that is connected to the internet. To scale up to largeand/or many projects, you will need at least a considerableamount of diskspace to store builds. Since Hydra can schedulemultiple simultaneous build jobs, it can be useful to have amulti-core machine, and/or attach multiple build machines in anetwork to the central Hydra server.</para><para>Of course we think it is a good idea to use the <linkxlink:href="http://nixos.org/nixos">NixOS</link> GNU/Linuxdistribution for your buildfarm server. But this is not arequirement. The Nix software deployment system can beinstalled on any GNU/Linux distribution in parallel to theregular package management system. Thus, you can use Hydra on aDebian, Fedora, SuSE, or Ubuntu system.</para></section><section><title>Getting Nix</title><para>If your server runs NixOS you are all set to continue withinstallation of Hydra. Otherwise you first need to install Nix.The latest stable version can be found one <linkxlink:href="http://nixos.org/nix/download.html">the Nix website</link>, along with a manual, which includes installationinstructions.</para></section><section><title>Installation</title><para>Hydra can be installed using Nixpkgs:<screen>nix-env -f /path/to/nixpkgs -iA hydra</screen>This makes the tools available in your Nix user environment,<literal>$HOME/.nix-profile</literal> by default.</para>--><para>The latest development snapshot of Hydra can be installedby visiting the URL <linkxlink:href="http://hydra.nixos.org/view/hydra/unstable"><literal>http://hydra.nixos.org/view/hydra/unstable</literal></link>and using the one-click install available at one of the buildpages. You can also install Hydra through the channel byperforming the following commands:<screen>nix-channel --add http://hydra.nixos.org/jobset/hydra/master/channel/latestnix-channel --updatenix-env -i hydra</screen></para><para>Command completion should reveal a number of command-line toolsfrom Hydra, such as <command>hydra-queue-runner</command>.</para></section><section><title>Creating the database</title><para>Hydra stores its results in a PostgreSQL database.</para><para>To setup a PostgreSQL database with <emphasis>hydra</emphasis>as database name and user name, issue the following commands onthe PostgreSQL server:<screen>createuser -S -D -R -P hydracreatedb -O hydra hydra</screen>Note that <emphasis>$prefix</emphasis> is the location of Hydrain the nix store.</para><para>Hydra uses an environment variable to know which database shouldbe used, and a variable which point to a location that holdssome state. To set these variables for a PostgreSQL database,add the following to the file <filename>~/.profile</filename> ofthe user running the Hydra services.<screen>export HYDRA_DBI="dbi:Pg:dbname=hydra;host=dbserver.example.org;user=hydra;"export HYDRA_DATA=/var/lib/hydra</screen>You can provide the username and password in the file<filename>~/.pgpass</filename>, e.g.<screen>dbserver.example.org:*:hydra:hydra:password</screen>Make sure that the <emphasis>HYDRA_DATA</emphasis> directoryexists and is writable for the user which will run the Hydraservices.</para><para>Having set these environment variables, you can now initialisethe database by doing:<screen>hydra-init</screen></para><para>To create projects, you need to create a user with<emphasis>admin</emphasis> privileges. This can be done usingthe command <command>hydra-create-user</command>:<screen>$ hydra-create-user alice --full-name 'Alice Q. User' \--email-address 'alice@example.org' --password foobar --role admin</screen>Additional users can be created through the web interface.</para></section><section><title>Upgrading</title><screen>hydra-init</screen></para></section><section><title>Getting Started</title><para>To start the Hydra web server, execute:<screen>hydra-server</screen>When the server is started, you can browse to<ulink>http://localhost:3000/</ulink> to start configuringyour Hydra instance.</para><para>The <command>hydra-server</command> command launches the webserver. There are two other processes that come into play:<itemizedlist><listitem>The <emphasis>evaluator</emphasis> is responsible forperiodically evaluating job sets, checking out theirdependencies off their version control systems (VCS), andqueueing new builds if the result of the evaluation changed.It is launched by the <command>hydra-evaluator</command>command.</listitem><listitem>The <emphasis>queue runner</emphasis> launches builds (usingNix) as they are queued by the evaluator, scheduling themonto the configured Nix hosts. It is launched using the<command>hydra-queue-runner</command> command.</listitem></itemizedlist>All three processes must be running for Hydra to be fullyfunctional, though it's possible to temporarily stop any one ofthem for maintenance purposes, for instance.</para></section><section><title> Serving behind reverse proxy </title><para>To serve hydra web server behind reverse proxy like<emphasis>nginx</emphasis> or <emphasis>httpd</emphasis> someadditional configuration must be made.</para><para>Edit your <literal>hydra.conf</literal> file in a similar way tothis example:<screen>using_frontend_proxy 1base_uri example.com</screen><literal>base_uri</literal> should be your hydra servers proxied URL.If you are using Hydra nixos module then setting <literal>hydraURL</literal>option should be enough.</para><para>If you want to serve Hydra with a prefix path, for example<ulink>http://example.com/hydra</ulink> then you need to configure yourreverse proxy to pass <literal>X-Request-Base</literal> to hydra, withprefix path as value.For example if you are using nginx, then use configuration similar to following:<screen>server {listen 433 ssl;server_name example.com;.. other configuration ..location /hydra/ {proxy_pass http://127.0.0.1:3000;proxy_redirect http://127.0.0.1:3000 https://example.com/hydra;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;proxy_set_header X-Request-Base /hydra;}}</screen></para></section></chapter><!--Local Variables:indent-tabs-mode: nilispell-local-dictionary: "american"End:--><screen>credential:class: Passwordpassword_field: passwordpassword_type: self_checkstore:class: LDAPldap_server: localhostldap_server_options.timeout: 30binddn: "cn=root,dc=example"bindpw: notapasswordstart_tls: 0start_tls_optionsverify: noneuser_basedn: "ou=users,dc=example"user_filter: "(&(objectClass=inetOrgPerson)(cn=%s))"user_scope: oneuser_field: cnuser_search_options:deref: alwaysuse_roles: 1role_basedn: "ou=groups,dc=example"role_filter: "(&(objectClass=groupOfNames)(member=%s))"role_scope: onerole_field: cnrole_value: dnrole_search_options:deref: always</screen><para>Roles can be assigned to users based on their LDAP group membership(<emphasis>use_roles: 1</emphasis> in the below example).For a user to have the role <emphasis>admin</emphasis> assigned to themthey should be in the group <emphasis>hydra_admin</emphasis>. In generalany LDAP group of the form <emphasis>hydra_some_role</emphasis>(notice the <emphasis>hydra_</emphasis> prefix) will work.</para></section><section><title>Using LDAP as authentication backend (optional)</title><para>Instead of using Hydra's built-in user management you can optionally use LDAP to manage roles and users.</para><para>The <command>hydra-server</command> accepts the environmentvariable <emphasis>HYDRA_LDAP_CONFIG</emphasis>. The value ofthe variable should point to a valid YAML file containing theCatalyst LDAP configuration. The format of the configurationfile is describe in the<link xlink:href="https://metacpan.org/pod/Catalyst::Authentication::Store::LDAP#CONFIGURATION-OPTIONS"><emphasis>Catalyst::Authentication::Store::LDAP</emphasis> documentation</link>.An example is given below.</para><para>If you're upgrading Hydra from a previous version, youshould do the following to perform any necessary database schema migrations:<!--<title>Installation</title>
<section xmlns="http://docbook.org/ns/docbook"xmlns:xlink="http://www.w3.org/1999/xlink"xml:id="sec-declarative-projects"><programlisting language="json">{"nixpkgs": {"enabled": 1,"hidden": false,"description": "Nixpkgs","nixexprinput": "nixpkgs","nixexprpath": "pkgs/top-level/release.nix","checkinterval": 300,"schedulingshares": 100,"enableemail": false,"emailoverride": "","keepnr": 3,"inputs": {"nixpkgs": {"type": "git","value": "git://github.com/NixOS/nixpkgs.git master","emailresponsible": false}}},"nixos": {"enabled": 1,"hidden": false,"description": "NixOS: Small Evaluation","nixexprinput": "nixpkgs","nixexprpath": "nixos/release-small.nix","checkinterval": 300,"schedulingshares": 100,"enableemail": false,"emailoverride": "","keepnr": 3,"inputs": {"nixpkgs": {"type": "git","value": "git://github.com/NixOS/nixpkgs.git master","emailresponsible": false}}}}</programlisting></para></listitem><listitem><para>Create a new project, and set the project's declarative input type,declarative input value, and declarative spec file to point to thesource and JSON file you created in step 2.</para></listitem></orderedlist><para>Hydra will create a special jobset named <literal>.jobsets</literal>.When the <literal>.jobsets</literal> jobset is evaluated, this staticspecification will be used for configuring the rest of the project'sjobsets.</para></section><section xml:id="sec-generated-declarative-projects"><title>Generated, Declarative Projects</title><para>Hydra also supports generated declarative projects, where jobsets areconfigured automatically from specification files instead of beingmanaged through the UI. A jobset specification is a JSON objectcontaining the configuration of the jobset, for example:</para><programlisting language="json">{"enabled": 1,"hidden": false,"description": "js","nixexprinput": "src","nixexprpath": "release.nix","checkinterval": 300,"schedulingshares": 100,"enableemail": false,"emailoverride": "","keepnr": 3,"inputs": {"src": { "type": "git", "value": "git://github.com/shlevy/declarative-hydra-example.git", "emailresponsible": false },"nixpkgs": { "type": "git", "value": "git://github.com/NixOS/nixpkgs.git release-16.03", "emailresponsible": false }}}</programlisting><para>To configure a declarative project, take the following steps:</para><orderedlist numeration="arabic" spacing="compact"><listitem><para>Create a jobset repository in the normal way (e.g. a git repo witha <literal>release.nix</literal> file, any other needed helperfiles, and taking any kind of hydra input), but without adding itto the UI. The nix expression of this repository should contain asingle job, named <literal>jobsets</literal>. The output of the<literal>jobsets</literal> job should be a JSON file containing anobject of jobset specifications. Each member of the object willbecome a jobset of the project, configured by the correspondingjobset specification.</para></listitem><listitem><para>In some hydra-fetchable source (potentially, but not necessarily,the same repo you created in step 1), create a JSON filecontaining a jobset specification that points to the jobsetrepository you created in the first step, specifying any neededinputs (e.g. nixpkgs) as necessary.</para></listitem><listitem><para>In the project creation/edit page, set declarative input type,declarative input value, and declarative spec file to point to thesource and JSON file you created in step 2.</para></listitem></orderedlist><para>Hydra will create a special jobset named <literal>.jobsets</literal>,which whenever evaluated will go through the steps above in reverseorder:</para><orderedlist numeration="arabic" spacing="compact"><listitem><para>Hydra will fetch the input specified by the declarative input typeand value.</para></listitem><listitem><para>Hydra will use the configuration given in the declarative specfile as the jobset configuration for this evaluation. In additionto any inputs specified in the spec file, hydra will also pass the<literal>declInput</literal> argument corresponding to the inputfetched in step 1.</para></listitem><listitem><para>As normal, hydra will build the jobs specified in the jobsetrepository, which in this case is the single<literal>jobsets</literal> job. When that job completes, hydrawill read the created jobset specifications and createcorresponding jobsets in the project, disabling any jobsets thatused to exist but are not present in the current spec.</para></listitem></orderedlist></section></section><title>Declarative projects</title><para>Hydra supports declaratively configuring a project's jobsets. Thisconfiguration can be done statically, or generated by a build job.</para><note><para>Hydra will treat the project's declarative input as a static definitionif and only if the spec file contains a dictionary of dictionaries.If the value of any key in the spec is not a dictionary, it willtreat the spec as a generated declarative spec.</para></note><section xml:id="sec-static-declarative-projects"><title>Static, Declarative Projects</title><para>Hydra supports declarative projects, where jobsets are configuredfrom a static JSON document in a repository.</para><para>To configure a static declarative project, take the following steps:</para><orderedlist numeration="arabic" spacing="compact"><listitem><para>Create a Hydra-fetchable source like a Git repository or local path.</para></listitem><listitem><para>In that source, create a file called <filename>spec.json</filename>,and add the specification for all of the jobsets. Each key is jobsetand each value is a jobset's specification. For example:
<chapter xmlns="http://docbook.org/ns/docbook"xmlns:xlink="http://www.w3.org/1999/xlink"xml:id="chap-introduction"><listitem> They do not manage the <emphasis>buildenvironment</emphasis>. The build environment consists of thedependencies necessary to perform a build action, e.g.,compilers, libraries, etc. Setting up the environment istypically done manually, and without proper SCM control (so itmay be hard to reproduce a build at a later time). Manualmanagement of the environment scales poorly in the number ofconfigurations that must be supported. For instance, supposethat we want to build a component that requires a certaincompiler X. We then have to go to each machine and install X.If we later need a newer version of X, the process must berepeated all over again. An ever worse problem occurs ifthere are conflicting, mutually exclusive versions of thedependencies. Thus, simply installing the latest version isnot an option. Of course, we can install these components indifferent directories and manually pass the appropriate pathsto the build processes of the various components. But this isa rather tiresome and error-prone process.</listitem><listitem> They do not easily support <emphasis>variability in softwaresystems</emphasis>. A system may have a great deal of build-timevariability: optional functionality, whether to build a debug orproduction version, different versions of dependencies, and so on.(For instance, the Linux kernel now has over 2,600 build-timeconfiguration switches.) It is therefore important that a continuousintegration tool can easily select and test different instances fromthe configuration space of the system to reveal problems, such aserroneous interactions between features. In a continuous integrationsetting, it is also useful to test different combinations of versionsof subsystems, e.g., the head revision of a component against stablereleases of its dependencies, and vice versa, as this can revealvarious integration problems.</listitem></itemizedlist></para><para><emphasis>Hydra</emphasis>, is a continuous integration toolthat solves these problems. It is built on top of the <linkxlink:href="http://nixos.org/nix/">Nix package manager</link>,which has a purely functional language for describing packagebuild actions and their dependencies. This allows the buildenvironment for projects to be produced automatically anddeterministically, and variability in components to be expressednaturally using functions; and as such is an ideal fit for acontinuous build system.</para></section><section><title>About Us</title><para>Hydra is the successor of the Nix Buildfarm, which was developedin tandem with the Nix software deployment system. Nix wasoriginally developed at the Department of Information andComputing Sciences, Utrecht University by the TraCE project(2003-2008). The project was funded by the Software EngineeringResearch Program Jacquard to improve the support for variabilityin software systems. Funding for the development of Nix andHydra is now provided by the NIRICT LaQuSo Build Farm project.</para></section><section><title>About this Manual</title><para>This manual tells you how to install the Hydra buildfarmsoftware on your own server and how to operate that server usingits web interface.</para></section><section><title>License</title><para>Hydra is free software: you can redistribute it and/ormodify it under the terms of the GNU General Public License aspublished by the Free Software Foundation, either version 3 ofthe License, or (at your option) any later version.</para><para>Hydra is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<link xlink:href="http://www.gnu.org/licenses/">GNU GeneralPublic License</link> for more details.</para></section><section><title>Hydra at <literal>nixos.org</literal></title><para>The <literal>nixos.org</literal> installation of Hydra runs at<linkxlink:href="http://hydra.nixos.org/"><literal>http://hydra.nixos.org/</literal></link>.That installation is used to build software components from the<link xlink:href="http://nixos.org">Nix</link>,<link xlink:href="http://nixos.org/nixos">NixOS</link>,<link xlink:href="http://www.gnu.org/">GNU</link>,<link xlink:href="http://strategoxt.org">Stratego/XT</link>,and related projects.</para><para>If you are one of the developers on those projects, it is likelythat you will be using the NixOS Hydra server in some way. Ifyou need to administer automatic builds for your project, youshould pull the right strings to get an account on theserver. This manual will tell you how to set up new projects andbuild jobs within those projects and write a release.nix file todescribe the build process of your project to Hydra. You canskip the next chapter.</para><para>If your project does not yet have automatic builds within theNixOS Hydra server, it may actually be eligible. We are in theprocess of setting up a large buildfarm that should be able tosupport open source and academic software projects. Get intouch.</para></section><section><title>Hydra on your own buildfarm</title><para>If you need to run your own Hydra installation, <xreflinkend="chap-installation" /> explains how to download andinstall the system on your own server.</para></section></chapter><!--Local Variables:indent-tabs-mode: nilispell-local-dictionary: "american"End:--><title>Introduction</title><section><title>About Hydra</title><para>Hydra is a tool for continuous integration testing and softwarerelease that uses a purely functional language to describe build jobsand their dependencies. Continuous integration is a simple techniqueto improve the quality of the software development process. Anautomated system continuously or periodically checks out the sourcecode of a project, builds it, runs tests, and produces reports for thedevelopers. Thus, various errors that might accidentally be committedinto the code base are automatically caught. Such a system allowsmore in-depth testing than what developers could feasibly do manually:<itemizedlist><listitem> <emphasis>Portability testing</emphasis>: Thesoftware may need to be built and tested on many differentplatforms. It is infeasible for each developer to do thisbefore every commit.</listitem><listitem> Likewise, many projects have very large test sets(e.g., regression tests in a compiler, or stress tests in aDBMS) that can take hours or days to run to completion.</listitem><listitem> Many kinds of static and dynamic analyses can beperformed as part of the tests, such as code coverage runs andstatic analyses.</listitem><listitem> It may also be necessary to build many different<emphasis>variants</emphasis> of the software. For instance,it may be necessary to verify that the component builds withvarious versions of a compiler.</listitem><listitem> Developers typically use incremental building totest their changes (since a full build may take too long), butthis is unreliable with many build management tools (such asMake), i.e., the result of the incremental build might differfrom a full build.</listitem><listitem> It ensures that the software can be built from thesources under revision control. Users of version managementsystems such as CVS and Subversion often forget to placesource files under revision control.</listitem><listitem> The machines on which the continuous integrationsystem runs ideally provides a clean, well-defined buildenvironment. If this environment is administered throughproper SCM techniques, then builds produced by the system canbe reproduced. In contrast, developer work environments aretypically not under any kind of SCM control.</listitem><listitem> In large projects, developers often work on aparticular component of the project, and do not build and testthe composition of those components (again since this islikely to take too long). To prevent the phenomenon of ``bigbang integration'', where components are only tested togethernear the end of the development process, it is important totest components together as soon as possible (hence<emphasis>continuous integration</emphasis>).</listitem><listitem> It allows software to be<emphasis>released</emphasis> by automatically creatingpackages that users can download and install. To do thismanually represents an often prohibitive amount of work, asone may want to produce releases for many different platforms:e.g., installers for Windows and Mac OS X, RPM or Debianpackages for certain Linux distributions, and so on.</listitem></itemizedlist></para><para>In its simplest form, a continuous integration tool sits in aloop building and releasing software components from a versionmanagement system. For each component, it performs thefollowing tasks:<itemizedlist><listitem>It obtains the latest version of the component'ssource code from the version management system.</listitem><listitem> It runs the component's build process (whichpresumably includes the execution of the component's testset).</listitem><listitem> It presents the results of the build (such as errorlogs and releases) to the developers, e.g., by producing a webpage.</listitem></itemizedlist>Examples of continuous integration tools include Jenkins,CruiseControl Tinderbox, Sisyphus, Anthill and BuildBot. Thesetools have various limitations.<itemizedlist>
<chapter xmlns="http://docbook.org/ns/docbook"xmlns:xlink="http://www.w3.org/1999/xlink"xmlns:xi="http://www.w3.org/2001/XInclude"xml:id="chap-projects"><title>Creating and Managing Projects</title><para>Once Hydra is installed and running, the next step is to addprojects to the build farm. We follow the example of the <linkxlink:href="http://nixos.org/patchelf.html">Patchelfproject</link>, a software tool written in C and using the GNUBuild System (GNU Autoconf and GNU Automake).</para><para>Log in to the web interface of your Hydra installation using theuser name and password you inserted in the database (by default,Hydra's web server listens on <linkxlink:href="http://localhost:3000/"><literal>localhost:3000</literal></link>).Then follow the "Create Project" link to create a new project.</para><section><title>Project Information</title><para>A project definition consists of some general information and aset of job sets. The general information identifies a project,its owner, and current state of activity.Here's what we fill in for the patchelf project:<screen>Identifier: patchelf</screen>The <emphasis>identifier</emphasis> is the identity of theproject. It is used in URLs and in the names of build results.</para><para>The identifier should be a unique name (it is the primarydatabase key for the project table in the database). If you tryto create a project with an already existing identifier you'dget an error message from the database.So try to create the project after entering just the generalinformation to figure out if you have chosen a unique name.Job sets can be added once the project has been created.<screen>Display name: Patchelf</screen>The <emphasis>display name</emphasis> is used in menus.<screen>Description: A tool for modifying ELF binaries</screen>The <emphasis>description</emphasis> is used as shortdocumentation of the nature of the project.<screen>Owner: eelco</screen>The <emphasis>owner</emphasis> of a project can create and editjob sets.<screen>Enabled: Yes</screen>Only if the project is <emphasis>enabled</emphasis> are buildsperformed.</para><para>Once created there should be an entry for the project in thesidebar. Go to the project page for the <linkxlink:href="http://localhost:3000/project/patchelf">Patchelf</link>project.</para></section><section><title>Job Sets</title><para>A project can consist of multiple <emphasis>job sets</emphasis>(hereafter <emphasis>jobsets</emphasis>), separate tasks thatcan be built separately, but may depend on each other (withoutcyclic dependencies, of course). Go to the <linkxlink:href="http://localhost:3000/project/patchelf/edit">Edit</link>page of the Patchelf project and "Add a new jobset" by providingthe following "Information":<screen>Identifier: trunkDescription: TrunkNix expression: release.nix in input patchelfSrc</screen>This states that in order to build the <literal>trunk</literal>jobset, the Nix expression in the file<filename>release.nix</filename>, which can be obtained frominput <literal>patchelfSrc</literal>, should beevaluated. (We'll have a look at<filename>release.nix</filename> later.)</para><para>To realize a job we probably need a number of inputs, which canbe declared in the table below. As many inputs as required canbe added. For patchelf we declare the following inputs.<screen>patchelfSrc'Git checkout' https://github.com/NixOS/patchelfnixpkgs 'Git checkout' https://github.com/NixOS/nixpkgsofficialRelease Boolean falsesystem String value "i686-linux"</screen></para></section><section><title>Building Jobs</title></section><section><title>Build Recipes</title><para>Build jobs and <emphasis>build recipes</emphasis> for a jobset arespecified in a text file written in the <linkxlink:href="http://nixos.org/nix/">Nix language</link>. Therecipe is actually called a <emphasis>Nix expression</emphasis> inNix parlance. By convention this file is often called<filename>release.nix</filename>.</para><para>The <filename>release.nix</filename> file is typically kept underversion control, and the repository that contains it one of thebuild inputs of the corresponding–often called<literal>hydraConfig</literal> by convention. The repository forthat file and the actual file name are specified on the webinterface of Hydra under the <literal>Setup</literal> tab of thejobset's overview page, under the <literal>Nixexpression</literal> heading. See, for example, the <linkxlink:href="http://hydra.nixos.org/jobset/patchelf/trunk">jobsetoverview page</link> of the PatchELF project, and <linkxlink:href="https://github.com/NixOS/patchelf/blob/master/release.nix">the corresponding Nix file</link>.</para>jobs = rec { <co xml:id='ex-hello-co-jobs' />tarball = <co xml:id='ex-hello-co-tarball' />pkgs.releaseTools.sourceTarball { <co xml:id='ex-hello-co-source-tarball' />name = "hello-tarball";src = <hello>; <co xml:id='ex-hello-co-tarball-args' />buildInputs = (with pkgs; [ gettext texLive texinfo ]);};build = <co xml:id='ex-hello-co-build' />{ system ? builtins.currentSystem }: <co xml:id='ex-hello-co-build-args' />let pkgs = import <nixpkgs> { inherit system; }; inpkgs.releaseTools.nixBuild { <co xml:id='ex-hello-co-nix-build' />name = "hello";src = jobs.tarball;configureFlags = [ "--disable-silent-rules" ];};};injobs <co xml:id='ex-hello-co-body' /></programlisting></example><para><xref linkend='ex-hello' /> shows what a<filename>release.nix</filename> file for <linkxlink:href="http://www.gnu.org/software/hello/">GNU Hello</link>would look like. GNU Hello is representative of many GNUand non-GNU free software projects:<itemizedlist><listitem>it uses the GNU Build System, namely GNU Autoconf,and GNU Automake; for users, it means it can be installedusing the <linkxlink:href="http://www.gnu.org/prep/standards/html_node/Managing-Releases.html">usual<literal>./configure && make install</literal>procedure</link>;</listitem><listitem>it uses Gettext for internationalization;</listitem><listitem>it has a Texinfo manual, which can be rendered as PDFwith TeX.</listitem></itemizedlist>The file defines a jobset consisting of two jobs:<literal>tarball</literal>, and <literal>build</literal>. Itcontains the following elements (referenced from the figure bynumbers):<calloutlist><callout arearefs='ex-hello-co-import-nixpkgs'><para>This defines a variable <varname>pkgs</varname> holdingthe set of packages provided by <linkxlink:href="http://nixos.org/nixpkgs/">Nixpkgs</link>.</para><para>Since <varname>nixpkgs</varname> appears in angle brackets,there must be a build input of that name in the Nix searchpath. In this case, the web interface should show a<varname>nixpkgs</varname> build input, which is a checkoutof the Nixpkgs source code repository; Hydra then adds thisand other build inputs to the Nix search path whenevaluating <filename>release.nix</filename>.</para></callout><callout arearefs='ex-hello-co-jobs'><para>This defines a variable holding the two Hydrajobs–an <emphasis>attribute set</emphasis> in Nix.</para></callout><callout arearefs='ex-hello-co-tarball'><para>This is the definition of the first job, named<varname>tarball</varname>. The purpose of this job is toproduce a usable source code tarball.</para></callout><callout arearefs='ex-hello-co-source-tarball'><para>The <varname>tarball</varname> job calls the<varname>sourceTarball</varname> function, which (roughly)runs <command>autoreconf && ./configure &&make dist</command> on the checkout. The<varname>buildInputs</varname> attribute specifiesadditional software dependencies for thejob<footnote><para>The package names used in<varname>buildInputs</varname>–e.g.,<varname>texLive</varname>–are the names of the<emphasis>attributes</emphasis> corresponding to thesepackages in Nixpkgs, specifically in the <linkxlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/top-level/all-packages.nix"><filename>all-packages.nix</filename></link>file. See the section entitled “Package Naming” in theNixpkgs manual for more information.</para></footnote>.</para></callout><callout arearefs='ex-hello-co-tarball-args'><para>The <varname>tarball</varname> jobs expects a<varname>hello</varname> build input to be available in theNix search path. Again, this input is passed by Hydra andis meant to be a checkout of GNU Hello's source coderepository.</para></callout><callout arearefs='ex-hello-co-build'><para>This is the definition of the <varname>build</varname>job, whose purpose is to build Hello from the tarballproduced above.</para></callout><callout arearefs='ex-hello-co-build-args'><para>The <varname>build</varname> function takes oneparameter, <varname>system</varname>, which should be a stringdefining the Nix system type–e.g.,<literal>"x86_64-linux"</literal>. Additionally, it refersto <varname>jobs.tarball</varname>, seen above.</para><para>Hydra inspects the formal argument list of the function(here, the <varname>system</varname> argument) and passes itthe corresponding parameter specified as a build input onHydra's web interface. Here, <varname>system</varname> ispassed by Hydra when it calls <varname>build</varname>.Thus, it must be defined as a build input of type string inHydra, which could take one of several values.</para><para>The question mark after <literal>system</literal> definesthe default value for this argument, and is only useful whendebugging locally.</para></callout><callout arearefs='ex-hello-co-nix-build'><para>The <varname>build</varname> job calls the<varname>nixBuild</varname> function, which unpacks thetarball, then runs <command>./configure && make&& make check && make install</command>.</para></callout><callout arearefs='ex-hello-co-body'><para>Finally, the set of jobs is returned to Hydra, as a Nixattribute set.</para></callout></calloutlist></para></section><section><title>Building from the Command Line</title><para>It is often useful to test a build recipe, for instance beforeit is actually used by Hydra, when testing changes, or whendebugging a build issue. Since build recipes for Hydra jobsetsare just plain Nix expressions, they can be evaluated using thestandard Nix tools.</para><para>To evaluate the <varname>tarball</varname> jobset of <xreflinkend='ex-hello' />, just run:<screen>$ nix-build release.nix -A tarball</screen>However, doing this with <xref linkend='ex-hello' /> as is willprobably yield an error like this:<screen>error: user-thrown exception: file `hello' was not found in the Nix search path (add it using $NIX_PATH or -I)</screen>The error is self-explanatory. Assuming<filename>$HOME/src/hello</filename> points to a checkout ofHello, this can be fixed this way:<screen>$ nix-build -I ~/src release.nix -A tarball</screen>Similarly, the <varname>build</varname> jobset can be evaluated:<screen>$ nix-build -I ~/src release.nix -A build</screen>The <varname>build</varname> job reuses the result of the<varname>tarball</varname> job, rebuilding it only if it needs to.</para></section><section><title>Adding More Jobs</title><para><xref linkend='ex-hello' /> illustrates how to write the mostbasic jobs, <varname>tarball</varname> and<varname>build</varname>. In practice, much more can be done byusing features readily provided by Nixpkgs or by creating new jobsas customizations of existing jobs.</para><para>For instance, test coverage report for projects compiled with GCCcan be automatically generated using the<varname>coverageAnalysis</varname> function provided by Nixpkgsinstead of <varname>nixBuild</varname>. Back to our GNU Helloexample, we can define a <varname>coverage</varname> job thatproduces an HTML code coverage report directly readable from thecorresponding Hydra build page:<programlisting>coverage ={ system ? builtins.currentSystem }:let pkgs = import nixpkgs { inherit system; }; inpkgs.releaseTools.coverageAnalysis {name = "hello";src = jobs.tarball;configureFlags = [ "--disable-silent-rules" ];};</programlisting>As can be seen, the only difference compared to<varname>build</varname> is the use of<varname>coverageAnalysis</varname>.</para><para>Nixpkgs provides many more build tools, including the ability torun build in virtual machines, which can themselves run anotherGNU/Linux distribution, which allows for the creation of packagesfor these distributions. Please see <linkxlink:href="https://github.com/NixOS/nixpkgs/tree/master/pkgs/build-support/release">the<filename>pkgs/build-support/release</filename> directory</link>of Nixpkgs for more. The NixOS manual also contains informationabout whole-system testing in virtual machine.</para><para>Now, assume we want to build Hello with an old version of GCC, andwith different <command>configure</command> flags. A new<varname>build_exotic</varname> job can be written that simply<emphasis>overrides</emphasis> the relevant arguments passed to<varname>nixBuild</varname>:</section></chapter><!--Local Variables:indent-tabs-mode: nilispell-local-dictionary: "american"End:--><xi:include href="declarative-projects.xml" /><section><title>Email Notifications</title><para>Hydra can send email notifications when the status of a build changes. This providesimmediate feedback to maintainers or committers when a change causes build failures.</para><para>The simplest approach to enable Email Notifications is to use the ssmtp package, whichsimply hands off the emails to another SMTP server. For details on how to configure ssmtp,see the documentation for the <varname>networking.defaultMailServer</varname> option.To use ssmtp for the Hydra email notifications, add it to the path option of the Hydra servicesin your <filename>/etc/nixos/configuration.nix</filename> file:<programlisting>systemd.services.hydra-queue-runner.path = [ pkgs.ssmtp ];systemd.services.hydra-server.path = [ pkgs.ssmtp ];</programlisting></para></section><programlisting>build_exotic ={ system ? builtins.currentSystem }:letpkgs = import nixpkgs { inherit system; };build = jobs.build { inherit system; };inpkgs.lib.overrideDerivation build (attrs: {buildInputs = [ pkgs.gcc33 ];preConfigure = "gcc --version";configureFlags =attrs.configureFlags ++ [ "--disable-nls" ];});</programlisting>The <varname>build_exotic</varname> job reuses<varname>build</varname> and overrides some of its arguments: itadds a dependency on GCC 3.3, a pre-configure phase that runs<command>gcc --version</command>, and adds the<literal>--disable-nls</literal> configure flags.</para><para>This customization mechanism is very powerful. For instance, itcan be used to change the way Hello and <emphasis>all</emphasis>its dependencies–including the C library and compiler used tobuild it–are built. See the Nixpkgs manual for more.</para><example xml:id='ex-hello'><title><filename>release.nix</filename> file for GNU Hello</title><programlisting>letpkgs = import <nixpkgs> {}; <co xml:id='ex-hello-co-import-nixpkgs' /><para>Knowledge of the Nix language is recommended, but the examplebelow should already give a good idea of how it works:</para>
<chapter xmlns="http://docbook.org/ns/docbook"xmlns:xlink="http://www.w3.org/1999/xlink"xmlns:xi="http://www.w3.org/2001/XInclude"xml:id="chap-api"><title>Using the external API</title><para>To be able to create integrations with other services, Hydra exposesan external API that you can manage projects with.</para><para>The API is accessed over HTTP(s) where all data is sent and receivedas JSON.</para><para>Creating resources requires the caller to be authenticated, whileretrieving resources does not.</para><para>The API does not have a separate URL structure for it's endpoints.Instead you request the pages of the web interface as<literal>application/json</literal> to use the API.</para><section><title>List projects</title><para>To list all the <literal>projects</literal> of the Hydra install:</para><programlisting>GET /Accept: application/json</programlisting><para>This will give you a list of <literal>projects</literal>, where each<literal>project</literal> contains general information and a listof its <literal>job sets</literal>.</para><para><emphasis role="strong">Example</emphasis></para><programlisting>curl -i -H 'Accept: application/json' \https://hydra.nixos.org</programlisting><para><emphasis role="strong">Note:</emphasis> this response is truncated</para><programlisting>GET https://hydra.nixos.org/HTTP/1.1 200 OKContent-Type: application/json[{"displayname": "Acoda","name": "acoda","description": "Acoda is a tool set for automatic data migration along an evolving data model","enabled": 0,"owner": "sander","hidden": 1,"jobsets": ["trunk"]},{"displayname": "cabal2nix","name": "cabal2nix","description": "Convert Cabal files into Nix build instructions","enabled": 0,"owner": "simons@cryp.to","hidden": 1,"jobsets": ["master"]}]</programlisting></section><section><title>Get a single project</title><para>To get a single <literal>project</literal> by identifier:</para><programlisting>GET /project/:project-identifierAccept: application/json</programlisting><para><emphasis role="strong">Example</emphasis></para><programlisting>curl -i -H 'Accept: application/json' \https://hydra.nixos.org/project/hydra</programlisting><programlisting>GET https://hydra.nixos.org/project/hydraHTTP/1.1 200 OKContent-Type: application/json{"description": "Hydra, the Nix-based continuous build system","hidden": 0,"displayname": "Hydra","jobsets": ["hydra-master","hydra-ant-logger-trunk","master","build-ng"],"name": "hydra","enabled": 1,"owner": "eelco"}</programlisting></section><section><title>Get a single job set</title><para>To get a single <literal>job set</literal> by identifier:</para><programlisting>GET /jobset/:project-identifier/:jobset-identifierContent-Type: application/json</programlisting><para><emphasis role="strong">Example</emphasis></para><programlisting>curl -i -H 'Accept: application/json' \https://hydra.nixos.org/jobset/hydra/build-ng</programlisting><programlisting>GET https://hydra.nixos.org/jobset/hydra/build-ngHTTP/1.1 200 OKContent-Type: application/json{"errormsg": "evaluation failed due to signal 9 (Killed)","fetcherrormsg": null,"nixexprpath": "release.nix","nixexprinput": "hydraSrc","emailoverride": "rob.vermaas@gmail.com, eelco.dolstra@logicblox.com","jobsetinputs": {"officialRelease": {"jobsetinputalts": ["false"]},"hydraSrc": {"jobsetinputalts": ["https://github.com/NixOS/hydra.git build-ng"]},"nixpkgs": {"jobsetinputalts": ["https://github.com/NixOS/nixpkgs.git release-14.12"]}},"enabled": 0}</programlisting></section><section><title>List evaluations</title><para>To list the <literal>evaluations</literal> of a<literal>job set</literal> by identifier:</para><programlisting>GET /jobset/:project-identifier/:jobset-identifier/evalsContent-Type: application/json</programlisting><para><emphasis role="strong">Example</emphasis></para><programlisting>curl -i -H 'Accept: application/json' \https://hydra.nixos.org/jobset/hydra/build-ng/evals</programlisting><para><emphasis role="strong">Note:</emphasis> this response is truncated</para><programlisting>GET https://hydra.nixos.org/jobset/hydra/build-ng/evalsHTTP/1.1 200 OKContent-Type: application/json{"evals": [{"jobsetevalinputs": {"nixpkgs": {"dependency": null,"type": "git","value": null,"uri": "https://github.com/NixOS/nixpkgs.git","revision": "f60e48ce81b6f428d072d3c148f6f2e59f1dfd7a"},"hydraSrc": {"dependency": null,"type": "git","value": null,"uri": "https://github.com/NixOS/hydra.git","revision": "48d6f0de2ab94f728d287b9c9670c4d237e7c0f6"},"officialRelease": {"dependency": null,"value": "false","type": "boolean","uri": null,"revision": null}},"hasnewbuilds": 1,"builds": [24670686,24670684,24670685,24670687],"id": 1213758}],"first": "?page=1","last": "?page=1"}</programlisting></section><section><title>Get a single build</title><para>To get a single <literal>build</literal> by its id:</para><programlisting>GET /build/:build-idContent-Type: application/json</programlisting><para><emphasis role="strong">Example</emphasis></para><programlisting>curl -i -H 'Accept: application/json' \https://hydra.nixos.org/build/24670686</programlisting><programlisting>GET /build/24670686HTTP/1.1 200 OKContent-Type: application/json{"job": "tests.api.x86_64-linux","jobsetevals": [1213758],"buildstatus": 0,"buildmetrics": null,"project": "hydra","system": "x86_64-linux","priority": 100,"releasename": null,"starttime": 1439402853,"nixname": "vm-test-run-unnamed","timestamp": 1439388618,"id": 24670686,"stoptime": 1439403403,"jobset": "build-ng","buildoutputs": {"out": {"path": "/nix/store/lzrxkjc35mhp8w7r8h82g0ljyizfchma-vm-test-run-unnamed"}},"buildproducts": {"1": {"path": "/nix/store/lzrxkjc35mhp8w7r8h82g0ljyizfchma-vm-test-run-unnamed","defaultpath": "log.html","type": "report","sha256hash": null,"filesize": null,"name": "","subtype": "testlog"}},"finished": 1}</programlisting></section></chapter><!--Local Variables:indent-tabs-mode: nilispell-local-dictionary: "american"End:-->