Add the ability to generate live-db-setup.pl to eg_db_config.pl
[Evergreen.git] / Open-ILS / src / support-scripts / eg_db_config.pl
1 #!/usr/bin/perl
2 # eg_db_config.pl -- configure Evergreen database settings and create schema
3 # vim:noet:ts=4:sw=4:
4 #
5 # Copyright (C) 2008 Equinox Software, Inc.
6 # Copyright (C) 2008 Laurentian University
7 # Author: Kevin Beswick <kevinbeswick00@gmail.com>
8 # Author: Dan Scott <dscott@laurentian.ca>
9 #
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.
14 #
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.
19
20 use strict; use warnings;
21 use XML::LibXML;
22 use File::Copy;
23 use Getopt::Long;
24 use File::Spec;
25 use File::Basename;
26
27 my ($dbhost, $dbport, $dbname, $dbuser, $dbpw, $help);
28 my $config_file = '';
29 my $build_db_sh = '';
30 my $bootstrap_file = '';
31 my @services;
32
33 # Get the directory for this script
34 my $script_dir = dirname($0);
35
36 sub update_config {
37         # Puts command line specified settings into xml file
38         my ($services, $settings) = @_;
39
40         my $parser = XML::LibXML->new();
41         my $opensrf_config = $parser->parse_file($config_file);
42
43         if (@$services) {
44                 foreach my $service (@$services) {
45                         foreach my $key (keys %$settings) {
46                                 next unless $settings->{$key};
47                                 my(@node) = $opensrf_config->findnodes("//$service//database/$key/text()");
48                                 foreach(@node) {
49                                         $_->setData($settings->{$key});
50                                 }
51                         }
52
53                 }
54         }
55         else {
56                 foreach my $key (keys %$settings) {
57                         my(@node) = $opensrf_config->findnodes("//database/$key/text()");
58                         foreach(@node) {
59                                 $_->setData($settings->{$key});
60                         }
61                 }
62         }
63
64         if (copy($config_file, "$config_file.bak")) {
65                 print "Backed up original configuration file to '$config_file.bak'\n";
66         } else {
67                 print STDERR "Unable to write to '$config_file.bak'; bailed out.\n";
68     }
69
70         $opensrf_config->toFile($config_file) or
71                 die "ERROR: Failed to update the configuration file '$config_file'\n";
72 }
73
74 # write out the DB bootstrapping config
75 sub create_db_bootstrap {
76         my ($setup, $settings) = @_;
77
78     open(FH, '>', $setup) or die "Could not write database setup to $setup\n";
79
80         print "Writing database bootstrapping configuration to $setup...\n";
81
82         printf FH "\$main::config{dsn} = 'dbi:Pg:host=%s;dbname=%s;port=%d';\n",
83                 $settings->{host}, $settings->{db}, $settings->{port};
84
85         printf FH "\$main::config{usr} = '%s';\n", $settings->{user};
86         printf FH "\$main::config{pw} = '%s';\n", $settings->{pw};
87         
88         print FH "\$main::config{index} = 'config.cgi';\n";
89     close(FH);
90 }
91
92 # Extracts database settings from opensrf.xml
93 sub get_settings {
94         my $settings = shift;
95
96         my $host = "/opensrf/default/apps/open-ils.storage/app_settings/databases/database/host/text()";
97         my $port = "/opensrf/default/apps/open-ils.storage/app_settings/databases/database/port/text()";
98         my $dbname = "/opensrf/default/apps/open-ils.storage/app_settings/databases/database/db/text()";
99         my $user = "/opensrf/default/apps/open-ils.storage/app_settings/databases/database/user/text()";
100         my $pw = "/opensrf/default/apps/open-ils.storage/app_settings/databases/database/pw/text()";
101
102         my $parser = XML::LibXML->new();
103         my $opensrf_config = $parser->parse_file($config_file);
104
105         $settings->{host} = $opensrf_config->findnodes($host);
106         $settings->{port} = $opensrf_config->findnodes($port);
107         $settings->{db} = $opensrf_config->findnodes($dbname);
108         $settings->{user} = $opensrf_config->findnodes($user);
109         $settings->{pw} = $opensrf_config->findnodes($pw);
110 }
111
112 # Creates the database schema by calling build-db.sh
113 sub create_schema {
114         my $settings = shift;
115
116         chdir(dirname($build_db_sh));
117         system(File::Spec->catfile('.', basename($build_db_sh)) . " " .
118                 $settings->{host} ." ".  $settings->{port} ." ". 
119                 $settings->{db} ." ".  $settings->{user} ." ". 
120                 $settings->{pw});
121         chdir($script_dir);
122 }
123
124 my $bootstrap;
125 my $cschema;
126 my $uconfig;
127 my %settings;
128
129 GetOptions("create-schema" => \$cschema, 
130                 "create-bootstrap" => \$bootstrap,
131                 "update-config" => \$uconfig,
132                 "bootstrap-file=s" => \$bootstrap_file,
133                 "config-file=s" => \$config_file,
134                 "build-db-file=s" => \$build_db_sh,
135                 "service=s" => \@services,
136                 "user=s" => \$settings{'user'},
137                 "password=s" => \$settings{'pw'},
138                 "database=s" => \$settings{'db'},
139                 "hostname=s" => \$settings{'host'},
140                 "port=i" => \$settings{'port'}, 
141                 "help" => \$help
142 );
143
144 if (grep(/^all$/, @services)) {
145         @services = qw/reporter open-ils.cstore open-ils.storage open-ils.reporter-store/;
146 }
147
148 my $eg_config = File::Spec->catfile($script_dir, '../extras/eg_config');
149
150 if (!$config_file) { 
151         my @temp = `$eg_config --sysconfdir`;
152         chomp $temp[0];
153         $config_file = File::Spec->catfile($temp[0], "opensrf.xml");
154 }
155
156 if (!$build_db_sh) {
157         $build_db_sh = File::Spec->catfile($script_dir, '../sql/Pg/build-db.sh');
158 }
159
160 if (!$bootstrap_file) {
161         $bootstrap_file = ('/openils/var/cgi-bin/live-db-setup.pl');
162 }
163
164 unless (-e $build_db_sh) { die "Error: $build_db_sh does not exist. \n"; }
165 unless (-e $config_file) { die "Error: $config_file does not exist. \n"; }
166
167 if ($uconfig) { update_config(\@services, \%settings); }
168
169 # Get our settings from the config file
170 get_settings(\%settings);
171
172 if ($cschema) { create_schema(); }
173 if ($bootstrap) { create_db_bootstrap($bootstrap_file, \%settings); }
174
175 if ((!$cschema && !$uconfig && !$bootstrap) || $help) {
176         print <<HERE;
177
178 SYNOPSIS
179     eg_db_config.pl [OPTION] ... [COMMAND] ... [CONFIG OPTIONS]
180
181 DESCRIPTION
182     Creates or recreates the Evergreen database schema based on the settings
183     in the opensrf.xml configuration file.
184
185     Manipulates the configuration file 
186
187 OPTIONS
188     --config-file
189         specifies the opensrf.xml file. Defaults to /openils/conf/opensrf.xml
190
191     --bootstrap-file
192         specifies the database bootstrap file required by the CGI setup interface
193
194     --build-db-file
195         specifies the script that creates the database schema. Defaults to
196         Open-ILS/src/sql/pg/build-db.sh
197
198 COMMANDS
199     --update-config
200         Configures Evergreen database settings in the file specified by
201         --build-db-file.  
202
203     --create-bootstrap
204         Creates the database bootstrap file required by the CGI setup interface
205
206     --create-schema
207         Creates the Evergreen database schema according to the settings in
208         the file specified by --config-file.  
209
210 SERVICE OPTIONS
211     --service
212         Specify "all" or one or more of the following services to update:
213             * reporter
214             * open-ils.cstore
215             * open-ils.storage
216             * open-ils.reporter-store
217     
218 DATABASE CONFIGURATION OPTIONS
219     --user            username for the database 
220
221     --password        password for the user 
222
223     --database        name of the database 
224
225     --hostname        name or address of the database host 
226
227     --port            port number for database access
228
229 EXAMPLES
230    This script is normally used during the initial installation and
231    configuration process.
232
233    For a single server install, or an install with one web/application
234    server and one database server, you will typically want to invoke this
235    script with a complete set of commands:
236
237    perl Open-ILS/src/support-scripts/eg_db_config.pl --update-config \
238        --service all --create-schema --create-bootstrap \
239        --user evergreen --password evergreen --hostname localhost --port 5432 \
240        --database evergreen 
241
242    To update the configuration for a single service - for example, if you
243    replicated a database for reporting purposes - just issue the
244    --update-config command with the service identified and the changed
245    database parameters specified:
246
247    perl Open-ILS/src/support-scripts/eg_db_config.pl --update-config \
248        --service reporter --hostname foobar --password newpass
249
250 HERE
251 }