Subversion Repositories camp_sysinfo_client_3

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
33 rodolico 1
#! /usr/bin/env perl
2
 
3
use strict;
4
use warnings;
5
 
6
our $VERSION = '1.1.3';
7
 
8
# find our location and use it for searching for libraries
9
BEGIN {
10
   use FindBin;
11
   use File::Spec;
12
   use lib File::Spec->catdir($FindBin::Bin);
13
}
14
 
15
use sysinfoconf;
16
use File::Basename;
17
 
18
use Data::Dumper;
19
 
20
# $TESTING can have the following values
21
# 0 - do everything
22
# 1 - Do everything except the install, display what would be done
23
# 2 - Be verbose to STDERR
24
# 3 - Be very verbose
25
my $TESTING = 1; # if test mode, simply show what would be done
26
 
27
my $status; # exit status of the processes
28
my $sourceDir = File::Spec->catdir($FindBin::Bin);
34 rodolico 29
my $installType;
33 rodolico 30
 
31
my %install = (  'bindir' => '/opt/camp/sysinfo-client',
32
                 'confdir' => '/etc/camp/sysinfo-client',
34 rodolico 33
                 'application name' => 'sysinfo client',
33 rodolico 34
                 'files' => {
35
                           'configure.pl' => { 
36
                                 'type' => 'file',
37
                                 'permission' => '700', 
38
                                 'owner' => 'root:root', 
39
                                 'target' =>  '<bindir>'
40
                              },
41
                           'sysinfo-client' => { 
42
                                 'type' => 'file',
43
                                 'permission' => '700',
44
                                 'owner' => 'root:root',
45
                                 'target' =>  '<bindir>'
46
                              },
47
                           'sysinfoconf.pm' => {
48
                                 'type' => 'file',
49
                                 'permission' => '600',
50
                                 'owner' => 'root:root',
51
                                 'target' =>  '<bindir>'
52
                              },
53
                           'debian.pm' => {
54
                                 'type' => 'file',
55
                                 'permission' => '600',
56
                                 'owner' => 'root:root',
57
                                 'target' =>  '<bindir>' 
58
                              },
59
                           'ipfire.pm' => { 
60
                                 'type' => 'file',
61
                                 'permission' => '600',
62
                                 'owner' => 'root:root',
63
                                 'target' =>  '<bindir>'
64
                              },
65
                           'notes' => { 
66
                                 'type' => 'file',
67
                                 'permission' => '600', 
68
                                 'owner' => 'root:root', 
69
                                 'target' =>  '<bindir>'
70
                              },
71
                           'sysinfo-client.conf.template' => { 
72
                                 'type' => 'file',
73
                                 'permission' => '600', 
74
                                 'owner' => 'root:root', 
75
                                 'target' =>  '<bindir>' 
76
                              },
77
                           'uninstall.pl' => { 
78
                                 'type' => 'file',
79
                                 'permission' => '700', 
80
                                 'owner' => 'root:root', 
81
                                 'target' =>  '<bindir>' 
82
                              },
83
                           'getSendEmail.pl' => { 
84
                                 'type' => 'file',
85
                                 'permission' => '700', 
86
                                 'owner' => 'root:root', 
87
                                 'target' =>  '<bindir>' 
88
                              },
89
                           'upgrade.pl' => { 
90
                                 'type' => 'file',
91
                                 'permission' => '700', 
92
                                 'owner' => 'root:root', 
93
                                 'target' =>  '<bindir>' 
94
                              },
95
                           'install.pl' => {
96
                                 'type' => 'file',
97
                                 'permission' => '700', 
98
                                 'owner' => 'root:root', 
99
                                 'target' =>  '<bindir>' 
100
                              },
101
                           'MANIFEST' => {
102
                                 'type' => 'file',
103
                                 'permission' => '600', 
104
                                 'owner' => 'root:root', 
105
                                 'target' =>  '<bindir>' 
106
                              },
107
                           'sysinfo-client.seed.example' => { 
108
                                 'type' => 'file',
109
                                 'permission' => '600', 
110
                                 'owner' => 'root:root', 
111
                                 'target' =>  '<bindir>' 
112
                              },
113
                           'VERSION' => { 
114
                                 'type' => 'file',
115
                                 'permission' => '600', 
116
                                 'owner' => 'root:root', 
117
                                 'target' =>  '<bindir>' 
118
                              },
119
                              'modules' => {
120
                                 'type' => 'directory',
121
                                 'permission' => '700', 
122
                                 'owner' => 'root:root', 
123
                                 'target' =>  '<bindir>',
124
                                 'action' => 'chmod 700 *'
125
                              },
126
                              'scripts' => {
127
                                 'type' => 'directory',
128
                                 'permission' => '700', 
129
                                 'owner' => 'root:root', 
130
                                 'target' =>  '<bindir>',
131
                                 'action' => 'chmod 700 *'
132
                              },
133
                              'sysinfo-client.conf' => {
134
                                 'type' => 'file',
135
                                 'create' => '<bindir>/configure.pl',
136
                                 'permission' => '700',
137
                                 'owner'      => 'root',
138
                                 'target'     => '<confdir>'
139
                              }
140
                     }
141
                  );
142
 
143
# hash to set up os specific rules                  
144
my %operatingSystems = (
145
                  'debian' => {
146
                     'bindir' => '/opt/camp/sysinfo-client',
147
                     'confdir' => '/etc/camp/sysinfo-client',
148
                     'crontab' => '/etc/cron.daily/sysinfo-client',
149
                     'modules' => '/^((dpkg)|(unix)|(ipmi))/',
150
                  },
151
                  'ipfire' => {
152
                     'bindir' => '/opt/camp/sysinfo-client',
153
                     'confdir' => '/etc/camp/sysinfo-client',
154
                     'crontab' => '/etc/fcron.daily/sysinfo-client.fcron',
155
                     'modules' => '/^((ipfire)|(unix))/',
156
                  }
157
                  );
158
 
159
 
160
# attempt to locate the operating system.
161
# if found, will set some defaults for it.
162
sub getOS {
34 rodolico 163
   my ( $install, $operatingSystems ) = @_;
33 rodolico 164
   my $osString = `uname -a`;
165
   foreach my $osType ( keys %$operatingSystems ) {
34 rodolico 166
      print "Checking if OS is $osType in $osString\n" if $TESTING > 2;
33 rodolico 167
      next unless $osString =~ m/$osType/i;
34 rodolico 168
      print "Yes, it is $osType\n" if $TESTING > 2;
33 rodolico 169
      # We found the OS, set up some defaults
34 rodolico 170
      $$install{'os'} = $osType;
171
      print "Setting keys for operating system\n" if $TESTING > 2;
33 rodolico 172
      for my $key ( keys $$operatingSystems{ $osType } ) {
34 rodolico 173
         $$install{$key} = $operatingSystems{ $osType }{$key};
33 rodolico 174
      } # if it is a known OS
175
      return 1;
176
   }
177
   return 0;
178
} # getOperatingSystem
179
 
34 rodolico 180
# get some input from the user and decide how to install/upgrade/remove/whatever
181
sub getInstallActions {
182
   my $install = shift;
183
   if ( ! &yesno( "This looks like a $$install{'os'} machine, correct?" ) ) {
184
      die "User Aborted\n" if &yesno( "If we continue, I will set this up like a $$install{'os'} system. Abort?" );
185
 
186
   }
187
   if ( -d $$install{'confdir'} ) {
188
      $$install{'action'} = &getAnswer( "It looks like $$install{'application name'} is already installed, what do you want to do?", 
189
                            ( "upgrade","remove", "overwrite" )
190
                          );
191
   } else {
192
      if ( &yesno( "This looks like a fresh install, correct?" ) ) {
193
         $$install{'action'} = 'install';
194
         $$install{'preseed config'} = &yesno( "Preseed the configuration file?" );
195
      } else {
196
         die "Can not continue at this time: Do not understand your system\n";
197
      }
198
   }
199
   $$install{'build config'} = &yesno( "Edit config file when done?" );
200
   $$install{'setup cron'} = &yesno( "Set up for automatic running via crontab?" );
201
   &showWork( $install );
202
   die unless &yesno( "Ready to run? Select No to abort." );
203
}
33 rodolico 204
 
34 rodolico 205
sub showWork { 
206
   my $install = shift;
207
   print Dumper( \%install );
208
}
209
 
210
# This will go through and first, see if anything is a directory, in
211
# which case, we'll create new entries for all files in there.
212
# then, it will do keyword substitution of <bindir> and <confdir>
213
# to populate the target.
214
# When this is done, each file should have a source and target that is
215
# a fully qualified path and filename
33 rodolico 216
sub populateSourceDir {
217
   my ( $install, $sourceDir ) = @_;
218
   my $bindir = $$install{'bindir'};
219
   my $confdir = $$install{'confdir'};
220
 
221
   my $allFiles = $$install{'files'};
222
 
223
   foreach my $dir ( keys %$allFiles ) {
224
      if ( defined( $$allFiles{$dir}{'type'} ) && $$allFiles{$dir}{'type'} eq 'directory' ) {
225
         print "Found directory $dir\n" if $TESTING > 2;
226
         if ( opendir( my $dh, "$sourceDir/$dir" ) ) {
227
            my @files = map{ $dir . '/' . $_ } grep { ! /^\./ && -f "$sourceDir/$dir/$_" } readdir( $dh );
228
            print "\tFound files " . join( ' ', @files ) . "\n" if $TESTING > 2;
229
            foreach my $file ( @files ) {
230
               $$allFiles{ $file }{'type'} = 'file';
231
               $$allFiles{ $file }{'permission'} = $$allFiles{ $dir }{'permission'};
232
               $$allFiles{ $file }{'owner'} = $$allFiles{ $dir }{'owner'};
233
               $$allFiles{ $file }{'target'} = $$allFiles{ $dir }{'target'};
234
            } # foreach
235
            closedir $dh;
236
         } # if opendir
237
      } # if it is a directory
238
   } # foreach
239
   print Dumper( $install ) if $TESTING > 2;
240
   foreach my $file ( keys %$allFiles ) {
241
      print STDERR "$file\t$bindir\t$$allFiles{$file}{'target'}\n" if $TESTING > 1;
242
      $$allFiles{$file}{'source'} = "$sourceDir/$file";
243
      $$allFiles{$file}{'target'} =~ s/<bindir>/$bindir/gi;
244
      $$allFiles{$file}{'target'} =~ s/<confdir>/$confdir/gi;
245
      $$allFiles{$file}{'target'} .= "/$file";
246
      if ( $$allFiles{$file}{'create'} ) {
247
         $$allFiles{$file}{'create'} =~ s/<bindir>/$bindir/gi;
248
         $$allFiles{$file}{'create'} =~ s/<confdir>/$confdir/gi;
249
         $$allFiles{$file}{'create'} .= "/file";
250
      }
251
 
252
   } # foreach
253
 
254
   return 1;
255
} # populateSourceDir
256
 
34 rodolico 257
# there is a file named VERSIONS. We get the values out of the install
258
# directory and (if it exists) the target so we can decide what needs
259
# to be updated.
33 rodolico 260
sub getVersions {
261
   my $install = shift;
262
   my $currentVersionFile = $$install{'files'}{'VERSION'}{'target'};
263
   my $newVersionFile = $$install{'files'}{'VERSION'}{'source'};
264
   if ( open FILE,"<$currentVersionFile" ) {
265
      while ( my $line = <FILE> ) {
266
         chomp $line;
267
         my ( $filename, $version, $checksum ) = split( "\t", $line );
268
         $$install{'files'}{$filename}{'installed version'} = $version ? $version : '';
269
#         $$install{'files'}{$filename}{'installed checksum'} = $checksum ? $checksum : '';
270
      }
271
      close FILE;
272
   }
273
   if ( open FILE,"<$newVersionFile" ) {
274
      while ( my $line = <FILE> ) {
275
         chomp $line;
276
         my ( $filename, $version, $checksum ) = split( "\t", $line );
277
         $$install{'files'}{$filename}{'new version'} = $version ? $version : '';
278
#         $$install{'files'}{$filename}{'new checksum'} = $checksum ? $checksum : '';
279
      }
280
      close FILE;
281
   }
282
   return 1;
283
} # getVersions
284
 
34 rodolico 285
# runs a system command. Also, if in testing mode, simply shows what
286
# would have been done.
33 rodolico 287
sub runCommand {
288
   while ( my $command = shift ) {
289
      if ( $TESTING ) {
290
         print "$command\n";
291
      } else {
292
         `$command`;
293
      }
294
   }
295
   return 1;
296
} # runCommand
297
 
34 rodolico 298
# checks if a directory exists and, if not, creates it
299
my %directories; # holds list of directories already created so no need to do an I/O
33 rodolico 300
 
301
sub checkDirectoryExists {
302
   my ( $filename,$mod,$owner ) = @_;
303
   $mod = "0700" unless $mod;
304
   $owner = "root:root" unless $owner;
305
   print "Checking Directory for $filename with $mod and $owner\n" if $TESTING > 2;
306
   my ($fn, $dirname) = fileparse( $filename );
307
   print "\tParsing out $dirname and $filename\n" if $TESTING > 2;
308
   return '' if exists $directories{$dirname};
309
   if ( -d $dirname ) {
310
      $directories{$dirname} = 1;
311
      return '';
312
   }
313
   if ( &runCommand( "mkdir -p $dirname", "chmod $mod $dirname", "chown $owner $dirname" ) ) {
314
      $directories{$dirname} = 1;
315
   }
316
   return '';   
317
}
318
 
34 rodolico 319
# this actually does the installation, except for the configuration
33 rodolico 320
sub doInstall {
321
   my $install = shift;
322
   my $fileList = $$install{'files'};
323
 
324
   &checkDirectoryExists( $$install{'bindir'} . '/' );
325
   foreach my $file ( keys %$fileList ) {
326
      next unless ( $$fileList{$file}{'type'} && $$fileList{$file}{'type'} eq 'file' );
34 rodolico 327
      next if $$install{'action'} eq 'upgrade' &&
328
              $$fileList{$file}{'installed version'} &&
33 rodolico 329
              $$fileList{$file}{'new version'} eq $$fileList{$file}{'installed version'};
330
      &checkDirectoryExists( $$fileList{$file}{'target'} );
331
      &runCommand( 
332
            "cp $$fileList{$file}{'source'} $$fileList{$file}{'target'}",
333
            "chmod $$fileList{$file}{'permission'} $$fileList{$file}{'target'}",
334
            "chown  $$fileList{$file}{'owner'} $$fileList{$file}{'target'}"
335
            );
336
   } # foreach file
337
   return 1;
338
}
339
 
34 rodolico 340
# parse the flags to decide the actions:
341
# install - assumes is a new install, overwrites everything
342
# upgrade - Checks for new files and overwrites only them
343
# uninstall - Removes everything
344
# reinstall - overwrites everything with fresh copy
345
 
346
################
347
# check for the configuration file!!!
348
################
349
 
350
 
351
 
352
 
33 rodolico 353
# figure out if we know our operating system
354
$status = &getOS( \%install, \%operatingSystems );
355
 
34 rodolico 356
$installType = getInstallActions( \%install );
357
 
33 rodolico 358
# based on the defaults, flesh out the install hash
359
$status = &populateSourceDir( \%install, $sourceDir );
360
 
361
$status = &getVersions( \%install );
362
 
363
$status = &doInstall( \%install );
364
 
34 rodolico 365
 
33 rodolico 366
print Dumper( \%install ) if $TESTING > 2;