| 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)
 | 
        
           | 101 | rodolico | 29 |   | 
        
           | 132 | rodolico | 30 | our $VERSION = '3.0';
 | 
        
           |  |  | 31 |   | 
        
           |  |  | 32 | # find our location and use it for searching for libraries
 | 
        
           |  |  | 33 | BEGIN {
 | 
        
           |  |  | 34 |    use FindBin;
 | 
        
           |  |  | 35 |    use File::Spec;
 | 
        
           |  |  | 36 |    use lib File::Spec->catdir($FindBin::Bin);
 | 
        
           |  |  | 37 |    eval( 'use YAML::Tiny' );
 | 
        
           |  |  | 38 | }
 | 
        
           |  |  | 39 |   | 
        
           | 101 | rodolico | 40 | my $sourceDir = File::Spec->catdir($FindBin::Bin);
 | 
        
           |  |  | 41 |   | 
        
           | 132 | rodolico | 42 | use sysinfoconf;
 | 
        
           |  |  | 43 | use Data::Dumper;
 | 
        
           |  |  | 44 | use File::Basename;
 | 
        
           |  |  | 45 | use Getopt::Long;
 | 
        
           | 101 | rodolico | 46 |   | 
        
           | 132 | rodolico | 47 | our %install;
 | 
        
           |  |  | 48 | our %operatingSystems;
 | 
        
           |  |  | 49 | our %libraries;
 | 
        
           |  |  | 50 | our %binaries;
 | 
        
           |  |  | 51 |   | 
        
           |  |  | 52 | do "$sourceDir/installer_config.pl";
 | 
        
           | 138 | rodolico | 53 | #
 | 
        
           |  |  | 54 | # set up log file
 | 
        
           |  |  | 55 | my $logFile = $install{'application name'};
 | 
        
           |  |  | 56 | $logFile =~ s/ /_/g;
 | 
        
           |  |  | 57 | $logFile = "$sourceDir/$logFile.log";
 | 
        
           | 139 | rodolico | 58 | print "Logging to $logFile\n";
 | 
        
           | 132 | rodolico | 59 |   | 
        
           | 138 | rodolico | 60 |   | 
        
           |  |  | 61 |   | 
        
           | 132 | rodolico | 62 | Getopt::Long::Configure ("bundling"); # allow -vd --os='debian'
 | 
        
           |  |  | 63 | my $dryRun = 0;
 | 
        
           |  |  | 64 | my $os;
 | 
        
           |  |  | 65 | my $help = 0;
 | 
        
           |  |  | 66 | my $version = 0;
 | 
        
           |  |  | 67 |   | 
        
           |  |  | 68 | my @messages; # stores any messages we want to show up at the end
 | 
        
           |  |  | 69 | my @feedback; # store feedback when we execute command line actions
 | 
        
           |  |  | 70 |   | 
        
           |  |  | 71 | my %configuration;
 | 
        
           |  |  | 72 |   | 
        
           |  |  | 73 | # simple display if --help is passed
 | 
        
           |  |  | 74 | sub help {
 | 
        
           |  |  | 75 |    my $oses = join( ' ', keys %operatingSystems );
 | 
        
           |  |  | 76 |    print <<END
 | 
        
           |  |  | 77 | $0 --verbose=x --os="osname" --dryrun --help --version
 | 
        
           |  |  | 78 |   | 
        
           |  |  | 79 | --os      - osname is one of [$oses]
 | 
        
           |  |  | 80 | --dryrun  - do not actually do anything, just tell you what I'd do
 | 
        
           | 138 | rodolico | 81 | --version - display version and exit
 | 
        
           | 132 | rodolico | 82 | END
 | 
        
           | 101 | rodolico | 83 | }
 | 
        
           |  |  | 84 |   | 
        
           | 138 | rodolico | 85 | #######################################################
 | 
        
           |  |  | 86 | # function to simply log things
 | 
        
           |  |  | 87 | # first parameter is the priority, if <= $logDef->{'log level'} will print
 | 
        
           |  |  | 88 | # all subsequent parameters assumed to be strings to sent to the log
 | 
        
           |  |  | 89 | # returns 0 on failure
 | 
        
           |  |  | 90 | #         1 on success
 | 
        
           |  |  | 91 | #         2 if priority > log level
 | 
        
           |  |  | 92 | #        -1 if $logDef is unset
 | 
        
           |  |  | 93 | # currently, only logs to a file
 | 
        
           |  |  | 94 | #######################################################
 | 
        
           |  |  | 95 | sub logIt {
 | 
        
           |  |  | 96 |    open LOG, '>>$logFile' or die "Could not append to $logFile: $!\n";
 | 
        
           |  |  | 97 |    while ( my $t = shift ) {
 | 
        
           |  |  | 98 |       print LOG &timeStamp() . "\t$t\n";
 | 
        
           |  |  | 99 |    }
 | 
        
           |  |  | 100 |    close LOG;
 | 
        
           |  |  | 101 |    return 1;
 | 
        
           |  |  | 102 | }
 | 
        
           | 101 | rodolico | 103 |   | 
        
           | 138 | rodolico | 104 |   | 
        
           | 132 | rodolico | 105 | # attempt to locate the operating system.
 | 
        
           |  |  | 106 | # if found, will set some defaults for it.
 | 
        
           |  |  | 107 | sub setUpOperatingSystemSpecific {
 | 
        
           |  |  | 108 |    my ( $install, $operatingSystems, $os, $installDir ) = @_;
 | 
        
           | 138 | rodolico | 109 |    &logIt( 'Entering setUpOperatingSystemSpecific' );
 | 
        
           |  |  | 110 |    &logIt( "They passed $os in as the \$os" );
 | 
        
           | 132 | rodolico | 111 |    if ( $os ) {
 | 
        
           |  |  | 112 |       # We found the OS, set up some defaults
 | 
        
           |  |  | 113 |       $$install{'os'} = $os;
 | 
        
           | 138 | rodolico | 114 |       &logIt( "Setting keys for operating system" );
 | 
        
           | 132 | rodolico | 115 |       # merge operatingSystems into install
 | 
        
           |  |  | 116 |       foreach my $key ( keys %{$operatingSystems->{$os}} ) {
 | 
        
           |  |  | 117 |          if ( $key eq 'files' ) {
 | 
        
           |  |  | 118 |             $install->{'files'} = { %{$install->{'files'}}, %{$operatingSystems->{$os}->{'files'}} }
 | 
        
           |  |  | 119 |          } else {
 | 
        
           |  |  | 120 |             $install->{$key} = $operatingSystems->{ $os }->{$key};
 | 
        
           |  |  | 121 |          }
 | 
        
           |  |  | 122 |       } # if it is a known OS
 | 
        
           |  |  | 123 |    } # if
 | 
        
           |  |  | 124 |    return $os;
 | 
        
           |  |  | 125 | } # getOperatingSystem
 | 
        
           |  |  | 126 |   | 
        
           |  |  | 127 | # validates the libraries needed exist
 | 
        
           |  |  | 128 | # simply eval's each library. If it doesn't exist, creates a list of
 | 
        
           |  |  | 129 | # commands to be executed to install it, and displays missing libraries
 | 
        
           |  |  | 130 | # offering to install them if possible.
 | 
        
           |  |  | 131 | sub validateLibraries {
 | 
        
           |  |  | 132 |    my ( $libraries, $os ) = @_;
 | 
        
           | 138 | rodolico | 133 |    &logIt( 'Entering validateLibraries' );
 | 
        
           | 132 | rodolico | 134 |    my %return;
 | 
        
           |  |  | 135 |    foreach my $lib ( keys %$libraries ) {
 | 
        
           | 138 | rodolico | 136 |       &logIt( "Checking on library $lib" );
 | 
        
           | 132 | rodolico | 137 |       eval( "use $lib;" );
 | 
        
           |  |  | 138 |       if ( $@ ) {
 | 
        
           |  |  | 139 |          $return{ $lib } = $libraries->{$lib}->{$os} ? $libraries->{$lib}->{$os} : 'UNK';
 | 
        
           |  |  | 140 |       }
 | 
        
           |  |  | 141 |    }
 | 
        
           |  |  | 142 |    return \%return;
 | 
        
           |  |  | 143 | } # validateLibraries
 | 
        
           |  |  | 144 |   | 
        
           |  |  | 145 |   | 
        
           |  |  | 146 | # check for any required binaries
 | 
        
           |  |  | 147 | sub validateBinaries {
 | 
        
           |  |  | 148 |    my ( $binaries, $os ) = @_;
 | 
        
           | 138 | rodolico | 149 |    &logIt( 'Entering validateBinaries' );
 | 
        
           | 132 | rodolico | 150 |    my %return;
 | 
        
           |  |  | 151 |    foreach my $bin ( keys %$binaries ) {
 | 
        
           |  |  | 152 |       unless ( `which $bin` ) {
 | 
        
           |  |  | 153 |          $return{$bin} = $binaries->{$bin}->{$os} ? $binaries->{$bin}->{$os} : 'UNK';
 | 
        
           |  |  | 154 |       }
 | 
        
           |  |  | 155 |    }
 | 
        
           |  |  | 156 |    return \%return;
 | 
        
           |  |  | 157 | } # validateBinaries
 | 
        
           |  |  | 158 |   | 
        
           |  |  | 159 | # get some input from the user and decide how to install/upgrade/remove/whatever
 | 
        
           |  |  | 160 | sub getInstallActions {
 | 
        
           |  |  | 161 |    my $install = shift;
 | 
        
           | 138 | rodolico | 162 |    &logIt( 'Entering getInstallActions' );
 | 
        
           | 132 | rodolico | 163 |    if ( -d $install->{'confdir'} ) {
 | 
        
           |  |  | 164 |       $install->{'action'} = "upgrade";
 | 
        
           |  |  | 165 |    } else {
 | 
        
           |  |  | 166 |       $install->{'action'} = 'install';
 | 
        
           |  |  | 167 |    }
 | 
        
           |  |  | 168 |    $install->{'build config'} = 'Y';
 | 
        
           |  |  | 169 |    $install->{'setup cron'} = 'Y';
 | 
        
           | 101 | rodolico | 170 | }
 | 
        
           |  |  | 171 |   | 
        
           | 132 | rodolico | 172 | # locate all items in $hash which have one of the $placeholder elements in it
 | 
        
           |  |  | 173 | # and replace, ie <binddir> is replaced with the actual binary directory
 | 
        
           |  |  | 174 | sub doPlaceholderSubstitution {
 | 
        
           |  |  | 175 |    my ($hash, $placeholder) = @_;
 | 
        
           | 138 | rodolico | 176 |    &logIt( 'Entering doPlaceholderSubstitution' );
 | 
        
           | 132 | rodolico | 177 |    return if ref $hash ne 'HASH';
 | 
        
           |  |  | 178 |    foreach my $key ( keys %$hash ) {
 | 
        
           |  |  | 179 |       if ( ref( $$hash{$key} ) ) {
 | 
        
           |  |  | 180 |          &doPlaceholderSubstitution( $$hash{$key}, $placeholder );
 | 
        
           |  |  | 181 |       } else {
 | 
        
           |  |  | 182 |          foreach my $place ( keys %$placeholder ) {
 | 
        
           |  |  | 183 |             $$hash{$key} =~ s/$place/$$placeholder{$place}/;
 | 
        
           |  |  | 184 |          } # foreach
 | 
        
           |  |  | 185 |       } # if..else
 | 
        
           |  |  | 186 |    } # foreach
 | 
        
           |  |  | 187 |    return;
 | 
        
           |  |  | 188 | }
 | 
        
           |  |  | 189 |   | 
        
           |  |  | 190 | # This will go through and first, see if anything is a directory, in
 | 
        
           |  |  | 191 | # which case, we'll create new entries for all files in there.
 | 
        
           |  |  | 192 | # then, it will do keyword substitution of <bindir> and <confdir>
 | 
        
           |  |  | 193 | # to populate the target.
 | 
        
           |  |  | 194 | # When this is done, each file should have a source and target that is
 | 
        
           |  |  | 195 | # a fully qualified path and filename
 | 
        
           |  |  | 196 | sub populateSourceDir {
 | 
        
           |  |  | 197 |    my ( $install, $sourceDir ) = @_;
 | 
        
           | 138 | rodolico | 198 |    &logIt( 'Entering populateSourceDir' );
 | 
        
           | 132 | rodolico | 199 |    my %placeHolders = 
 | 
        
           |  |  | 200 |       ( 
 | 
        
           |  |  | 201 |         '<bindir>' => $$install{'bindir'},
 | 
        
           |  |  | 202 |         '<confdir>' => $$install{'confdir'},
 | 
        
           |  |  | 203 |         '<default owner>' => $$install{'default owner'},
 | 
        
           |  |  | 204 |         '<default group>' => $$install{'default group'},
 | 
        
           |  |  | 205 |         '<default permission>' => $$install{'default permission'},
 | 
        
           |  |  | 206 |         '<installdir>' => $sourceDir
 | 
        
           |  |  | 207 |       );
 | 
        
           | 101 | rodolico | 208 |   | 
        
           | 132 | rodolico | 209 |    my $allFiles = $$install{'files'};
 | 
        
           | 101 | rodolico | 210 |   | 
        
           | 132 | rodolico | 211 |    # find all directory entries and load files in that directory into $$install{'files'}
 | 
        
           |  |  | 212 |    foreach my $dir ( keys %$allFiles ) {
 | 
        
           |  |  | 213 |       if ( defined( $$allFiles{$dir}{'type'} ) && $$allFiles{$dir}{'type'} eq 'directory' ) {
 | 
        
           | 138 | rodolico | 214 |          &logIt( "Found directory $dir" );
 | 
        
           | 132 | rodolico | 215 |          if ( opendir( my $dh, "$sourceDir/$dir" ) ) {
 | 
        
           |  |  | 216 |             my @files = map{ $dir . '/' . $_ } grep { ! /^\./ && -f "$sourceDir/$dir/$_" } readdir( $dh );
 | 
        
           | 138 | rodolico | 217 |             &logIt( "\tFound files " . join( ' ', @files ) );
 | 
        
           | 132 | rodolico | 218 |             foreach my $file ( @files ) {
 | 
        
           |  |  | 219 |                $$allFiles{ $file }{'type'} = 'file';
 | 
        
           |  |  | 220 |                if ( $dir eq 'modules' ) {
 | 
        
           |  |  | 221 |                   $$allFiles{ $file }{'permission'} = ( $file =~ m/$$install{'modules'}/ ) ? '0700' : '0600';
 | 
        
           |  |  | 222 |                } else {
 | 
        
           |  |  | 223 |                   $$allFiles{ $file }{'permission'} = $$allFiles{ $dir }{'permission'};
 | 
        
           |  |  | 224 |                }
 | 
        
           |  |  | 225 |                $$allFiles{ $file }{'owner'} = $$allFiles{ $dir }{'owner'};
 | 
        
           |  |  | 226 |                $$allFiles{ $file }{'target'} = $$allFiles{ $dir }{'target'};
 | 
        
           |  |  | 227 |             } # foreach
 | 
        
           |  |  | 228 |             closedir $dh;
 | 
        
           |  |  | 229 |          } # if opendir
 | 
        
           |  |  | 230 |       } # if it is a directory
 | 
        
           |  |  | 231 |    } # foreach
 | 
        
           |  |  | 232 |    # find all files, and set the source directory, and add the filename to
 | 
        
           |  |  | 233 |    # the target
 | 
        
           |  |  | 234 |    foreach my $file ( keys %$allFiles ) {
 | 
        
           |  |  | 235 |       $$allFiles{$file}{'source'} = "$sourceDir/$file";
 | 
        
           |  |  | 236 |       $$allFiles{$file}{'target'} .= "/$file";
 | 
        
           |  |  | 237 |    } # foreach
 | 
        
           | 101 | rodolico | 238 |   | 
        
           | 132 | rodolico | 239 |    # finally, do place holder substitution. This recursively replaces all keys
 | 
        
           |  |  | 240 |    # in  %placeHolders with the values.
 | 
        
           |  |  | 241 |    &doPlaceholderSubstitution( $install, \%placeHolders );
 | 
        
           | 101 | rodolico | 242 |   | 
        
           | 138 | rodolico | 243 |    &logIt( "Exiting populateSourceDir with values\n" . Data::Dumper->Dump([$install],[qw($install)]) ) ;
 | 
        
           | 101 | rodolico | 244 |   | 
        
           | 132 | rodolico | 245 |    return 1;
 | 
        
           |  |  | 246 | } # populateSourceDir
 | 
        
           |  |  | 247 |   | 
        
           |  |  | 248 | sub GetPermission {
 | 
        
           |  |  | 249 |    my $install = shift;
 | 
        
           | 138 | rodolico | 250 |    &logIt( 'Entering GetPermission' );
 | 
        
           | 132 | rodolico | 251 |    print "Ready to install, please verify the following\n";
 | 
        
           |  |  | 252 |    print "A. Operating System:  " . $install->{'os'} . "\n";
 | 
        
           |  |  | 253 |    print "B. Installation Type: " . $install->{'action'} . "\n";
 | 
        
           |  |  | 254 |    print "C. Using Seed file: " . $install->{'configuration seed file'} . "\n" if -e $install->{'configuration seed file'};
 | 
        
           |  |  | 255 |    print "D. Target Binary Directory: " . $install->{'bindir'} . "\n";
 | 
        
           |  |  | 256 |    print "E. Target Configuration Directory: " . $install->{'confdir'} . "\n";
 | 
        
           |  |  | 257 |    print "F. Automatic Running: " . ( $install->{'crontab'} ? $install->{'crontab'} : 'No' ) . "\n";
 | 
        
           |  |  | 258 |    print "G. Install Missing Perl Libraries\n";
 | 
        
           |  |  | 259 |    foreach my $task ( sort keys %{ $install->{'missing libraries'} } ) {
 | 
        
           |  |  | 260 |       print "\t$task -> " . $install->{'missing libraries'}->{$task} . "\n";
 | 
        
           | 101 | rodolico | 261 |    }
 | 
        
           | 132 | rodolico | 262 |    print "H. Install Missing Binaries\n";
 | 
        
           |  |  | 263 |    foreach my $task ( sort keys %{ $install->{'missing binaries'} } ) {
 | 
        
           |  |  | 264 |       print "\t$task -> " . $install->{'missing binaries'}->{$task} . "\n";
 | 
        
           |  |  | 265 |    }
 | 
        
           |  |  | 266 |    return &yesno( "Do you want to proceed?" );
 | 
        
           | 101 | rodolico | 267 | }
 | 
        
           |  |  | 268 |   | 
        
           | 132 | rodolico | 269 | # note, this fails badly if you stick non-numerics in the version number
 | 
        
           |  |  | 270 | # simply create a "number" from the version which may have an arbitrary
 | 
        
           |  |  | 271 | # number of digits separated by a period, for example
 | 
        
           |  |  | 272 | # 1.2.5
 | 
        
           |  |  | 273 | # while there are digits, divide current calculation by 100, then add the last
 | 
        
           |  |  | 274 | # digit popped of. So, 1.2.5 would become
 | 
        
           |  |  | 275 | # 1 + 2/100 + 5/10000, or 1.0205
 | 
        
           |  |  | 276 | # and 1.25.16 would become 1.2516
 | 
        
           |  |  | 277 | # 
 | 
        
           |  |  | 278 | # Will give invalid results if any set of digits is more than 99
 | 
        
           |  |  | 279 | sub dotVersion2Number {
 | 
        
           |  |  | 280 |    my $dotVersion = shift;
 | 
        
           |  |  | 281 |   | 
        
           |  |  | 282 |    my @t = split( '\.', $dotVersion );
 | 
        
           |  |  | 283 |    #print "\n$dotVersion\n" . join( "\n", @t ) . "\n";
 | 
        
           |  |  | 284 |    my $return = 0;
 | 
        
           |  |  | 285 |    while ( @t ) {
 | 
        
           |  |  | 286 |       $return /= 100;
 | 
        
           |  |  | 287 |       $return += pop @t;
 | 
        
           |  |  | 288 |    }
 | 
        
           |  |  | 289 |    #print "$return\n";
 | 
        
           |  |  | 290 |    return $return;
 | 
        
           |  |  | 291 | }
 | 
        
           |  |  | 292 |   | 
        
           |  |  | 293 | # there is a file named VERSIONS. We get the values out of the install
 | 
        
           |  |  | 294 | # directory and (if it exists) the target so we can decide what needs
 | 
        
           |  |  | 295 | # to be updated.
 | 
        
           |  |  | 296 | sub getVersions {
 | 
        
           |  |  | 297 |    my $install = shift;
 | 
        
           | 138 | rodolico | 298 |    &logIt( 'Entering getVersions' );
 | 
        
           | 132 | rodolico | 299 |    my $currentVersionFile = $install->{'files'}->{'VERSION'}->{'target'};
 | 
        
           |  |  | 300 |    my $newVersionFile = $install->{'files'}->{'VERSION'}->{'source'};
 | 
        
           |  |  | 301 |    if ( open FILE,"<$currentVersionFile" ) {
 | 
        
           |  |  | 302 |       while ( my $line = <FILE> ) {
 | 
        
           |  |  | 303 |          chomp $line;
 | 
        
           |  |  | 304 |          my ( $filename, $version, $checksum ) = split( "\t", $line );
 | 
        
           |  |  | 305 |          $install{'files'}->{$filename}->{'installed version'} = $version ? $version : '';
 | 
        
           |  |  | 306 |       }
 | 
        
           |  |  | 307 |       close FILE;
 | 
        
           |  |  | 308 |    }
 | 
        
           |  |  | 309 |    if ( open FILE,"<$newVersionFile" ) {
 | 
        
           |  |  | 310 |       while ( my $line = <FILE> ) {
 | 
        
           |  |  | 311 |          chomp $line;
 | 
        
           |  |  | 312 |          my ( $filename, $version, $checksum ) = split( "\t", $line );
 | 
        
           |  |  | 313 |          $install->{'files'}->{$filename}->{'new version'} = $version ? $version : '';
 | 
        
           |  |  | 314 |       }
 | 
        
           |  |  | 315 |       close FILE;
 | 
        
           |  |  | 316 |    }
 | 
        
           |  |  | 317 |    foreach my $file ( keys %{$$install{'files'}} ) {
 | 
        
           |  |  | 318 |       $install{'files'}->{$file}->{'installed version'} = -2 unless defined $install->{'files'}->{$file}->{'installed version'};
 | 
        
           |  |  | 319 |       $install{'files'}->{$file}->{'new version'} = -1 unless defined $install->{'files'}->{$file}->{'new version'};
 | 
        
           |  |  | 320 |    }
 | 
        
           |  |  | 321 |    return 1;
 | 
        
           |  |  | 322 | } # getVersions
 | 
        
           |  |  | 323 |   | 
        
           |  |  | 324 |   | 
        
           |  |  | 325 | # this actually does the installation, except for the configuration
 | 
        
           |  |  | 326 | sub doInstall {
 | 
        
           |  |  | 327 |    my $install = shift;
 | 
        
           | 138 | rodolico | 328 |    &logIt( 'Entering doInstall' );
 | 
        
           | 132 | rodolico | 329 |    my $fileList = $install->{'files'};
 | 
        
           |  |  | 330 |   | 
        
           |  |  | 331 |    &checkDirectoryExists( $install->{'bindir'} . '/', $install->{'default permission'}, $install->{'default owner'} . ':' . $install->{'default group'} );
 | 
        
           |  |  | 332 |    foreach my $file ( keys %$fileList ) {
 | 
        
           |  |  | 333 |       next unless ( $fileList->{$file}->{'type'} && $fileList->{$file}->{'type'} eq 'file' );
 | 
        
           |  |  | 334 |   | 
        
           |  |  | 335 |       next if $install->{'action'} eq 'upgrade' && ! defined( $fileList->{$file}->{'installed version'} )
 | 
        
           |  |  | 336 |               ||
 | 
        
           |  |  | 337 |               ( &dotVersion2Number( $fileList->{$file}->{'new version'} ) <= &dotVersion2Number($fileList->{$file}->{'installed version'} ) );
 | 
        
           |  |  | 338 |       &checkDirectoryExists( $fileList->{$file}->{'target'}, $install->{'default permission'}, $install->{'default owner'} . ':' . $install->{'default group'} );
 | 
        
           |  |  | 339 |       &runCommand( 
 | 
        
           |  |  | 340 |             "cp $fileList->{$file}->{'source'} $fileList->{$file}->{'target'}",
 | 
        
           |  |  | 341 |             "chmod $fileList->{$file}->{'permission'} $fileList->{$file}->{'target'}",
 | 
        
           |  |  | 342 |             "chown $fileList->{$file}->{'owner'} $fileList->{$file}->{'target'}"
 | 
        
           |  |  | 343 |             );
 | 
        
           |  |  | 344 |       # if there is a post action, run it and store any return in @feedback
 | 
        
           |  |  | 345 |       push @feedback, `$fileList->{$file}->{'post action'}` if defined $fileList->{$file}->{'post action'};
 | 
        
           |  |  | 346 |       # if there is a message to be passed, store it in @messages
 | 
        
           |  |  | 347 |       push @messages, $fileList->{$file}->{'meesage'} if defined $fileList->{$file}->{'message'};
 | 
        
           |  |  | 348 |    } # foreach file
 | 
        
           |  |  | 349 |    # set up crontab, if necessary
 | 
        
           |  |  | 350 |    &runCommand( $install->{'crontab'} ) if defined ( $install->{'crontab'} );
 | 
        
           |  |  | 351 |    return 1;
 | 
        
           |  |  | 352 | }
 | 
        
           |  |  | 353 |   | 
        
           |  |  | 354 | sub postInstall {
 | 
        
           |  |  | 355 |    my $install = shift;
 | 
        
           |  |  | 356 |   | 
        
           | 138 | rodolico | 357 |    &logIt( 'Entering postInstall' );
 | 
        
           | 132 | rodolico | 358 |    # seed configuration, if needed
 | 
        
           |  |  | 359 |    if ( $$install{'build config'} ) {
 | 
        
           |  |  | 360 |       my $config;
 | 
        
           |  |  | 361 |       my @fileList;
 | 
        
           |  |  | 362 |   | 
        
           |  |  | 363 |       # the order is important here as, if multiple files exist, latter ones can
 | 
        
           |  |  | 364 |       # overwrite values in the previous. We do a push so the first value pushed
 | 
        
           |  |  | 365 |       # is processed last, ie has higher priority.
 | 
        
           |  |  | 366 |       push @fileList, $install->{'configuration'}->{'old configuration file'};
 | 
        
           |  |  | 367 |       push @fileList, $install->{'configuration'}->{'configuration file'};
 | 
        
           |  |  | 368 |   | 
        
           |  |  | 369 |       my $seedFile = $install->{'configuration'}->{'configuration seed file'};
 | 
        
           |  |  | 370 |       if ( -e $install->{'configuration seed file'} ) {
 | 
        
           |  |  | 371 |          push @fileList, $install->{'configuration seed file'};
 | 
        
           |  |  | 372 |       } # if preload seed file
 | 
        
           |  |  | 373 |   | 
        
           |  |  | 374 |       $config = &makeConfig( @fileList );
 | 
        
           |  |  | 375 |       # if ScriptDirs and moduleDirs not populated, do so from our configuration
 | 
        
           |  |  | 376 |       if ( ! $$config{'scriptDirs'} || ! scalar @{ $$config{'scriptDirs'} }  ) {
 | 
        
           |  |  | 377 |          $config->{'scriptDirs'} = [ $install->{'files'}->{'scripts'}->{'target'} ];
 | 
        
           |  |  | 378 |       }
 | 
        
           |  |  | 379 |       if ( ! $$config{'moduleDirs'} || ! @{ $$config{'moduleDirs'} }  ) {
 | 
        
           |  |  | 380 |          $config->{'moduleDirs'} = [ $install->{'files'}->{'modules'}->{'target'} ];
 | 
        
           |  |  | 381 |       }
 | 
        
           |  |  | 382 |       my $content = &showConf( $config );
 | 
        
           |  |  | 383 |       return &writeConfig( '' , $content );
 | 
        
           |  |  | 384 |    } # if we are building/merging configuration
 | 
        
           |  |  | 385 | }
 | 
        
           |  |  | 386 |   | 
        
           |  |  | 387 | # installs binaries and libraries
 | 
        
           |  |  | 388 | sub installOSStuff {
 | 
        
           |  |  | 389 |    my $install = shift;
 | 
        
           |  |  | 390 |    my @actions = values( %{ $install->{'missing libraries'} } );
 | 
        
           |  |  | 391 |    push @actions, values( %{ $install->{'missing binaries'} } );
 | 
        
           |  |  | 392 |    foreach my $action ( @actions ) {
 | 
        
           |  |  | 393 |       print "$action\n";
 | 
        
           |  |  | 394 |       &runCommand( $action );
 | 
        
           |  |  | 395 |    }
 | 
        
           |  |  | 396 | }
 | 
        
           |  |  | 397 |   | 
        
           |  |  | 398 |   | 
        
           |  |  | 399 | ################################################################
 | 
        
           |  |  | 400 | #               Main Code                                      #
 | 
        
           |  |  | 401 | ################################################################
 | 
        
           |  |  | 402 |   | 
        
           |  |  | 403 | # handle any command line parameters that may have been passed in
 | 
        
           |  |  | 404 |   | 
        
           |  |  | 405 | GetOptions (
 | 
        
           |  |  | 406 |             "os|o=s"      => \$os,      # pass in the operating system
 | 
        
           |  |  | 407 |             "dryrun|n"    => \$dryRun,  # do NOT actually do anything
 | 
        
           |  |  | 408 |             'help|h'      => \$help,
 | 
        
           | 138 | rodolico | 409 |             'version|v'   => \$version
 | 
        
           | 132 | rodolico | 410 |             ) or die "Error parsing command line\n";
 | 
        
           |  |  | 411 |   | 
        
           |  |  | 412 | if ( $help ) { &help() ; exit; }
 | 
        
           |  |  | 413 | if ( $version ) { print "$0 version $VERSION\n"; exit; }
 | 
        
           |  |  | 414 |   | 
        
           | 138 | rodolico | 415 | &logIt( 'Beginning installation' );
 | 
        
           |  |  | 416 |   | 
        
           | 132 | rodolico | 417 | $install{'os'} = &setUpOperatingSystemSpecific( \%install, \%operatingSystems, $os ? $os : `$sourceDir/determineOS`, $sourceDir );
 | 
        
           | 138 | rodolico | 418 | &logIt( "Operating System is $install{'os'}" );
 | 
        
           |  |  | 419 |   | 
        
           | 132 | rodolico | 420 | $install{'missing libraries'} = &validateLibraries( \%libraries, $install{'os'} );
 | 
        
           | 138 | rodolico | 421 | &logIt( "Missing Libraries\n" . Data::Dumper->Dump( [$install{'missing libraries'}],[qw($install{'missing libraries'})])  );
 | 
        
           |  |  | 422 |   | 
        
           | 132 | rodolico | 423 | $install{'missing binaries'} = &validateBinaries( \%binaries, $install{'os'} );
 | 
        
           | 138 | rodolico | 424 | &logIt( "Missing binaries\n" . Data::Dumper->Dump( [$install{'missing binaries'}],[qw($install{'missing binaries'})]) );
 | 
        
           |  |  | 425 |   | 
        
           | 132 | rodolico | 426 | &getInstallActions( \%install );
 | 
        
           | 138 | rodolico | 427 | &logIt( "Completed getInstallActions\n" .  Data::Dumper->Dump( [\%install],[qw(%install)]) );
 | 
        
           |  |  | 428 |   | 
        
           | 132 | rodolico | 429 | populateSourceDir( \%install, $sourceDir );
 | 
        
           |  |  | 430 |   | 
        
           |  |  | 431 | if ( &GetPermission( \%install ) ) {
 | 
        
           |  |  | 432 |    &installOSStuff( \%install );
 | 
        
           |  |  | 433 |    &getVersions( \%install ) unless $install{'action'} eq 'new';
 | 
        
           |  |  | 434 |    &doInstall( \%install );
 | 
        
           |  |  | 435 | } else {
 | 
        
           |  |  | 436 |    die "Please fix whatever needs to be done and try again\n";
 | 
        
           | 138 | rodolico | 437 |    &logIt( "User chose to kill process" );
 | 
        
           | 132 | rodolico | 438 | }
 | 
        
           |  |  | 439 |   | 
        
           |  |  | 440 | my $filename = &postInstall( \%install );
 | 
        
           |  |  | 441 | my $confFileName = $install{'configuration'}{'configuration file'};
 | 
        
           |  |  | 442 | print "Running configure.pl with $filename, output to $confFileName\n";
 | 
        
           |  |  | 443 |   | 
        
           |  |  | 444 | exec( "$install{bindir}/configure.pl -f $filename -o $confFileName" );
 |