2 # eg_db_config.pl -- configure Evergreen database settings and create schema
5 # Copyright (C) 2008 Equinox Software, Inc.
6 # Copyright (C) 2008-2009 Laurentian University
7 # Author: Kevin Beswick <kevinbeswick00@gmail.com>
8 # Author: Dan Scott <dscott@laurentian.ca>
10 # This program is free software; you can redistribute it and/or
11 # modify it under the terms of the GNU General Public License
12 # as published by the Free Software Foundation; either version 2
13 # of the License, or (at your option) any later version.
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
20 use strict; use warnings;
28 my ($dbhost, $dbport, $dbname, $dbuser, $dbpw, $help, $admin_user, $admin_pw);
31 my $offline_file = '';
34 my $pg_contribdir = '';
35 my $create_db_sql = '';
38 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
40 # Get the directory for this script
41 my $script_dir = dirname($0);
45 =item update_config() - Puts command line specified settings into xml file
48 my ($services, $settings) = @_;
50 my $parser = XML::LibXML->new();
51 my $opensrf_config = $parser->parse_file($config_file);
54 foreach my $service (@$services) {
55 foreach my $key (keys %$settings) {
56 next unless $settings->{$key};
59 if ($service eq 'state_store') {
60 (@node) = $opensrf_config->findnodes("//state_store/$key/text()");
62 (@node) = $opensrf_config->findnodes("//$service//database/$key/text()");
66 $_->setData($settings->{$key});
73 my $timestamp = sprintf("%d.%d.%d.%d.%d.%d",
74 $year + 1900, $mon +1, $mday, $hour, $min, $sec);
75 if (copy($config_file, "$config_file.$timestamp")) {
76 print "Backed up original configuration file to '$config_file.$timestamp'\n";
78 print STDERR "Unable to write to '$config_file.$timestamp'; bailed out.\n";
81 $opensrf_config->toFile($config_file) or
82 die "ERROR: Failed to update the configuration file '$config_file'\n";
85 =item create_offline_config() - Write out the offline config
87 sub create_offline_config {
88 my ($setup, $settings) = @_;
90 open(FH, '>', $setup) or die "Could not write offline database setup to $setup\n";
92 print "Writing offline database configuration to $setup\n";
94 printf FH "\$main::config{base_dir} = '%s/var/data/offline/';\n", $prefix;
95 printf FH "\$main::config{bootstrap} = '%s/opensrf_core.xml';\n", $sysconfdir;
97 printf FH "\$main::config{dsn} = 'dbi:Pg:host=%s;dbname=%s;port=%d';\n",
98 $settings->{host}, $settings->{db}, $settings->{port};
100 printf FH "\$main::config{usr} = '%s';\n", $settings->{user};
101 printf FH "\$main::config{pw} = '%s';\n", $settings->{pw};
106 =item get_settings() - Extracts database settings from opensrf.xml
109 my $settings = shift;
111 my $host = "/opensrf/default/apps/open-ils.storage/app_settings/databases/database/host/text()";
112 my $port = "/opensrf/default/apps/open-ils.storage/app_settings/databases/database/port/text()";
113 my $dbname = "/opensrf/default/apps/open-ils.storage/app_settings/databases/database/db/text()";
114 my $user = "/opensrf/default/apps/open-ils.storage/app_settings/databases/database/user/text()";
115 my $pw = "/opensrf/default/apps/open-ils.storage/app_settings/databases/database/pw/text()";
117 my $parser = XML::LibXML->new();
118 my $opensrf_config = $parser->parse_file($config_file);
120 # If the user passed in settings at the command line,
121 # we don't want to override them
122 $settings->{host} = $settings->{host} || $opensrf_config->findnodes($host);
123 $settings->{port} = $settings->{port} || $opensrf_config->findnodes($port);
124 $settings->{db} = $settings->{db} || $opensrf_config->findnodes($dbname);
125 $settings->{user} = $settings->{user} || $opensrf_config->findnodes($user);
126 $settings->{pw} = $settings->{pw} || $opensrf_config->findnodes($pw);
129 =item create_database() - Creates the database using create_database.sql
131 sub create_database {
132 my $settings = shift;
134 $ENV{'PGUSER'} = $settings->{user};
135 $ENV{'PGPASSWORD'} = $settings->{pw};
136 $ENV{'PGPORT'} = $settings->{port};
137 $ENV{'PGHOST'} = $settings->{host};
138 my $cmd = 'psql -vdb_name=' . $settings->{db} . ' -vcontrib_dir=' . $pg_contribdir .
139 ' -d postgres -f ' . $create_db_sql;
143 =item create_schema() - Creates the database schema by calling build-db.sh
146 my $settings = shift;
148 chdir(dirname($build_db_sh));
149 my $cmd = File::Spec->catfile('.', basename($build_db_sh)) . " " .
150 $settings->{host} ." ". $settings->{port} ." ".
151 $settings->{db} ." ". $settings->{user} ." ".
157 =item set_admin_account() - Sets the administrative user's user name and password
159 sub set_admin_account {
160 my $admin_user = shift;
161 my $admin_pw = shift;
162 my $settings = shift;
164 my $dbh = DBI->connect('dbi:Pg:dbname=' . $settings->{db} .
165 ';host=' . $settings->{host} . ';port=' . $settings->{port} . ';',
166 $settings->{user} . "", $settings->{pw} . "", {AutoCommit => 1}
169 print STDERR "Could not connect to database to set admin account. ";
170 print STDERR "Error was " . $dbh->errstr . "\n";
173 my $stmt = $dbh->prepare("UPDATE actor.usr SET usrname = ?, passwd = ? WHERE id = 1");
174 $stmt->execute(($admin_user, $admin_pw));
176 print STDERR "Failed to set admin account. ";
177 print STDERR "Error was " . $dbh->errstr . "\n";
189 GetOptions("create-schema" => \$cschema,
190 "create-database" => \$cdatabase,
191 "create-offline" => \$offline,
192 "update-config" => \$uconfig,
193 "config-file=s" => \$config_file,
194 "build-db-file=s" => \$build_db_sh,
195 "pg-contrib-dir=s" => \$pg_contribdir,
196 "create-db-sql=s" => \$create_db_sql,
197 "pg-config=s" => \$pgconfig,
198 "admin-user=s" => \$admin_user,
199 "admin-password=s" => \$admin_pw,
200 "service=s" => \@services,
201 "user=s" => \$settings{'user'},
202 "password=s" => \$settings{'pw'},
203 "database=s" => \$settings{'db'},
204 "hostname=s" => \$settings{'host'},
205 "port=i" => \$settings{'port'},
209 if (grep(/^all$/, @services)) {
210 @services = qw/reporter open-ils.cstore open-ils.pcrud open-ils.storage open-ils.reporter-store state_store/;
213 my $eg_config = File::Spec->catfile($script_dir, '../extras/eg_config');
216 my @temp = `$eg_config --sysconfdir`;
218 $sysconfdir = $temp[0];
219 $config_file = File::Spec->catfile($sysconfdir, "opensrf.xml");
223 my @temp = `$eg_config --prefix`;
229 $build_db_sh = File::Spec->catfile($script_dir, '../sql/Pg/build-db.sh');
232 if (!$pg_contribdir) {
233 $pgconfig = 'pg_config' if(!$pgconfig);
234 my @temp = `$pgconfig --sharedir`;
236 $pg_contribdir = File::Spec->catdir($temp[0], 'contrib');
239 if (!$create_db_sql) {
240 $create_db_sql = File::Spec->catfile($script_dir, '../sql/Pg/create_database.sql');
243 if (!$offline_file) {
244 $offline_file = File::Spec->catfile($sysconfdir, 'offline-config.pl');
247 unless (-e $build_db_sh) { die "Error: $build_db_sh does not exist. \n"; }
248 unless (-e $config_file) { die "Error: $config_file does not exist. \n"; }
249 unless (-d $pg_contribdir || !$cdatabase) { die "Error: $pg_contribdir does not exist. \n"; }
251 if ($uconfig) { update_config(\@services, \%settings); }
253 # Get our settings from the config file
254 get_settings(\%settings);
256 if ($cdatabase) { create_database(\%settings); }
257 if ($cschema) { create_schema(\%settings); }
258 if ($admin_user && $admin_pw) {
259 set_admin_account($admin_user, $admin_pw, \%settings);
261 if ($offline) { create_offline_config($offline_file, \%settings); }
263 if ((!$cdatabase && !$cschema && !$uconfig && !$offline && !$admin_pw) || $help) {
267 eg_db_config.pl [OPTION] ... [COMMAND] ... [CONFIG OPTIONS]
270 Creates or recreates the Evergreen database schema based on the settings
271 in the opensrf.xml configuration file.
273 Manipulates the configuration file
277 specifies the opensrf.xml file. Defaults to /openils/conf/opensrf.xml
280 specifies the script that creates the database schema. Defaults to
281 Open-ILS/src/sql/pg/build-db.sh
284 specifies the offline database settings file required by the offline
285 data uploader. Defaults to /openils/conf/offline-config.pl
289 Configures Evergreen database settings in the file specified by
293 Creates the database setting file required by the offline data uploader
296 Creates the Evergreen database schema according to the settings in
297 the file specified by --config-file.
300 Creates the database itself, provided the user and password options
301 represent a superuser.
305 Specify "all" or one or more of the following services to update:
310 * open-ils.reporter-store
313 DATABASE CONFIGURATION OPTIONS
314 --user username for the database
316 --password password for the user
318 --database name of the database
320 --hostname name or address of the database host
322 --port port number for database access
324 --admin-user administration user's user name
326 --admin-pass administration user's password
329 This script is normally used during the initial installation and
330 configuration process. This creates the database schema, sets
331 the administration user's user name and password, and modifies your
332 configuration files to include the correct database connection
335 For a single server install, or an install with one web/application
336 server and one database server, you will typically want to invoke this
337 script with a complete set of commands:
339 perl Open-ILS/src/support-scripts/eg_db_config.pl --update-config \
340 --service all --create-schema --create-offline \
341 --user <db-user> --password <db-pass> --hostname localhost --port 5432 \
342 --database evergreen --admin-user <admin-user> --admin-pass <admin-pass>
344 To update the configuration for a single service - for example, if you
345 replicated a database for reporting purposes - just issue the
346 --update-config command with the service identified and the changed
347 database parameters specified:
349 perl Open-ILS/src/support-scripts/eg_db_config.pl --update-config \
350 --service reporter --hostname foobar --password newpass