Removed /usr/local from CDPATH
[clearscm.git] / clearadm / updatesystem.pl
1 #!/usr/bin/env perl
2
3 =pod
4
5 =head1 NAME $RCSfile: updatesystem.pl,v $
6
7 Update System
8
9 =head1 VERSION
10
11 =over
12
13 =item Author
14
15 Andrew DeFaria <Andrew@ClearSCM.com>
16
17 =item Revision
18
19 $Revision: 1.17 $
20
21 =item Created:
22
23 Mon Dec 13 09:13:27 EST 2010
24
25 =item Modified:
26
27 $Date: 2012/11/09 06:44:38 $
28
29 =back
30
31 =head1 SYNOPSIS
32
33  Usage updatesystem.pl: [-u|sage] [-ve|rbose] [-deb|ug]
34                         [-del|ete -h|ost <host>]
35
36  Where:
37    -u|sage:       Displays usage
38  
39    -ve|rbose:     Be verbose
40    -deb|ug:       Output debug messages
41    
42    -del|ete:      Delete host
43    -h|ost <host>: Host to operate on (Default: Current host)
44    -p|ort <port>: Clearexec port to connect to
45
46 =head1 DESCRIPTION
47
48 This script will add/update the system to the Clearadm database.  You can also
49 delete a system from the Clearadm database.
50
51 =cut
52
53 use strict;
54 use warnings;
55
56 use Sys::Hostname;
57
58 use FindBin;
59 use Getopt::Long;
60
61 use lib "$FindBin::Bin/lib", "$FindBin::Bin/../lib";
62
63 use Clearadm;
64 use Clearexec;
65 use Display;
66 use Utils;
67
68 my $VERSION  = '$Revision: 1.17 $';
69   ($VERSION) = ($VERSION =~ /\$Revision: (.*) /);
70
71 my $clearadm  = Clearadm->new;
72 my $clearexec = Clearexec->new;
73
74 my ($delete, $host, $port);
75
76 sub GetFilesystems(%) {
77   my (%system) = @_;
78   
79   # TODO: Unix/Linux systems often vary as to what parameters df supports. The
80   # -P is to intended to make this POSIX standard. Need to make sure this works
81   # on other systems (i.e. Solaris, HP-UX, Redhat, etc.).
82   my $cmd = $system{type} eq 'Windows'
83           ? 'df -TP'
84           : $system{type} eq 'Unix' # I think I need to add a Solaris type
85           ? '/usr/xpg4/bin/df -l -P'
86           : 'df -l -TP';
87    
88   my ($status, @output) = $clearexec->execute($cmd);
89   
90   error "Unable to execute $cmd - $! (Status: $status)\n" . join ("\n". @output), $status if $status;
91   
92   # Real file systems start with "/"
93   my @fs = grep { /^\// } @output;
94
95   # Also add lines that start with rpool (This is for Solaris zones
96   push @fs, grep { /^rpool/ } @output;
97   
98   my @filesystems;
99     
100   for (@fs) {
101     if (/^(\S+)\s+(\S+).+?(\S+)$/) {
102       my %filesystem;
103       
104       $filesystem{system}     = $system{name};
105       $filesystem{filesystem} = $1;
106       $filesystem{fstype}     = $2;
107       $filesystem{mount}      = $3;
108
109       push @filesystems, \%filesystem;    
110     } # if
111   } # for
112   
113   return @filesystems;
114 } # GetFilesystems
115
116 sub GatherSysInfo(;%) {
117   my (%system) = @_;
118
119   # Set name if not currently set  
120   $system{name} = $host unless $system{name};
121     
122   my ($status, @output);
123   
124   $system{port} ||= $port;
125
126   # Connect to clearexec server
127   $status = $clearexec->connectToServer($system{name}, $system{port});
128
129   unless ($status) {
130     warning "Unable to connect to $system{name}:$port";
131     return %system;
132   } # if
133
134   # Get OS info
135   my $cmd = 'uname -a';
136
137   ($status, @output) = $clearexec->execute($cmd);
138   
139   error "Unable to execute '$cmd' - $!", $status . join("\n". @output) if $status;
140   
141   $system{os} = $output[0];
142   
143   $system{clearagent} = 1;
144   
145   $cmd = 'uname -s';
146   
147   ($status, @output) = $clearexec->execute($cmd);
148
149   error "Unable to execute '$cmd' - $!", $status . join("\n". @output) if $status;
150   
151   # TODO: Need to handle this better
152   if ($output[0] =~ /sunos/i) {
153     $system{type} = 'Unix';
154   } elsif ($output[0] =~ /cygwin/i) {
155     $system{type} = 'Windows';
156   } else {
157     $system{type} = 'Linux';
158   } # if
159   
160   return %system;  
161 } # GatherSysInfo
162
163 sub AddFilesystems(%) {
164   my (%system) = @_;
165
166   my ($err, $msg);
167     
168   for (GetFilesystems %system) {
169     my %filesystem = %{$_};
170     
171     my %oldfilesystem = $clearadm->GetFilesystem(
172       $filesystem{system},
173       $filesystem{filesystem}
174     );
175     
176     if (%oldfilesystem) {
177       verbose "Updating filesystem $filesystem{system}:$filesystem{filesystem}";
178       
179       ($err, $msg) = $clearadm->UpdateFilesystem(
180         $filesystem{system},
181         $filesystem{filesystem},
182         %filesystem,
183       );
184       
185       error 'Unable to update filesystem '
186           . "$filesystem{system}:$filesystem{filesystem}" if $err;
187     } else {
188       verbose 'Adding filesystem '
189             . "$filesystem{system}:$filesystem{filesystem}";
190     
191       ($err, $msg) = $clearadm->AddFilesystem(%filesystem);
192
193       error 'Unable to add filesystem '
194           . "$filesystem{system}:$filesystem{filesystem}" if $err;
195     } # if
196   } # for
197   
198   return ($err, $msg);  
199 } # AddFilesystems
200
201 sub AddSystem($) {
202   my ($system) = @_;
203   
204   verbose "Adding newhost $system";
205
206   my %system = GatherSysInfo;
207   
208   # If GatherSysInfo was able to connect to clearagent it will set this field
209   my $clearagent = delete $system{clearagent};
210   
211   my ($err, $msg) = $clearadm->AddSystem(%system);
212   
213   return ($err, $msg) if $err;
214     
215   if ($clearagent) {
216     return AddFilesystems %system;
217   } else {
218     return ($err, $msg);
219   } # if
220 } # AddSystem
221
222 sub UpdateSystem(%) {
223   my (%system) = @_;
224   
225   my ($err, $msg);
226   
227   %system = GatherSysInfo(%system);
228   
229   # If GatherSysInfo was able to connect to clearagent it will set this field
230   my $clearagent = delete $system{clearagent};
231   
232   return ($err, $msg) unless $clearagent;
233   
234   verbose "Updating existing host $system{name}";
235   
236   ($err, $msg) = $clearadm->UpdateSystem($system{name}, %system);
237     
238   return ($err, $msg) if $err;
239
240   ($err, $msg) = AddFilesystems %system;
241   
242   $clearexec->disconnectFromServer;
243   
244   return ($err, $msg);
245 } # UpdateSystem
246
247 # Main
248 $host = hostname;
249 $port = $Clearexec::CLEAROPTS{CLEAREXEC_PORT};
250
251 GetOptions(
252   'usage'   => sub { Usage },
253   'verbose' => sub { set_verbose },
254   'debug'   => sub { set_debug },
255   'delete'  => \$delete,
256   'host=s'  => \$host,
257   'port=s'  => \$port,
258 ) or Usage "Invalid parameter";
259
260 Usage 'Extraneous options: ' . join ' ', @ARGV if @ARGV;
261
262 if ($delete) {
263   error "Must specify -host if you specify -delete", 1 unless $host;
264 } # if
265
266 # Announce ourselves
267 verbose "$FindBin::Script V$VERSION";
268
269 my ($err, $msg);
270
271 if ($delete) {
272   display_nolf "Delete host $host (y/N):";
273   
274   my $answer = <STDIN>;
275   
276   if ($answer =~ /(y|yes)/i) {
277     ($err, $msg) = $clearadm->DeleteSystem($host);
278   
279     if ($err == 0) {
280        error "No host named $host in database";
281     } elsif ($err < 0) {
282       error "Unable to delete $host" . $msg, $err;
283     } else {
284       verbose "Deleted host $host";
285     } # if
286   } else {
287         display "Host $host not deleted";
288   } # if
289 } else {
290   if ($host eq 'all') {
291     for ($clearadm->FindSystem) {
292       my %system = %$_;
293       
294       ($err, $msg) = UpdateSystem(%system);
295   
296       error "Unable to update host $system{name}\n$msg", $err if $err;
297     } # for
298   } else {
299     my %system = $clearadm->GetSystem($host);
300     
301     if (%system) {
302       ($err, $msg) = UpdateSystem(%system);
303     } else {
304       ($err, $msg) = AddSystem($host);
305     } # if
306
307     if ($err) {
308       my $errmsg  = 'Unable to ';
309          $errmsg .= %system ? 'update' : 'add';
310          $errmsg .= " host $host\$msg"; 
311
312       error "Unable to add host $host\n$msg", $err;
313     } # if
314   } # if
315 } # if
316
317 =pod
318
319 =head1 CONFIGURATION AND ENVIRONMENT
320
321 DEBUG: If set then $debug is set to this level.
322
323 VERBOSE: If set then $verbose is set to this level.
324
325 TRACE: If set then $trace is set to this level.
326
327 =head1 DEPENDENCIES
328
329 =head2 Perl Modules
330
331 L<FindBin>
332
333 L<Getop::Long|Getopt::Long>
334
335 L<Sys::Hostname|Sys::Hostname>
336
337 =head2 ClearSCM Perl Modules
338
339 =begin man 
340
341  Clearadm
342  Clearexec
343  Display
344  Utils
345
346 =end man
347
348 =begin html
349
350 <blockquote>
351 <a href="http://clearscm.com/php/scm_man.php?file=clearadm/lib/Clearadm.pm">Clearadm</a><br>
352 <a href="http://clearscm.com/php/scm_man.php?file=clearadm/lib/Clearexec.pm">Clearexec</a><br>
353 <a href="http://clearscm.com/php/scm_man.php?file=lib/Display.pm">Display</a><br>
354 <a href="http://clearscm.com/php/scm_man.php?file=lib/Utils.pm">Utils</a><br>
355 </blockquote>
356
357 =end html
358
359 =head1 BUGS AND LIMITATIONS
360
361 There are no known bugs in this script
362
363 Please report problems to Andrew DeFaria <Andrew@ClearSCM.com>.
364
365 =head1 LICENSE AND COPYRIGHT
366
367 Copyright (c) 2010, ClearSCM, Inc. All rights reserved.
368
369 =cut