Provide a command ‘hydra-init’ to initialise/upgrade the database

For schema upgrades, hydra-init executes the files
src/sql/upgrade-<N>.sql, each of which upgrades the schema from
version N-1 to N.  The upgrades are wrapped in a transaction.
This commit is contained in:
Eelco Dolstra 2012-02-28 20:16:16 +01:00
parent 918fc5e6df
commit 541238030d
7 changed files with 137 additions and 53 deletions

View file

@ -1,37 +1,38 @@
{pkgs}:
{ pkgs }:
with pkgs;
[ perlPackages.CatalystDevel
perlPackages.CatalystPluginSessionStoreFastMmap
perlPackages.CatalystPluginStackTrace
[ perlPackages.CatalystAuthenticationStoreDBIxClass
perlPackages.CatalystPluginAccessLog
perlPackages.CatalystPluginAuthorizationRoles
perlPackages.CatalystPluginSessionStateCookie
perlPackages.CatalystPluginAccessLog
perlPackages.CatalystAuthenticationStoreDBIxClass
perlPackages.CatalystViewTT
perlPackages.CatalystPluginSessionStoreFastMmap
perlPackages.CatalystPluginStackTrace
perlPackages.CatalystViewDownload
perlPackages.CatalystViewJSON
perlPackages.CatalystViewTT
perlPackages.CatalystXScriptServerStarman
perlPackages.XMLSimple
perlPackages.IPCRun
perlPackages.IOCompress
perlPackages.Readonly
perlPackages.CryptRandPasswd
perlPackages.DBDPg
perlPackages.DBDSQLite
perlPackages.EmailSender
perlPackages.TextTable
perlPackages.TextDiff
perlPackages.FileSlurp
perlPackages.NetTwitterLite
perlPackages.PadWalker
perlPackages.DataDump
perlPackages.JSONXS
perlPackages.DateTime
perlPackages.DigestSHA1
perlPackages.CryptRandPasswd
perlPackages.TestMore
perlPackages.SysHostnameLong
perlPackages.EmailSender
perlPackages.FileSlurp
perlPackages.IOCompress
perlPackages.IPCRun
perlPackages.JSONXS
perlPackages.NetTwitterLite
perlPackages.PadWalker
perlPackages.CatalystDevel
perlPackages.Readonly
perlPackages.SQLSplitStatement
perlPackages.Starman
perlPackages.SysHostnameLong
perlPackages.TestMore
perlPackages.TextDiff
perlPackages.TextTable
perlPackages.XMLSimple
nixUnstable
]

View file

@ -73,21 +73,23 @@
<section>
<title>Installation</title>
<!--
<para>
Hydra can be installed using Nixpkgs:
<screen>
nix-env -Ai hydra -f /path/to/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>
Alternatively, the latest development snapshot can be installed
The latest development snapshot of Hydra can be installed
by visiting the URL <link
xlink:href="http://hydra.nixos.org/view/hydra/unstable"><literal>http://hydra.nixos.org/view/hydra/unstable</literal></link>
and use the one-click install available at one of the build
and using the one-click install available at one of the build
pages. You can also install Hydra through the channel by
performing the following commands:
@ -101,8 +103,10 @@ nix-env -i hydra</screen>
Command completion should reveal a number of command-line tools from Hydra:
<screen>
hydra-build hydra-evaluator hydra-server
hydra-eval-jobs hydra-queue-runner hydra-update-gc-roots</screen>
hydra-build hydra-init hydra-update-gc-roots
hydra-eval-jobs hydra-queue-runner
hydra-evaluator hydra-server
</screen>
</para>
</section>
@ -116,24 +120,46 @@ hydra-eval-jobs hydra-queue-runner hydra-update-gc-roots</screen>
<para>
To setup a PostgreSQL database with <emphasis>hydra</emphasis>
as database name and user name, issue the following commands:
as database name and user name, issue the following commands on
the PostgreSQL server:
<screen>
createdb hydra
echo "CREATE USER hydra WITH PASSWORD '&lt;your-password&gt;' ;" | psql hydra
cat $prefix/share/hydra/sql/hydra-postgresql.sql | psql hydra
echo "GRANT ALL ON DATABASE hydra TO hydra;" | psql hydra</screen>
createuser -S -D -R -P hydra
createdb -O hydra hydra</screen>
Note that <emphasis>$prefix</emphasis> is the location of Hydra
in the nix store.
</para>
<para>
For SQLite, the following command is all it takes to create the
database:
Hydra uses an environment variable to know which database should
be used, and a variable which point to a location that holds
some state. To set these variables for a PostgreSQL database,
add the following to the file <filename>~/.profile</filename> of
the user running the Hydra services.
<screen>
cat $prefix/share/hydra/sql/hydra-sqlite.sql | sqlite3 /path/to/hydra.sqlite</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> directory
exists and is writable for the user which will run the Hydra
services. For a SQLite database, the
<varname>HYDRA_DBI</varname> should be set to something like
<literal>dbi:SQLite:/path/to/hydra.sqlite</literal>
</para>
<para>
Having set these environment variables, you can now initialise
the database by doing:
<screen>
hydra-init</screen>
</para>
<para>
@ -148,23 +174,17 @@ echo "INSERT INTO UserRoles(userName, role) values('root', 'admin');" | psql hyd
/path/to/hydra.sqlite</command>.
</para>
<para>
Hydra uses an environment variable to know which database should
be used, and a variable which point to a location that holds
some state. To set these variables for a PostgreSQL database,
add the following to the <filename>.profile</filename> of the
user running the Hydra services.
</section>
<section>
<title>Upgrading</title>
<para>If you're upgrading Hydra from a previous version, you
should do the following to perform any necessary database schema migrations:
<screen>
export HYDRA_DBI="dbi:Pg:dbname=hydra;host=localhost;"
export HYDRA_DATA=/var/lib/hydra</screen>
Make sure that the <emphasis>HYDRA_DATA</emphasis> directory
exists and is writable for the user which will run the Hydra
services. For a SQLite database, the
<varname>HYDRA_DBI</varname> should be set to something like
<literal>dbi:SQLite:/path/to/hydra.sqlite</literal>
hydra-init</screen>
</para>
</section>
<section>

View file

@ -8,7 +8,7 @@ use Hydra::Helper::CatalystUtils;
our @ISA = qw(Exporter);
our @EXPORT = qw(
getHydraPath getHydraDBPath openHydraDB getHydraConf txn_do
getHydraPath getHydraHome getHydraDBPath openHydraDB getHydraConf txn_do
registerRoot getGCRootsDir gcRootFor
getPrimaryBuildsForView
getPrimaryBuildTotal
@ -21,6 +21,13 @@ sub getHydraPath {
return $dir;
}
sub getHydraHome {
my $dir = $ENV{"HYDRA_HOME"} or die "The HYDRA_HOME directory does not exist!\n";
return $dir;
}
sub getHydraConf {
my $conf = $ENV{"HYDRA_CONFIG"} || (getHydraPath . "/hydra.conf");
die "The HYDRA_CONFIG file ($conf) does not exist!\n" unless -f $conf;

58
src/script/hydra-init Executable file
View file

@ -0,0 +1,58 @@
#! /var/run/current-system/sw/bin/perl -w
use strict;
use Hydra::Schema;
use Hydra::Helper::Nix;
use File::Slurp;
use SQL::SplitStatement;
use List::Util qw(max);
my $db = openHydraDB;
my $dbh = $db->storage->dbh;
$dbh->{RaiseError} = 1;
my $home = getHydraHome;
my $sql_splitter = SQL::SplitStatement->new;
# Figure out the target schema version.
my $maxSchemaVersion = max (map { /.*\/upgrade-(\d.*)\.sql/; $1 } (glob "$home/sql/upgrade-[0-9]*.sql")) || 1;
# Check whether the database has been initialised. If not, load the
# schema.
my @tables = $dbh->tables;
if (! grep { /SchemaVersion/i } @tables) {
print STDERR "initialising the Hydra database schema...\n";
my $schema = read_file(
$dbh->{Driver}->{Name} eq 'SQLite' ? "$home/sql/hydra-sqlite.sql" :
$dbh->{Driver}->{Name} eq 'Pg' ? "$home/sql/hydra-postgresql.sql" :
die "unsupported database type\n");
my @statements = $sql_splitter->split($schema);
eval {
$dbh->begin_work;
$dbh->do($_) foreach @statements;
$db->resultset('SchemaVersion')->create({version => $maxSchemaVersion});
$dbh->commit;
};
die "schema initialisation failed: $@\n" if $@;
exit 0;
}
# Get the current schema version.
my @versions = $db->resultset('SchemaVersion')->all;
die "couldn't get Hydra schema version!" if scalar @versions != 1;
my $schemaVersion = $versions[0]->version;
for (my $n = $schemaVersion; $n < $maxSchemaVersion; $n++) {
my $m = $n + 1;
print STDERR "upgrading Hydra schema from version $n to $m\n";
my $schema = read_file("$home/sql/upgrade-$m.sql");
my @statements = $sql_splitter->split($schema);
eval {
$dbh->begin_work;
$dbh->do($_) foreach @statements;
$db->resultset('SchemaVersion')->update({version => $m});
$dbh->commit;
};
die "schema upgrade failed: $@\n" if $@;
}

View file

@ -1,6 +1,6 @@
EXTRA_DIST = hydra.sql hydra-postgresql.sql hydra-sqlite.sql
sqldir = $(datadir)/hydra/sql
sqldir = $(libexecdir)/hydra/sql
nobase_sql_DATA = $(EXTRA_DIST)
hydra-postgresql.sql: hydra.sql

View file

@ -3,8 +3,6 @@ create table SchemaVersion (
version integer not null
);
insert into SchemaVersion (version) values (1);
create table Users (
userName text primary key not null,

View file

@ -31,7 +31,7 @@ clean :
check_SCRIPTS = db.sqlite repos
db.sqlite : $(top_srcdir)/src/sql/hydra-sqlite.sql
sqlite3 db.sqlite < $(top_srcdir)/src/sql/hydra-sqlite.sql
perl $(top_srcdir)/src/script/hydra-init
repos : dirs git-repo hg-repo svn-repo svn-checkout-repo bzr-repo bzr-checkout-repo