Subversion Repositories camp_sysinfo_client_3

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
101 rodolico 1
#! /usr/bin/env perl
2
 
3
use strict;
4
use warnings;
5
 
132 rodolico 6
# install.pl
7
#
8
# installer for perl script, in this case, sysinfo
9
#
10
# Revision history
11
#
12
# Version 1.1.7 20161010 RWR
13
# Added ability to validate required libraries are installed
14
#
15
# version 1.2 20170327 RWR
16
# did some major modifications to correctly work on BSD systems also
17
#
18
# version 2.0 20190330 RWR
19
# changed it so all configs are YAML
20
#
21
# version 3.0 20191105 RWR
22
# set up so all options are presented on initial screen
23
# user can choose options to edit
24
# rest of install is automatic
138 rodolico 25
#
26
# version 3.1 20191112 RWR
27
# Added logging. Log file will be written to the install directory with
28
# the application name.log as the name (application name taken from installer_config.pl)
144 rodolico 29
#
30
# version 3.1.1 20191117 RWR
31
# Added the ability to verify cpan is installed and configured on systems which need it
32
#
156 rodolico 33
# version 3.1.2 20200215 RWR
34
# Adding version comparisons
101 rodolico 35
 
132 rodolico 36
# find our location and use it for searching for libraries
37
BEGIN {
38
   use FindBin;
39
   use File::Spec;
203 rodolico 40
   # use libraries from the directory this script is in
132 rodolico 41
   use lib File::Spec->catdir($FindBin::Bin);
203 rodolico 42
   # and its parent
43
   use lib File::Spec->catdir( $FindBin::Bin . '/../' );
132 rodolico 44
   eval( 'use YAML::Tiny' );
45
}
46
 
101 rodolico 47
my $sourceDir = File::Spec->catdir($FindBin::Bin);
48
 
156 rodolico 49
use Digest::MD5 qw(md5_hex);
208 rodolico 50
use File::Copy;
156 rodolico 51
 
52
# define the version number
53
# see https://metacpan.org/pod/release/JPEACOCK/version-0.97/lib/version.pod
54
use version;
203 rodolico 55
our $VERSION = version->declare("v3.002.001");
156 rodolico 56
 
57
 
132 rodolico 58
use Data::Dumper;
59
use File::Basename;
60
use Getopt::Long;
101 rodolico 61
 
132 rodolico 62
our %install;
63
our %operatingSystems;
64
our %libraries;
65
our %binaries;
206 rodolico 66
# load the definitions from installer_config.pl
132 rodolico 67
do "$sourceDir/installer_config.pl";
138 rodolico 68
#
69
# set up log file
70
my $logFile = $install{'application name'};
71
$logFile =~ s/ /_/g;
72
$logFile = "$sourceDir/$logFile.log";
132 rodolico 73
 
74
Getopt::Long::Configure ("bundling"); # allow -vd --os='debian'
75
my $dryRun = 0;
76
my $os;
77
my $help = 0;
78
my $version = 0;
206 rodolico 79
my $quiet = 0;
80
my $inplace = 0;
132 rodolico 81
 
82
my @messages; # stores any messages we want to show up at the end
83
my @feedback; # store feedback when we execute command line actions
84
 
85
my %configuration;
86
 
87
# simple display if --help is passed
88
sub help {
89
   my $oses = join( ' ', keys %operatingSystems );
156 rodolico 90
   use File::Basename;
91
   print basename($0) . " $VERSION\n";
132 rodolico 92
   print <<END
156 rodolico 93
$0 [options]
94
Options:
95
   --os      - osname is one of [$oses]
96
   --dryrun  - do not actually do anything, just tell you what I'd do
97
   --version - display version and exit
206 rodolico 98
   --quiet   - Do not ask questions, just do stuff
99
   --inplace - Do an inplace upgrade
100
 
101
For an inplace upgrade, it is assumed the source code has been
102
downloaded and installed into the correct directories already
132 rodolico 103
END
101 rodolico 104
}
105
 
138 rodolico 106
#######################################################
144 rodolico 107
#
108
# timeStamp
109
#
110
# return current system date as YYYY-MM-DD HH:MM:SS
111
#
112
#######################################################
113
sub timeStamp {
114
   my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
115
   return sprintf "%4d-%02d-%02d %02d:%02d:%02d",$year+1900,$mon+1,$mday,$hour,$min,$sec;
116
}
117
 
118
sub yesno {
119
   my ( $prompt, $default ) = @_;
120
   $default = 'yes' unless $default;
121
   my $answer = &getAnswer( $prompt, $default eq 'yes' ? ('yes','no' ) : ('no', 'yes') );
122
   return lc( substr( $answer, 0, 1 ) ) eq 'y';
123
}
124
 
125
# prompt the user for a response, then allow them to enter it
126
# the first response is considered the default and is printed
127
# in all caps if more than one exists
128
# first answer is used if they simply press the Enter
129
# key. The response is returned all lower case if more than one
130
# exists.
131
# it is assumed 
132
sub getAnswer {
133
   my ( $prompt, @answers ) = @_;
134
   $answers[0] = '' unless defined( $answers[0] );
135
   my $default = $answers[0];
136
   my $onlyOneAnswer = scalar( @answers ) == 1;
137
   print $prompt . '[ ';
138
   $answers[0] = uc $answers[0] unless $onlyOneAnswer;
139
   print join( ' | ', @answers ) . ' ]: ';
140
   my $thisAnswer = <>;
141
   chomp $thisAnswer;
142
   $thisAnswer = $default unless $thisAnswer;
143
   return $thisAnswer;
144
}
145
 
146
 
147
#######################################################
138 rodolico 148
# function to simply log things
149
# first parameter is the priority, if <= $logDef->{'log level'} will print
150
# all subsequent parameters assumed to be strings to sent to the log
151
# returns 0 on failure
152
#         1 on success
153
#         2 if priority > log level
154
#        -1 if $logDef is unset
155
# currently, only logs to a file
156
#######################################################
157
sub logIt {
140 rodolico 158
   open LOG, ">>$logFile" or die "Could not append to $logFile: $!\n";
138 rodolico 159
   while ( my $t = shift ) {
160
      print LOG &timeStamp() . "\t$t\n";
161
   }
162
   close LOG;
163
   return 1;
164
}
101 rodolico 165
 
138 rodolico 166
 
132 rodolico 167
# attempt to locate the operating system.
168
# if found, will set some defaults for it.
169
sub setUpOperatingSystemSpecific {
170
   my ( $install, $operatingSystems, $os, $installDir ) = @_;
138 rodolico 171
   &logIt( 'Entering setUpOperatingSystemSpecific' );
172
   &logIt( "They passed $os in as the \$os" );
132 rodolico 173
   if ( $os ) {
174
      # We found the OS, set up some defaults
175
      $$install{'os'} = $os;
138 rodolico 176
      &logIt( "Setting keys for operating system" );
132 rodolico 177
      # merge operatingSystems into install
178
      foreach my $key ( keys %{$operatingSystems->{$os}} ) {
179
         if ( $key eq 'files' ) {
180
            $install->{'files'} = { %{$install->{'files'}}, %{$operatingSystems->{$os}->{'files'}} }
181
         } else {
182
            $install->{$key} = $operatingSystems->{ $os }->{$key};
183
         }
184
      } # if it is a known OS
185
   } # if
186
   return $os;
187
} # getOperatingSystem
188
 
189
# validates the libraries needed exist
190
# simply eval's each library. If it doesn't exist, creates a list of
191
# commands to be executed to install it, and displays missing libraries
192
# offering to install them if possible.
193
sub validateLibraries {
194
   my ( $libraries, $os ) = @_;
138 rodolico 195
   &logIt( 'Entering validateLibraries' );
132 rodolico 196
   my %return;
197
   foreach my $lib ( keys %$libraries ) {
138 rodolico 198
      &logIt( "Checking on library $lib" );
132 rodolico 199
      eval( "use $lib;" );
200
      if ( $@ ) {
201
         $return{ $lib } = $libraries->{$lib}->{$os} ? $libraries->{$lib}->{$os} : 'UNK';
202
      }
203
   }
204
   return \%return;
205
} # validateLibraries
206
 
207
 
208
# check for any required binaries
209
sub validateBinaries {
210
   my ( $binaries, $os ) = @_;
138 rodolico 211
   &logIt( 'Entering validateBinaries' );
132 rodolico 212
   my %return;
213
   foreach my $bin ( keys %$binaries ) {
214
      unless ( `which $bin` ) {
215
         $return{$bin} = $binaries->{$bin}->{$os} ? $binaries->{$bin}->{$os} : 'UNK';
216
      }
217
   }
218
   return \%return;
219
} # validateBinaries
220
 
221
# get some input from the user and decide how to install/upgrade/remove/whatever
222
sub getInstallActions {
223
   my $install = shift;
138 rodolico 224
   &logIt( 'Entering getInstallActions' );
132 rodolico 225
   if ( -d $install->{'confdir'} ) {
226
      $install->{'action'} = "upgrade";
227
   } else {
228
      $install->{'action'} = 'install';
229
   }
230
   $install->{'build config'} = 'Y';
231
   $install->{'setup cron'} = 'Y';
101 rodolico 232
}
233
 
132 rodolico 234
# locate all items in $hash which have one of the $placeholder elements in it
235
# and replace, ie <binddir> is replaced with the actual binary directory
236
sub doPlaceholderSubstitution {
237
   my ($hash, $placeholder) = @_;
138 rodolico 238
   &logIt( 'Entering doPlaceholderSubstitution' );
132 rodolico 239
   return if ref $hash ne 'HASH';
240
   foreach my $key ( keys %$hash ) {
241
      if ( ref( $$hash{$key} ) ) {
242
         &doPlaceholderSubstitution( $$hash{$key}, $placeholder );
243
      } else {
244
         foreach my $place ( keys %$placeholder ) {
245
            $$hash{$key} =~ s/$place/$$placeholder{$place}/;
246
         } # foreach
247
      } # if..else
248
   } # foreach
249
   return;
250
}
251
 
252
# This will go through and first, see if anything is a directory, in
253
# which case, we'll create new entries for all files in there.
254
# then, it will do keyword substitution of <bindir> and <confdir>
255
# to populate the target.
256
# When this is done, each file should have a source and target that is
257
# a fully qualified path and filename
208 rodolico 258
sub massageInstallValues {
132 rodolico 259
   my ( $install, $sourceDir ) = @_;
138 rodolico 260
   &logIt( 'Entering populateSourceDir' );
132 rodolico 261
   my %placeHolders = 
262
      ( 
263
        '<bindir>' => $$install{'bindir'},
264
        '<confdir>' => $$install{'confdir'},
265
        '<default owner>' => $$install{'default owner'},
266
        '<default group>' => $$install{'default group'},
267
        '<default permission>' => $$install{'default permission'},
268
        '<installdir>' => $sourceDir
269
      );
101 rodolico 270
 
132 rodolico 271
   my $allFiles = $$install{'files'};
101 rodolico 272
 
132 rodolico 273
   # find all directory entries and load files in that directory into $$install{'files'}
274
   foreach my $dir ( keys %$allFiles ) {
275
      if ( defined( $$allFiles{$dir}{'type'} ) && $$allFiles{$dir}{'type'} eq 'directory' ) {
138 rodolico 276
         &logIt( "Found directory $dir" );
132 rodolico 277
         if ( opendir( my $dh, "$sourceDir/$dir" ) ) {
278
            my @files = map{ $dir . '/' . $_ } grep { ! /^\./ && -f "$sourceDir/$dir/$_" } readdir( $dh );
138 rodolico 279
            &logIt( "\tFound files " . join( ' ', @files ) );
132 rodolico 280
            foreach my $file ( @files ) {
281
               $$allFiles{ $file }{'type'} = 'file';
282
               if ( $dir eq 'modules' ) {
283
                  $$allFiles{ $file }{'permission'} = ( $file =~ m/$$install{'modules'}/ ) ? '0700' : '0600';
284
               } else {
285
                  $$allFiles{ $file }{'permission'} = $$allFiles{ $dir }{'permission'};
286
               }
287
               $$allFiles{ $file }{'owner'} = $$allFiles{ $dir }{'owner'};
288
               $$allFiles{ $file }{'target'} = $$allFiles{ $dir }{'target'};
289
            } # foreach
290
            closedir $dh;
291
         } # if opendir
292
      } # if it is a directory
293
   } # foreach
294
   # find all files, and set the source directory, and add the filename to
295
   # the target
296
   foreach my $file ( keys %$allFiles ) {
297
      $$allFiles{$file}{'source'} = "$sourceDir/$file";
298
      $$allFiles{$file}{'target'} .= "/$file";
299
   } # foreach
101 rodolico 300
 
132 rodolico 301
   # finally, do place holder substitution. This recursively replaces all keys
302
   # in  %placeHolders with the values.
303
   &doPlaceholderSubstitution( $install, \%placeHolders );
101 rodolico 304
 
144 rodolico 305
   &logIt( "Exiting populateSourceDir with values\n" . Dumper( $install ) ) ;
101 rodolico 306
 
132 rodolico 307
   return 1;
308
} # populateSourceDir
309
 
310
sub GetPermission {
311
   my $install = shift;
138 rodolico 312
   &logIt( 'Entering GetPermission' );
132 rodolico 313
   print "Ready to install, please verify the following\n";
314
   print "A. Operating System:  " . $install->{'os'} . "\n";
315
   print "B. Installation Type: " . $install->{'action'} . "\n";
316
   print "C. Using Seed file: " . $install->{'configuration seed file'} . "\n" if -e $install->{'configuration seed file'};
317
   print "D. Target Binary Directory: " . $install->{'bindir'} . "\n";
318
   print "E. Target Configuration Directory: " . $install->{'confdir'} . "\n";
319
   print "F. Automatic Running: " . ( $install->{'crontab'} ? $install->{'crontab'} : 'No' ) . "\n";
320
   print "G. Install Missing Perl Libraries\n";
321
   foreach my $task ( sort keys %{ $install->{'missing libraries'} } ) {
144 rodolico 322
      print "\t$task -> " . $install->{'missing libraries'}->{$task}->{'command'} . ' ' . $install->{'missing libraries'}->{$task}->{'parameter'} . "\n";
101 rodolico 323
   }
132 rodolico 324
   print "H. Install Missing Binaries\n";
325
   foreach my $task ( sort keys %{ $install->{'missing binaries'} } ) {
144 rodolico 326
      print "\t$task -> " . $install->{'missing binaries'}->{$task}->{'command'} . ' ' . $install->{'missing binaries'}->{$task}->{'parameter'} . "\n";
132 rodolico 327
   }
328
   return &yesno( "Do you want to proceed?" );
101 rodolico 329
}
330
 
132 rodolico 331
# note, this fails badly if you stick non-numerics in the version number
332
# simply create a "number" from the version which may have an arbitrary
333
# number of digits separated by a period, for example
334
# 1.2.5
335
# while there are digits, divide current calculation by 100, then add the last
336
# digit popped of. So, 1.2.5 would become
337
# 1 + 2/100 + 5/10000, or 1.0205
338
# and 1.25.16 would become 1.2516
339
# 
340
# Will give invalid results if any set of digits is more than 99
341
sub dotVersion2Number {
342
   my $dotVersion = shift;
343
 
344
   my @t = split( '\.', $dotVersion );
345
   #print "\n$dotVersion\n" . join( "\n", @t ) . "\n";
346
   my $return = 0;
347
   while ( @t ) {
348
      $return /= 100;
349
      $return += pop @t;
350
   }
351
   #print "$return\n";
352
   return $return;
353
}
354
 
355
# there is a file named VERSIONS. We get the values out of the install
356
# directory and (if it exists) the target so we can decide what needs
357
# to be updated.
358
sub getVersions {
359
   my $install = shift;
138 rodolico 360
   &logIt( 'Entering getVersions' );
132 rodolico 361
   my $currentVersionFile = $install->{'files'}->{'VERSION'}->{'target'};
362
   my $newVersionFile = $install->{'files'}->{'VERSION'}->{'source'};
363
   if ( open FILE,"<$currentVersionFile" ) {
364
      while ( my $line = <FILE> ) {
365
         chomp $line;
366
         my ( $filename, $version, $checksum ) = split( "\t", $line );
367
         $install{'files'}->{$filename}->{'installed version'} = $version ? $version : '';
156 rodolico 368
         $install{'files'}->{$filename}->{'installed checksum'} = $checksum ? $checksum : '';
132 rodolico 369
      }
370
      close FILE;
371
   }
372
   if ( open FILE,"<$newVersionFile" ) {
373
      while ( my $line = <FILE> ) {
374
         chomp $line;
375
         my ( $filename, $version, $checksum ) = split( "\t", $line );
376
         $install->{'files'}->{$filename}->{'new version'} = $version ? $version : '';
156 rodolico 377
         $install->{'files'}->{$filename}->{'new checksum'} = $checksum ? $checksum : '';
132 rodolico 378
      }
379
      close FILE;
380
   }
381
   foreach my $file ( keys %{$$install{'files'}} ) {
156 rodolico 382
      $install{'files'}->{$file}->{'installed version'} = '' unless defined $install->{'files'}->{$file}->{'installed version'};
383
      $install{'files'}->{$file}->{'new version'} = '' unless defined $install->{'files'}->{$file}->{'new version'};
132 rodolico 384
   }
385
   return 1;
386
} # getVersions
387
 
144 rodolico 388
# checks if a directory exists and, if not, creates it
389
my %directories; # holds list of directories already created so no need to do an I/O
132 rodolico 390
 
144 rodolico 391
sub checkDirectoryExists {
392
   my ( $filename,$mod,$owner ) = @_;
393
   $mod = "0700" unless $mod;
394
   $owner = "root:root" unless $owner;
395
   &logIt( "Checking Directory for $filename with $mod and $owner" );
396
   my ($fn, $dirname) = fileparse( $filename );
397
   logIt( "\tParsing out $dirname and $filename" );
398
   return '' if exists $directories{$dirname};
399
   if ( -d $dirname ) {
400
      $directories{$dirname} = 1;
401
      return '';
402
   }
403
   if ( &runCommand( "mkdir -p $dirname", "chmod $mod $dirname", "chown $owner $dirname" ) ) {
404
      $directories{$dirname} = 1;
405
   }
406
   return '';   
407
}
408
 
409
# runs a system command. Also, if in testing mode, simply shows what
410
# would have been done.
411
sub runCommand {
412
   while ( my $command = shift ) {
413
      if ( $dryRun ) {
414
         print "$command\n";
415
      } else {
416
         `$command`;
417
      }
418
   }
419
   return 1;
420
} # runCommand
421
 
132 rodolico 422
# this actually does the installation, except for the configuration
423
sub doInstall {
424
   my $install = shift;
138 rodolico 425
   &logIt( 'Entering doInstall' );
132 rodolico 426
   my $fileList = $install->{'files'};
427
 
428
   &checkDirectoryExists( $install->{'bindir'} . '/', $install->{'default permission'}, $install->{'default owner'} . ':' . $install->{'default group'} );
429
   foreach my $file ( keys %$fileList ) {
430
      next unless ( $fileList->{$file}->{'type'} && $fileList->{$file}->{'type'} eq 'file' );
431
 
156 rodolico 432
#   *********** Removed error checking to get this working; should reenable later
433
#      if ( version->parse( $fileList->{$file}->{'installed version'} ) && version->parse( $fileList->{$file}->{'installed version'} ) < version->parse( $fileList->{$file}->{'new version'} ) ) {
434
#         # we have a new version, so overwrite it
435
#      } elsif ( $fileList->{$file}->{'installed checksum'} eq $fileList->{$file}->{'installed checksum'} ) { # has file been modified
436
#      }
437
#         
438
#
439
#      next if $install->{'action'} eq 'upgrade' && ! defined( $fileList->{$file}->{'installed version'} )
440
#              ||
441
#              ( &dotVersion2Number( $fileList->{$file}->{'new version'} ) <= &dotVersion2Number($fileList->{$file}->{'installed version'} ) );
208 rodolico 442
      # check the directory and permissions, creating directory and setting permissions if necessary
132 rodolico 443
      &checkDirectoryExists( $fileList->{$file}->{'target'}, $install->{'default permission'}, $install->{'default owner'} . ':' . $install->{'default group'} );
208 rodolico 444
      # copy the files to the new directory
132 rodolico 445
      &runCommand( 
208 rodolico 446
            "cp $fileList->{$file}->{'source'} $fileList->{$file}->{'target'}",            
132 rodolico 447
            "chmod $fileList->{$file}->{'permission'} $fileList->{$file}->{'target'}",
448
            "chown $fileList->{$file}->{'owner'} $fileList->{$file}->{'target'}"
449
            );
450
      # if there is a post action, run it and store any return in @feedback
451
      push @feedback, `$fileList->{$file}->{'post action'}` if defined $fileList->{$file}->{'post action'};
452
      # if there is a message to be passed, store it in @messages
156 rodolico 453
      push @messages, $fileList->{$file}->{'message'} if defined $fileList->{$file}->{'message'};
132 rodolico 454
   } # foreach file
455
   return 1;
456
}
457
 
458
 
459
# installs binaries and libraries
460
sub installOSStuff {
461
   my $install = shift;
144 rodolico 462
   my %commands;
132 rodolico 463
   my @actions = values( %{ $install->{'missing libraries'} } );
464
   push @actions, values( %{ $install->{'missing binaries'} } );
465
   foreach my $action ( @actions ) {
144 rodolico 466
      $commands{$action->{'command'}} .= ' ' . $action->{'parameter'};
132 rodolico 467
   }
144 rodolico 468
   foreach my $command ( keys %commands ) {
208 rodolico 469
      &logIt( $command );
470
      print "Running command $command $commands{$command}\n" unless $quiet;
144 rodolico 471
      `$command $commands{$command}`;
472
   }
132 rodolico 473
}
144 rodolico 474
 
475
################################################################
476
# validateCPAN
477
#
478
# some of the systems will need to run cpan to get some perl modules.
479
# this will go through each of them and see if command starts with cpan
480
# and, if so, will check that cpan is installed and configured for root.
481
#
482
# when cpan is installed, it requires one manual run as root from the cli
483
# to determine where to get the files. If that is not done, cpan can not
484
# be controlled by a program. We check to see if cpan is installed, then
485
# verify /root/.cpan has been created by the configuration tool
486
################################################################
487
 
488
 
489
sub validateCPAN {
490
   my $libraries = shift;
491
   my $needCPAN = 0;
492
   foreach my $app ( keys %$libraries ) {
493
      if ( $libraries->{$app}->{'command'} =~ m/^cpan/ ) {
494
         $needCPAN = 1;
495
         last;
496
      }
497
   }
498
   return unless $needCPAN;
499
   if ( `which cpan` ) {
500
      die "****ERROR****\nWe need cpan, and it is installed, but not configured\nrun cpan as root one time to configure it\n" unless -d '/root/.cpan';
501
   } else {
502
      die 'In order to install on this OS, we need cpan, which should have been installed with perl.' .
503
          " Can not continue until cpan is installed and configured\n";
504
   }
208 rodolico 505
}
506
 
507
# set up the config file.
508
# at worst, we'll have an empty configuration file
509
sub checkConfig {
510
   my $install = shift;
511
   # if the configuration file does not exist, create one
512
   if ( not -e $install->{'configuration'}->{'configuration file'} ) {
513
      &logIt( "Configuration file " . $install->{'configuration'}->{'configuration file'} . " does not exist, creating" );
514
      &checkDirectoryExists(
515
            $install->{'configuration'}->{'configuration file'},
516
            $install->{'configuration'}->{'permission'},
517
            $install->{'configuration'}->{'owner'}
518
            );
519
      if ( -e $install->{'configuration seed file'} ) {
520
         &logIt( "Seed file " . $install->{'configuration seed file'} . " exists, using as default" );
521
         copy( $install->{'configuration seed file'}, $install->{'configuration'}->{'configuration file'} );
522
      } else { # we don't have a seed, and we don't have a configuration file, so just give it an empty one
523
         &logIt( "No seed file or configuration file, creating an empty YAML" );
524
         open YAML, '>' . $install->{'configuration'}->{'configuration file'} 
525
            or die "Could not create configuration file " . $install->{'configuration'}->{'configuration file'} . ": $!\n";
526
         print YAML "# This is an empty configuration file\n---\n";
527
         close YAML;
528
      }
529
   }
530
}
531
 
532
# create a cron entry if necessary
533
sub cronTab {
534
   my $install = shift;
535
   # set up crontab, if necessary
536
   &logIt("Setting up crontab as " . $install->{'crontab'} );
537
   &runCommand( $install->{'crontab'} ) if defined ( $install->{'crontab'} );
144 rodolico 538
}   
132 rodolico 539
 
540
################################################################
541
#               Main Code                                      #
542
################################################################
543
 
544
# handle any command line parameters that may have been passed in
545
 
546
GetOptions (
547
            "os|o=s"      => \$os,      # pass in the operating system
548
            "dryrun|n"    => \$dryRun,  # do NOT actually do anything
549
            'help|h'      => \$help,
206 rodolico 550
            'version|v'   => \$version,
551
            'quiet|q'     => \$quiet,
552
            'inplace|i'   => \$inplace
132 rodolico 553
            ) or die "Error parsing command line\n";
554
 
555
if ( $help ) { &help() ; exit; }
156 rodolico 556
if ( $version ) { use File::Basename; print basename($0) . " $VERSION\n"; exit; }
132 rodolico 557
 
156 rodolico 558
print "Logging to $logFile\n";
138 rodolico 559
&logIt( 'Beginning installation' );
560
 
208 rodolico 561
# determine the operating system and set up installer hash with correct values
132 rodolico 562
$install{'os'} = &setUpOperatingSystemSpecific( \%install, \%operatingSystems, $os ? $os : `$sourceDir/determineOS`, $sourceDir );
138 rodolico 563
&logIt( "Operating System is $install{'os'}" );
564
 
208 rodolico 565
# check libraries necessary are loaded, and if not, track the ones we need
132 rodolico 566
$install{'missing libraries'} = &validateLibraries( \%libraries, $install{'os'} );
144 rodolico 567
&logIt( "Missing Libraries\n" . Dumper( $install{'missing libraries'} ) );
138 rodolico 568
 
208 rodolico 569
# Check that required binaries are installed and create list of the ones we need
132 rodolico 570
$install{'missing binaries'} = &validateBinaries( \%binaries, $install{'os'} );
144 rodolico 571
&logIt( "Missing binaries\n" . Dumper( $install{'missing binaries'} ) );
138 rodolico 572
 
208 rodolico 573
# if we need libraries and the os needs to use CPAN, validate CPAN
574
&validateCPAN( $install{'missing libraries'} ) if ( $install{'missing libraries'} );
144 rodolico 575
 
208 rodolico 576
# determine if it is an upgrade or fresh install and default to creating conf and cron
132 rodolico 577
&getInstallActions( \%install );
144 rodolico 578
&logIt( "Completed getInstallActions\n" .  Dumper( \%install ) );
138 rodolico 579
 
208 rodolico 580
# go through %install and replace all variables with correct values
581
# moving directories as needed in the %install
582
&massageInstallValues( \%install, $sourceDir );
132 rodolico 583
 
208 rodolico 584
#print Dumper( \%install ) ; die;
585
 
586
# ask permission if $quiet not set
206 rodolico 587
if ( $quiet || &GetPermission( \%install ) ) {
208 rodolico 588
   # install binaries and libraries as needed
132 rodolico 589
   &installOSStuff( \%install );
208 rodolico 590
   # do a version comparison unless we already have it in place, or it is a new install
591
   &getVersions( \%install ) unless $inplace || $install{'action'} eq 'new';
592
   # move the binaries in place unless they are already there
207 rodolico 593
   &doInstall( \%install ) unless $inplace;
132 rodolico 594
} else {
595
   die "Please fix whatever needs to be done and try again\n";
138 rodolico 596
   &logIt( "User chose to kill process" );
132 rodolico 597
}
598
 
208 rodolico 599
# set up automatic running
600
&cronTab( \%install );
601
# make sure something is in the configuration file
602
&checkConfig( \%install );
603
 
144 rodolico 604
&logIt( "Installation done, running \&postInstall if it exists" );
132 rodolico 605
 
206 rodolico 606
&postInstall( \%install, $quiet ) if defined( &postInstall );
144 rodolico 607
 
608
1;