systemd Service: Abhängigkeiten gefixt; User ergänzt; ProtectXZY ergänzt
[kivitendo-erp.git] / scripts / installation_check.pl
1 #!/usr/bin/perl -w
2
3 use strict;
4 use Getopt::Long;
5 use Pod::Usage;
6 use Term::ANSIColor;
7 use Text::Wrap;
8 our $master_templates;
9 BEGIN {
10   unshift @INC, "modules/override"; # Use our own versions of various modules (e.g. YAML).
11   push    @INC, "modules/fallback"; # Only use our own versions of modules if there's no system version.
12
13   # this is a default dir. may be wrong in your installation, change it then
14   $master_templates = './templates/print/';
15 }
16
17 unless (eval { require Config::Std; 1 }){
18   print STDERR <<EOL ;
19 +------------------------------------------------------------------------------+
20   Perl Modul Config::Std could not be loaded.
21
22   Debian: you may install the needed *.deb package with:
23     apt-get install libconfig-std-perl
24
25   Red Hat/Fedora/CentOS: you may install the needed *.rpm package with:
26     yum install perl-Config-Std
27
28   SUSE: you may install the needed *.rpm package with:
29     zypper install perl-Config-Std
30
31 +------------------------------------------------------------------------------+
32 EOL
33
34   exit 72;
35 }
36
37 use SL::InstallationCheck;
38 use SL::LxOfficeConf;
39
40 my @missing_modules;
41 my %check;
42 Getopt::Long::Configure ("bundling");
43 GetOptions(
44   "v|verbose"   => \ my $v,
45   "a|all"       => \ $check{a},
46   "o|optional!" => \ $check{o},
47   "d|devel!"    => \ $check{d},
48   "l|latex!"    => \ $check{l},
49   "r|required!" => \ $check{r},
50   "h|help"      => sub { pod2usage(-verbose => 2) },
51   "c|color!"    => \ ( my $c = 1 ),
52   "i|install-command!"  => \ my $apt,
53   "s|silent"    => \ $check{s},
54 );
55
56 my %install_methods = (
57   apt    => { key => 'debian', install => 'sudo apt-get install', system => "Debian, Ubuntu" },
58   yum    => { key => 'fedora', install => 'sudo yum install',     system => "RHEL, Fedora, CentOS" },
59   zypper => { key => 'suse',   install => 'sudo zypper install',  system => "SLES, openSUSE" },
60   cpan   => { key => 'name',   install => "sudo cpan",            system => "CPAN" },
61 );
62
63 # if nothing is requested check "required"
64 my $default_run;
65 if (!defined $check{a}
66  && !defined $check{l}
67  && !defined $check{o}
68  && !defined $check{d}) {
69   $check{r} = 1;
70   $default_run ='1';  # no parameter, therefore print a note after default run
71 }
72
73 if ($check{a}) {
74   $check{$_} //= 1 for qw(o d l r);
75 }
76
77
78 $| = 1;
79
80 if (!SL::LxOfficeConf->read(undef, 'may fail')) {
81   print_header('Could not load the config file. If you have dependancies from any features enabled in the configuration these will still show up as optional because of this. Please rerun this script after installing the dependancies needed to load the configuration.')
82 } else {
83   SL::InstallationCheck::check_for_conditional_dependencies();
84 }
85
86 if ($check{r}) {
87   print_header('Checking Required Modules');
88   check_module($_, required => 1) for @SL::InstallationCheck::required_modules;
89 }
90 if ($check{o}) {
91   print_header('Checking Optional Modules');
92   check_module($_, optional => 1) for @SL::InstallationCheck::optional_modules;
93   check_aqbanking();
94 }
95 if ($check{d}) {
96   print_header('Checking Developer Modules');
97   check_module($_, devel => 1) for @SL::InstallationCheck::developer_modules;
98 }
99 if ($check{l}) {
100   check_latex();
101 }
102
103 my $fail = @missing_modules;
104 print_header('Result');
105 print_line('All', $fail ? 'NOT ok' : 'OK', $fail ? 'red' : 'green');
106
107 if ($default_run && !$check{s}) {
108   if (@missing_modules) {
109     $apt = 1;
110   print <<"EOL";
111
112 HEY! It seems there are modules MISSING! Look for the red lines with "NOT ok"
113 above. You'll want to fix those, I've enabled --install-command for you...
114 EOL
115   } else {
116   print <<"EOL";
117
118 Standard check done, everything is OK and up to date. Have a look at the --help
119 section of this script to see some more advanced checks for developer and
120 optional dependancies, as well as LaTeX packages you might need.
121 EOL
122   }
123 }
124
125 if (@missing_modules && $apt && !$check{s}) {
126   print "\nHere are some sample installation lines, choose one appropriate for your system:\n\n";
127   local $Text::Wrap::separator = " \\\n";
128
129   for (keys %install_methods) {
130     my $method = $install_methods{$_};
131     if (my @install_candidates = grep $_, map { $_->{$method->{key}} } @missing_modules) {
132       print "$method->{system}:\n";
133       print wrap("  ", "    ",  $method->{install}, @install_candidates);
134       print $/;
135     }
136   }
137 }
138
139 exit !!@missing_modules;
140
141 sub check_latex {
142   my ($res) = check_kpsewhich();
143   print_result("Looking for LaTeX kpsewhich", $res);
144   if ($res) {
145     check_template_dir($_) for SL::InstallationCheck::template_dirs($master_templates);
146   }
147 }
148
149 sub check_template_dir {
150   my ($dir) = @_;
151   my $path  = $master_templates . $dir;
152
153   print_header("Checking LaTeX Dependencies for Master Templates '$dir'");
154   kpsewhich($path, 'cls', $_) for SL::InstallationCheck::classes_from_latex($path, '\documentclass');
155   kpsewhich($path, 'sty', $_) for SL::InstallationCheck::classes_from_latex($path, '\usepackage');
156 }
157
158 our $mastertemplate_path = './templates/print/';
159
160 sub check_kpsewhich {
161   return 1 if SL::InstallationCheck::check_kpsewhich();
162
163   print STDERR <<EOL if $v && !$check{s};
164 +------------------------------------------------------------------------------+
165   Can't find kpsewhich, is there a proper installed LaTeX?
166   On Debian you may run "aptitude install texlive-base-bin"
167 +------------------------------------------------------------------------------+
168 EOL
169   return 0;
170 }
171
172 sub kpsewhich {
173   my ($dw, $type, $package) = @_;
174   $package =~ s/[^-_0-9A-Za-z]//g;
175   my $type_desc = $type eq 'cls' ? 'document class' : 'package';
176
177   eval { use String::ShellQuote; 1 } or warn "can't load String::ShellQuote" && return;
178      $dw         = shell_quote $dw;
179   my $e_package  = shell_quote $package;
180   my $e_type     = shell_quote $type;
181
182   my $exit = system(qq|TEXINPUTS=".:$dw:" kpsewhich $e_package.$e_type > /dev/null|);
183   my $res  = $exit > 0 ? 0 : 1;
184
185   print_result("Looking for LaTeX $type_desc $package", $res);
186   if (!$res) {
187     print STDERR <<EOL if $v && !$check{s};
188 +------------------------------------------------------------------------------+
189   LaTeX $type_desc $package could not be loaded.
190
191   On Debian you may find the needed *.deb package with:
192     apt-file search $package.$type
193
194   Maybe you need to install apt-file first by:
195     aptitude install apt-file && apt-file update
196 +------------------------------------------------------------------------------+
197 EOL
198   }
199 }
200
201 sub check_aqbanking {
202   my $aqbin = $::lx_office_conf{applications}->{aqbanking};
203   if ( !$aqbin ) {
204     print_line('Looking for aqbanking executable', 'not configured','red');
205   }
206   else {
207     my $line = "Looking for aqbanking executable '".$aqbin."'";
208     my $shell_out = `$aqbin versions 2>&1 | grep AqBanking-CLI 2> /dev/null`;
209     my ($label,$version)  = split /:/,$shell_out;
210     if ( $label && $label eq ' AqBanking-CLI' ) {
211       chop $version;
212       print_line($line, $version, 'green');
213     } else {
214       print_line($line, 'not installed','red');
215       my %modinfo = ( name => 'aqbanking' );
216       push @missing_modules, \%modinfo;
217     }
218   }
219 }
220
221 sub check_module {
222   my ($module, %role) = @_;
223
224   my $line = "Looking for $module->{fullname}";
225   $line   .= " (from $module->{dist_name})" if $module->{dist_name};
226   my ($res, $ver) = SL::InstallationCheck::module_available($module->{"name"}, $module->{version});
227   if ($res) {
228     my $ver_string = ref $ver && $ver->can('numify') ? $ver->numify : $ver ? $ver : 'no version';
229     print_line($line, $ver_string, 'green');
230   } else {
231     print_result($line, $res);
232   }
233
234
235   return if $res;
236
237   push @missing_modules, $module;
238
239   my $needed_text =
240       $role{optional} ? 'It is OPTIONAL for kivitendo but RECOMMENDED for improved functionality.'
241     : $role{required} ? 'It is NEEDED by kivitendo and must be installed.'
242     : $role{devel}    ? 'It is OPTIONAL for kivitendo and only useful for developers.'
243     :                   'It is not listed as a dependancy yet. Please tell this the developers.';
244
245   my @source_texts = module_source_texts($module);
246   local $" = $/;
247   print STDERR <<EOL if $v && !$check{s};
248 +------------------------------------------------------------------------------+
249   $module->{fullname} could not be loaded.
250
251   This module is either too old or not available on your system.
252   $needed_text
253
254   Here are some ideas how to get it:
255
256 @source_texts
257 +------------------------------------------------------------------------------+
258 EOL
259 }
260
261 sub module_source_texts {
262   my ($module) = @_;
263   my @texts;
264   for my $key (keys %install_methods) {
265     my $method = $install_methods{$key};
266     push @texts, <<"EOL" if $module->{$method->{key}};
267   - Using $method->{system} you can install it with $key:
268       $method->{install} $module->{$method->{key}}
269 EOL
270   }
271   push @texts, <<EOL if $module->{url};
272   - You can download it from this URL and install it manually:
273       $module->{url}
274 EOL
275
276   return @texts;
277 }
278
279 sub mycolor {
280   return $_[0] unless $c;
281   return colored(@_);
282 }
283
284 sub print_result {
285   my ($test, $exit) = @_;
286   if ($exit) {
287     print_line($test, 'ok', 'green');
288   } else {
289     print_line($test, 'NOT ok', 'red');
290   }
291 }
292
293 sub print_line {
294   my ($text, $res, $color) = @_;
295   return if $check{s};
296   print $text, " ", ('.' x (78 - length($text) - length($res))), " ", mycolor($res, $color), $/;
297 }
298
299 sub print_header {
300   return if $check{s};
301   print $/;
302   print "$_[0]:", $/;
303 }
304
305 1;
306
307 __END__
308
309 =encoding UTF-8
310
311 =head1 NAME
312
313 scripts/installation_check.pl - check kivitendo dependancies
314
315 =head1 SYNOPSIS
316
317   scripts/installation_check.pl [OPTION]
318
319 =head1 DESCRIPTION
320
321 Check dependencys. List all perl modules needed by kivitendo, probes for them,
322 and warns if one is not available.  List all LaTeX document classes and
323 packages needed by kivitendo master templates, probes for them, and warns if
324 one is not available.
325
326
327 =head1 OPTIONS
328
329 =over 4
330
331 =item C<-a, --all>
332
333 Probe for all perl modules and all LaTeX master templates.
334
335 =item C<-c, --color>
336
337 Color output. Default on.
338
339 =item C<--no-color>
340
341 No color output. Helpful to avoid terminal escape problems.
342
343 =item C<-d, --devel>
344
345 Probe for perl developer dependancies. (Used for console  and tags file)
346
347 =item C<--no-devel>
348
349 Don't probe for perl developer dependancies. (Useful in combination with --all)
350
351 =item C<-h, --help>
352
353 Display this help.
354
355 =item C<-o, --optional>
356
357 Probe for optional modules.
358
359 =item C<--no-optional>
360
361 Don't probe for optional perl modules. (Useful in combination with --all)
362
363 =item C<-r, --required>
364
365 Probe for required perl modules (default).
366
367 =item C<--no-required>
368
369 Don't probe for required perl modules. (Useful in combination with --all)
370
371 =item C<-l. --latex>
372
373 Probe for LaTeX documentclasses and packages in master templates.
374
375 =item C<--no-latex>
376
377 Don't probe for LaTeX document classes and packages in master templates. (Useful in combination with --all)
378
379 =item C<-v. --verbose>
380
381 Print additional info for missing dependancies
382
383 =item C<-i, --install-command>
384
385 Tries to generate installation commands for the most common package managers.
386 Note that these lists can be slightly off, but it should still save you a lot
387 of typing.
388
389 =back
390
391 =head1 BUGS, CAVEATS and TODO
392
393 =over 4
394
395 =item *
396
397 Fedora packages not listed yet.
398
399 =item *
400
401 Not possible yet to generate a combined cpan/apt-get string to install all needed.
402
403 =item *
404
405 Not able to handle devel cpan modules yet.
406
407 =item *
408
409 Version requirements not fully tested yet.
410
411 =back
412
413 =head1 AUTHOR
414
415   Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
416   Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
417   Wulf Coulmann E<lt>wulf@coulmann.deE<gt>
418
419 =cut