Teach eg_db_config.pl to generate offline-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 $offline_file = '';
32 my $prefix = '';
33 my $sysconfdir = '';
34 my @services;
35
36 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
37
38 # Get the directory for this script
39 my $script_dir = dirname($0);
40
41 sub update_config {
42         # Puts command line specified settings into xml file
43         my ($services, $settings) = @_;
44
45         my $parser = XML::LibXML->new();
46         my $opensrf_config = $parser->parse_file($config_file);
47
48         if (@$services) {
49                 foreach my $service (@$services) {
50                         foreach my $key (keys %$settings) {
51                                 next unless $settings->{$key};
52                                 my(@node) = $opensrf_config->findnodes("//$service//database/$key/text()");
53                                 foreach(@node) {
54                                         $_->setData($settings->{$key});
55                                 }
56                         }
57
58                 }
59         }
60         else {
61                 foreach my $key (keys %$settings) {
62                         my(@node) = $opensrf_config->findnodes("//database/$key/text()");
63                         foreach(@node) {
64                                 $_->setData($settings->{$key});
65                         }
66                 }
67         }
68
69         my $timestamp = sprintf("%d.%d.%d.%d.%d.%d",
70                 $year + 1900, $mon +1, $mday, $hour, $min, $sec);
71         if (copy($config_file, "$config_file.$timestamp")) {
72                 print "Backed up original configuration file to '$config_file.$timestamp'\n";
73         } else {
74                 print STDERR "Unable to write to '$config_file.$timestamp'; bailed out.\n";
75     }
76
77         $opensrf_config->toFile($config_file) or
78                 die "ERROR: Failed to update the configuration file '$config_file'\n";
79 }
80
81 # write out the DB bootstrapping config
82 sub create_db_bootstrap {
83         my ($setup, $settings) = @_;
84
85     open(FH, '>', $setup) or die "Could not write database setup to $setup\n";
86
87         print "Writing database bootstrapping configuration to $setup\n";
88
89         printf FH "\$main::config{dsn} = 'dbi:Pg:host=%s;dbname=%s;port=%d';\n",
90                 $settings->{host}, $settings->{db}, $settings->{port};
91
92         printf FH "\$main::config{usr} = '%s';\n", $settings->{user};
93         printf FH "\$main::config{pw} = '%s';\n", $settings->{pw};
94         
95         print FH "\$main::config{index} = 'config.cgi';\n";
96     close(FH);
97 }
98
99 # write out the offline config
100 sub create_offline_config {
101         my ($setup, $settings) = @_;
102
103     open(FH, '>', $setup) or die "Could not write offline database setup to $setup\n";
104
105         print "Writing offline database configuration to $setup\n";
106
107         printf FH "\$main::config{base_dir} = '%s/var/data/offline/';\n", $prefix;
108         printf FH "\$main::config{bootstrap} = '%s/opensrf_core.xml';\n", $sysconfdir;
109
110         printf FH "\$main::config{dsn} = 'dbi:Pg:host=%s;dbname=%s;port=%d';\n",
111                 $settings->{host}, $settings->{db}, $settings->{port};
112
113         printf FH "\$main::config{usr} = '%s';\n", $settings->{user};
114         printf FH "\$main::config{pw} = '%s';\n", $settings->{pw};
115
116     close(FH);
117 }
118 # Extracts database settings from opensrf.xml
119 sub get_settings {
120         my $settings = shift;
121
122         my $host = "/opensrf/default/apps/open-ils.storage/app_settings/databases/database/host/text()";
123         my $port = "/opensrf/default/apps/open-ils.storage/app_settings/databases/database/port/text()";
124         my $dbname = "/opensrf/default/apps/open-ils.storage/app_settings/databases/database/db/text()";
125         my $user = "/opensrf/default/apps/open-ils.storage/app_settings/databases/database/user/text()";
126         my $pw = "/opensrf/default/apps/open-ils.storage/app_settings/databases/database/pw/text()";
127
128         my $parser = XML::LibXML->new();
129         my $opensrf_config = $parser->parse_file($config_file);
130
131         $settings->{host} = $opensrf_config->findnodes($host);
132         $settings->{port} = $opensrf_config->findnodes($port);
133         $settings->{db} = $opensrf_config->findnodes($dbname);
134         $settings->{user} = $opensrf_config->findnodes($user);
135         $settings->{pw} = $opensrf_config->findnodes($pw);
136 }
137
138 # Creates the database schema by calling build-db.sh
139 sub create_schema {
140         my $settings = shift;
141
142         chdir(dirname($build_db_sh));
143         system(File::Spec->catfile('.', basename($build_db_sh)) . " " .
144                 $settings->{host} ." ".  $settings->{port} ." ". 
145                 $settings->{db} ." ".  $settings->{user} ." ". 
146                 $settings->{pw});
147         chdir($script_dir);
148 }
149
150 my $bootstrap;
151 my $offline;
152 my $cschema;
153 my $uconfig;
154 my %settings;
155
156 GetOptions("create-schema" => \$cschema, 
157                 "create-bootstrap" => \$bootstrap,
158                 "create-offline" => \$offline,
159                 "update-config" => \$uconfig,
160                 "bootstrap-file=s" => \$bootstrap_file,
161                 "config-file=s" => \$config_file,
162                 "build-db-file=s" => \$build_db_sh,
163                 "service=s" => \@services,
164                 "user=s" => \$settings{'user'},
165                 "password=s" => \$settings{'pw'},
166                 "database=s" => \$settings{'db'},
167                 "hostname=s" => \$settings{'host'},
168                 "port=i" => \$settings{'port'}, 
169                 "help" => \$help
170 );
171
172 if (grep(/^all$/, @services)) {
173         @services = qw/reporter open-ils.cstore open-ils.storage open-ils.reporter-store/;
174 }
175
176 my $eg_config = File::Spec->catfile($script_dir, '../extras/eg_config');
177
178 if (!$config_file) { 
179         my @temp = `$eg_config --sysconfdir`;
180         chomp $temp[0];
181         $sysconfdir = $temp[0];
182         $config_file = File::Spec->catfile($sysconfdir, "opensrf.xml");
183 }
184
185 if (!$prefix) {
186         my @temp = `$eg_config --prefix`;
187         chomp $temp[0];
188         $prefix = $temp[0];
189 }
190
191 if (!$build_db_sh) {
192         $build_db_sh = File::Spec->catfile($script_dir, '../sql/Pg/build-db.sh');
193 }
194
195 if (!$bootstrap_file) {
196         $bootstrap_file = File::Spec->catfile($sysconfdir, 'live-db-setup.pl');
197 }
198
199 if (!$offline_file) {
200         $offline_file = File::Spec->catfile($sysconfdir, 'offline-config.pl');
201 }
202
203 unless (-e $build_db_sh) { die "Error: $build_db_sh does not exist. \n"; }
204 unless (-e $config_file) { die "Error: $config_file does not exist. \n"; }
205
206 if ($uconfig) { update_config(\@services, \%settings); }
207
208 # Get our settings from the config file
209 get_settings(\%settings);
210
211 if ($cschema) { create_schema(\%settings); }
212 if ($bootstrap) { create_db_bootstrap($bootstrap_file, \%settings); }
213 if ($offline) { create_offline_config($offline_file, \%settings); }
214
215 if ((!$cschema && !$uconfig && !$bootstrap && !$offline) || $help) {
216         print <<HERE;
217
218 SYNOPSIS
219     eg_db_config.pl [OPTION] ... [COMMAND] ... [CONFIG OPTIONS]
220
221 DESCRIPTION
222     Creates or recreates the Evergreen database schema based on the settings
223     in the opensrf.xml configuration file.
224
225     Manipulates the configuration file 
226
227 OPTIONS
228     --config-file
229         specifies the opensrf.xml file. Defaults to /openils/conf/opensrf.xml
230
231     --bootstrap-file
232         specifies the database bootstrap file required by the CGI setup
233         interface. Defaults to /openils/conf/live-db-setup.pl
234
235     --build-db-file
236         specifies the script that creates the database schema. Defaults to
237         Open-ILS/src/sql/pg/build-db.sh
238
239     --offline-file
240         specifies the offline database settings file required by the offline
241         data uploader. Defaults to /openils/conf/offline-config.pl
242
243 COMMANDS
244     --update-config
245         Configures Evergreen database settings in the file specified by
246         --build-db-file.  
247
248     --create-bootstrap
249         Creates the database bootstrap file required by the CGI setup interface
250
251     --create-offline
252         Creates the database setting file required by the offline data uploader
253
254     --create-schema
255         Creates the Evergreen database schema according to the settings in
256         the file specified by --config-file.  
257
258 SERVICE OPTIONS
259     --service
260         Specify "all" or one or more of the following services to update:
261             * reporter
262             * open-ils.cstore
263             * open-ils.storage
264             * open-ils.reporter-store
265     
266 DATABASE CONFIGURATION OPTIONS
267     --user            username for the database 
268
269     --password        password for the user 
270
271     --database        name of the database 
272
273     --hostname        name or address of the database host 
274
275     --port            port number for database access
276
277 EXAMPLES
278    This script is normally used during the initial installation and
279    configuration process.
280
281    For a single server install, or an install with one web/application
282    server and one database server, you will typically want to invoke this
283    script with a complete set of commands:
284
285    perl Open-ILS/src/support-scripts/eg_db_config.pl --update-config \
286        --service all --create-schema --create-bootstrap --create-offline \
287        --user evergreen --password evergreen --hostname localhost --port 5432 \
288        --database evergreen 
289
290    To update the configuration for a single service - for example, if you
291    replicated a database for reporting purposes - just issue the
292    --update-config command with the service identified and the changed
293    database parameters specified:
294
295    perl Open-ILS/src/support-scripts/eg_db_config.pl --update-config \
296        --service reporter --hostname foobar --password newpass
297
298 HERE
299 }