]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/support-scripts/settings-tester.pl
Disable strict refs (really)
[Evergreen.git] / Open-ILS / src / support-scripts / settings-tester.pl
1 #!/usr/bin/perl
2 # vim:noet:ts=4:
3 use strict;
4 use warnings;
5
6 BEGIN {
7         eval "use OpenSRF::Utils::Config;";
8         die "Please ensure that /openils/lib/perl5 is in your PERL5LIB environment variable.
9         You must run this script as the 'opensrf' user.\n" if ($@);
10         eval "use Error qw/:try/;";
11         die "Please install Error.pm.\n" if ($@);
12         eval "use UNIVERSAL::require;";
13         die "Please install the UNIVERSAL::require perl module.\n" if ($@);
14         eval "use Getopt::Long;";
15         die "Please install the Getopt::Long perl module.\n" if ($@);
16         eval "use Net::Domain;";
17         die "Please install the Net::Domain perl module.\n" if ($@);
18 }
19
20 my $output = '';
21 my $perloutput = '';
22 my $result;
23
24 my ($gather, $hostname, $core_config, $tmpdir) =
25         (0, Net::Domain::hostfqdn(), '/openils/conf/opensrf_core.xml', '/tmp/');
26
27 GetOptions(
28         'gather' => \$gather,
29         'hostname=s' => \$hostname,
30         'config_file=s' => \$core_config,
31         'tempdir=s' => \$tmpdir,
32 );
33
34 while (my $mod = <DATA>) {
35         chomp $mod;
36         my @list = split / /, $mod;
37
38         my $ok = 0;
39         for my $m (@list) {
40                 $ok++ if ($m->use);
41                 # Disable strict refs for now
42                 no strict 'refs';
43                 print "$m version ".${$m."::VERSION"}."\n" unless ($@);
44         }
45
46         unless ($ok) {
47                 if (@list == 1) {
48                         warn "Please install $mod\n";
49                         $perloutput .= "Please install the $mod Perl module.\n";
50                 } else {
51                         warn "Please install one of the following modules: $mod\n";
52                         $perloutput .= "Please install one of the following modules: $mod\n";
53                 }
54         }
55                         
56 }
57
58 use OpenSRF::Transport::SlimJabber::Client;
59 use OpenSRF::Utils::SettingsParser;
60 use OpenSRF::Utils::SettingsClient;
61 use Data::Dumper;
62 use DBI;
63
64 (my $conf_dir = $core_config) =~ s#(.*)/.*#$1#;
65
66
67 OpenSRF::Utils::Config->load(config_file => $core_config);
68 my $conf = OpenSRF::Utils::Config->current;
69 my $j_username    = $conf->bootstrap->username;
70 my $j_password    = $conf->bootstrap->passwd;
71 my $j_port    = $conf->bootstrap->port;
72 my $j_domain    = $conf->bootstrap->domains->[0];
73 my $settings_config = $conf->bootstrap->settings_config;
74 my $logfile    = $conf->bootstrap->logfile;
75 (my $log_dir = $logfile) =~ s#(.*)/.*#$1#;
76
77
78 print "\nChecking Jabber connection\n";
79 # connect to jabber 
80 my $client = OpenSRF::Transport::SlimJabber::Client->new(
81     port => $j_port, 
82     username => $j_username, 
83     password => $j_password,
84     host => $j_domain,
85     resource => 'test123'
86 );
87
88
89 my $je = undef;
90 try {
91     unless($client->initialize()) {
92         $je = "* Unable to connect to jabber server $j_domain\n";
93         warn "* Unable to connect to jabber server $j_domain\n";
94     }
95 } catch Error with {
96     $je = "* Error connecting to jabber:\n" . shift() . "\n";
97     warn "* Error connecting to jabber:\n" . shift() . "\n";
98 };
99
100 print "* Jabber successfully connected\n" unless ($je);
101 $output .= ($je) ? $je : "* Jabber successfully connected\n";
102
103 my $xmlparser = XML::LibXML->new();
104 my $osrfxml = $xmlparser->parse_file($settings_config);
105
106 print "\nChecking database connections\n";
107 # Check database connections
108 my @databases = $osrfxml->findnodes('//database');
109 foreach my $database (@databases) {
110         my $db_name = $database->findvalue("./db");     
111         if (!$db_name) {
112                 $db_name = $database->findvalue("./name");      
113         }
114         my $db_host = $database->findvalue("./host");   
115         my $db_port = $database->findvalue("./port");   
116         my $db_user = $database->findvalue("./user");   
117         my $db_pw = $database->findvalue("./pw");       
118     if (!$db_pw && $database->parentNode->parentNode->nodeName eq 'reporter') {
119         $db_pw = $database->findvalue("./password");
120         warn "* WARNING: Deprecated <password> element used for the <reporter> entry.  ".
121             "Please use <pw> instead.\n" if ($db_pw);
122     }
123
124         my $osrf_xpath;
125         foreach my $node ($database->findnodes("ancestor::node()")) {
126                 next unless $node->nodeType == XML::LibXML::XML_ELEMENT_NODE;
127                 $osrf_xpath .= "/" . $node->nodeName;
128         }
129         $output .= test_db_connect($db_name, $db_host, $db_port, $db_user, $db_pw, $osrf_xpath);
130 }
131
132 print "\nChecking database drivers to ensure <driver> matches <language>\n";
133 # Check database drivers
134 # if language eq 'C', driver eq 'pgsql'
135 # if language eq 'perl', driver eq 'Pg'
136 my @drivers = $osrfxml->findnodes('//driver');
137 foreach my $driver_node (@drivers) {
138         my $language;
139         my $driver_xpath;
140         my @driver_xpath_nodes;
141         foreach my $node ($driver_node->findnodes("ancestor::node()")) {
142                 next unless $node->nodeType == XML::LibXML::XML_ELEMENT_NODE;
143                 $driver_xpath .= "/" . $node->nodeName;
144                 push @driver_xpath_nodes, $node->nodeName;
145         }
146         my $lang_xpath;
147         my $driver = $driver_node->findvalue("child::text()");
148         while (pop(@driver_xpath_nodes) && scalar(@driver_xpath_nodes) > 0 && !$language) {
149                 $lang_xpath = "/" . join('/', @driver_xpath_nodes) . "/language";
150                 my @lang_nodes = $osrfxml->findnodes($lang_xpath);
151                 next unless scalar(@lang_nodes > 0);
152                 $language = $lang_nodes[0]->findvalue("child::text()");
153         }
154         if ($driver eq "pgsql") {
155                 if ($language eq "C") {
156                         $result = "* OK: $driver language is $language in $lang_xpath\n";
157                 } else {
158                         $result = "* ERROR: $driver language is $language in $lang_xpath\n";
159                         warn $result;
160                 }
161         } elsif ($driver eq "Pg") {
162                 if ($driver_xpath =~ /reporter/) {
163                         $result = "* OK: $driver language is undefined for reporter base configuration\n";
164                 } elsif ($language eq "perl") {
165                         $result = "* OK: $driver language is $language in $lang_xpath\n";
166                 } else {
167                         $result = "* ERROR: $driver language is $language in $lang_xpath\n";
168                         warn $result;
169                 }
170         } else {
171                 $result = "* ERROR: Unknown driver $driver in $driver_xpath\n";
172                 warn $result;
173         }
174         print $result;
175         $output .= $result;
176 }
177
178 print "\nChecking libdbi and libdbi-drivers\n";
179 $output .= check_libdbd();
180
181 print "\nChecking hostname\n";
182 my @hosts = $osrfxml->findnodes('/opensrf/hosts/*');
183 foreach my $host (@hosts) {
184         next unless $host->nodeType == XML::LibXML::XML_ELEMENT_NODE;
185         my $osrfhost = $host->nodeName;
186         my $he;
187         if ($osrfhost ne $hostname && $osrfhost ne "localhost") {
188                 $result = " * ERROR: expected hostname '$hostname', found '$osrfhost' in <hosts> section of opensrf.xml\n";
189                 warn $result;
190                 $he = 1;
191         } elsif ($osrfhost eq "localhost") {
192                 $result = " * OK: found hostname 'localhost' in <hosts> section of opensrf.xml\n";
193         } else {
194                 $result = " * OK: found hostname '$hostname' in <hosts> section of opensrf.xml\n";
195         }
196         print $result unless $he;
197         $output .= $result;
198 }
199
200
201 if ($gather) {
202         get_debug_info( $tmpdir, $log_dir, $conf_dir, $perloutput, $output );
203 }
204
205 sub test_db_connect {
206         my ($db_name, $db_host, $db_port, $db_user, $db_pw, $osrf_xpath) = @_;
207
208         my $dsn = "dbi:Pg:dbname=$db_name;host=$db_host;port=$db_port";
209         my $de = undef;
210         my ($dbh, $encoding);
211         try {
212                 $dbh = DBI->connect($dsn, $db_user, $db_pw);
213                 unless($dbh) {
214                         $de = "* $osrf_xpath :: Unable to connect to database $dsn, user=$db_user, password=$db_pw\n";
215                         warn "* $osrf_xpath :: Unable to connect to database $dsn, user=$db_user, password=$db_pw\n";
216                 }
217                 my $sth = $dbh->prepare("show server_encoding");
218                 $sth->execute;
219                 $sth->bind_col(1, \$encoding);
220                 $sth->fetch;
221                 $sth->finish;
222                 $dbh->disconnect;
223         } catch Error with {
224                 $de = "* $osrf_xpath :: Unable to connect to database $dsn, user=$db_user, password=$db_pw\n" . shift() . "\n";
225                 warn "* $osrf_xpath :: Unable to connect to database $dsn, user=$db_user, password=$db_pw\n" . shift() . "\n";
226         };
227         print "* $osrf_xpath :: Successfully connected to database $dsn\n" unless ($de);
228         if ($encoding !~ m/(utf-?8|unicode)/i) {
229                 $de .= "* ERROR: $osrf_xpath :: Database $dsn has encoding $encoding instead of UTF8 or UNICODE.\n";
230                 warn "* ERROR: $osrf_xpath :: Database $dsn has encoding $encoding instead of UTF8 or UNICODE.\n";
231         } else {
232                 print "  * Database has the expected server encoding $encoding.\n";
233         }
234         return ($de) ? $de : "* $osrf_xpath :: Successfully connected to database $dsn with encoding $encoding\n";
235
236 }
237
238 sub check_libdbd {
239         my $results = '';
240         my @location = `locate libdbdpgsql.so |grep -v home`; # simple(ton) attempt to filter out build versions
241         if (scalar(@location) > 1) {
242
243                 my $res = "Found more than one location for libdbdpgsql.so.
244   We have found that system packages don't link against libdbi.so;
245   therefore, we strongly recommend compiling libdbi and libdbi-drivers from source.\n";
246                 $results .= $res;
247                 print $res;
248         }
249         foreach my $loc (@location) {
250                 my @linkage = `ldd $loc`;
251                 if (!grep(/libdbi/, @linkage)) {
252                         my $res = "$loc was not linked against libdbi - you probably need to compile libdbi-drivers from source with the --enable-libdbi configure switch.\n";
253                         $results .= $res;
254                         print $res;
255                 }
256         }
257         return $results;
258 }
259
260 sub get_debug_info {
261   my $temp_dir = shift; # place we can write files
262   my $log = shift; # location of the log directory
263   my $config = shift; # location of the config files
264   my $perl_test = shift; # output from the Perl prereq testing
265   my $config_test = shift; # output from the config file testing
266
267   my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
268   my $oils_time = sprintf("%04d-%02d-%02d_%02dh-%02d-%02d", $year+1900, $mon, $mday, $hour, $min, $sec);
269   
270   # evil approach that requires no other Perl dependencies
271   chdir($temp_dir);
272   my $oils_debug_dir = "$temp_dir/oils_$oils_time";
273
274   # Replace with something Perlish
275   mkdir($oils_debug_dir) or die $!;
276
277   # Replace with File::Copy
278   system("cp $log/*log $oils_debug_dir");
279
280   # Passwords will go through in the clear for now
281   system("cp $config/*xml $oils_debug_dir");
282
283   # Get Perl output
284   open(FH, ">", "$oils_debug_dir/perl_test.out") or die $!;
285   print FH $perl_test;
286   close(FH);
287
288   # Get XML output
289   open(FH, ">", "$oils_debug_dir/xml_test.out") or die $!;
290   print FH $config_test;
291   close(FH);
292   
293   # Tar this up - does any system not have tar?
294   system("tar czf oils_$oils_time.tar.gz oils_$oils_time");
295
296   # Clean up after ourselves, somewhat dangerously
297   system("rm -fr $oils_debug_dir");
298
299   print "Wrote your debug information to $temp_dir/oils_$oils_time.tar.gz.\n";
300 }
301
302 __DATA__
303 LWP::UserAgent
304 XML::LibXML
305 XML::LibXSLT
306 Net::Server::PreFork
307 Cache::Memcached
308 Class::DBI
309 Class::DBI::AbstractSearch
310 Template
311 DBD::Pg
312 Net::Z3950 Net::Z3950::ZOOM
313 MARC::Record
314 MARC::Charset
315 MARC::File::XML
316 Text::Aspell
317 CGI
318 DateTime::TimeZone
319 DateTime
320 DateTime::Format::ISO8601
321 Unix::Syslog
322 GD::Graph3d
323 JavaScript::SpiderMonkey
324 Log::Log4perl
325 Email::Send
326 Text::CSV
327 Text::CSV_XS
328 Spreadsheet::WriteExcel::Big
329 Tie::IxHash