File Coverage

blib/lib/NBU/Host.pm
Criterion Covered Total %
statement 22 277 7.9
branch 0 100 0.0
condition 0 18 0.0
subroutine 6 33 18.1
pod 0 27 0.0
total 28 455 6.1


line stmt bran cond sub pod time code
1             #
2             # Copyright (c) 2002 Paul Winkeler. All Rights Reserved.
3             # This program is free software; you may redistribute it and/or modify it under
4             # the same terms as Perl itself.
5             #
6             package NBU::Host;
7              
8 1     1   5 use strict;
  1         1  
  1         28  
9 1     1   4 use Carp;
  1         1  
  1         64  
10              
11             my %hostList;
12              
13             BEGIN {
14 1     1   5 use Exporter ();
  1         2  
  1         15  
15 1     1   2181 use AutoLoader qw(AUTOLOAD);
  1         3525  
  1         6  
16 1     1   38 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $AUTOLOAD);
  1         3  
  1         259  
17 1     1   3 $VERSION = do { my @r=(q$Revision: 1.33 $=~/\d+/g); sprintf "%d."."%02d"x$#r,@r };
  1         7  
  1         11  
18 1         16 @ISA = qw();
19 1         3 @EXPORT = qw();
20 1         2 @EXPORT_OK = qw();
21 1         3771 %EXPORT_TAGS = qw();
22             }
23              
24             my %aliases;
25             sub loadAlias {
26 0     0 0   my $proto = shift;
27 0           my ($alias, $canonical) = @_;
28              
29 0           $aliases{$alias} = $canonical;
30             }
31              
32             sub new {
33 0     0 0   my $proto = shift;
34 0           my $host;
35              
36 0 0         if (@_) {
37 0           my $name = shift;
38 0 0         $name = $aliases{$name} if (exists($aliases{$name}));
39             # my $keyName = substr($name, 0, 12);
40 0           my $keyName = $name;
41              
42 0 0         if (!($host = $hostList{$keyName})) {
43 0           $host = {};
44 0           bless $host, $proto;
45 0           $host->{NAME} = $name;
46              
47 0           $hostList{$keyName} = $host;
48              
49 0           $host->{ENROLLED} = 0;
50 0           $host->{MM} = 0;
51 0           $host->{MMTYPE} = 0;
52             }
53             }
54 0           return $host;
55             }
56              
57             sub populate {
58 0     0 0   my $proto = shift;
59              
60 0           my $pipe = NBU->cmd("bpclclients -allunique -noheader |");
61 0           while (<$pipe>) {
62 0           my ($platform, $os, $name) = split;
63 0           my $host = NBU::Host->new($name);
64              
65 0           $host->os($os);
66 0           $host->platform($platform);
67             }
68 0           close($pipe);
69             }
70              
71             sub byName {
72 0     0 0   my $proto = shift;
73 0           my $name = shift;
74 0           my $keyName = substr($name, 0, 12);
75              
76 0 0         if (my $host = $hostList{$keyName}) {
77 0           return $host;
78             }
79 0           return undef;
80             }
81              
82             sub list {
83 0     0 0   my $proto = shift;
84              
85 0           return (values %hostList);
86             }
87              
88             sub enrolled {
89 0     0 0   my $self = shift;
90              
91 0           $self->{ENROLLED} = 1;
92             }
93              
94             sub mediaManager {
95 0     0 0   my $self = shift;
96              
97 0 0         if (@_) {
98 0           $self->{MM} = shift;
99             }
100 0           return $self->{MM};
101             }
102              
103             sub roboticMediaManager {
104 0     0 0   my $self = shift;
105              
106 0 0         if (@_) {
107 0           $self->{MMTYPE} = shift;
108             }
109 0           return $self->{MMTYPE};
110             }
111              
112             sub loadClasses {
113 0     0 0   my $self = shift;
114              
115 0           NBU::Pool->populate;
116              
117 0           my $pipe = NBU->cmd("bpcllist -byclient ".$self->name." -l |");
118 0           NBU::Class->loadClasses($pipe, "CLIENT", $self->clientOf);
119              
120 0           close($pipe);
121             }
122              
123             sub makeClassMember {
124 0     0 0   my $self = shift;
125 0           my $newClass = shift;
126              
127 0 0         if (!defined($self->{CLASSES})) {
128 0           $self->{CLASSES} = [];
129             }
130              
131 0           my $classesR = $self->{CLASSES};
132 0           push @$classesR, $newClass;
133              
134 0           return $newClass;
135             }
136              
137             sub classes {
138 0     0 0   my $self = shift;
139              
140 0 0         $self->loadClasses if (!$self->{ENROLLED});
141              
142 0           my $classesR = $self->{CLASSES};
143 0 0         if (defined($classesR)) {
144 0           return (@$classesR);
145             }
146 0           return ();
147             }
148              
149             sub name {
150 0     0 0   my $self = shift;
151              
152 0           return $self->{NAME};
153             }
154              
155             sub loadConfig {
156 0     0 0   my $self = shift;
157              
158 0 0         return 1 if ($self->{CONFIGLOADED});
159 0           $self->{PLATFORM} = undef;
160 0           $self->{OS} = undef;
161 0           $self->{NBUVERSION} = undef;
162 0           $self->{RELEASE} = undef;
163 0           $self->{RELEASEID} = undef;
164 0           $self->{CONFIGLOADED} = 1;
165              
166 0           my $pipe = NBU->cmd("bpgetconfig -g ".$self->name." |");
167 0 0         unless (defined($_ = <$pipe>)) { close($pipe); return; } chop; s/[\s]*$//;
  0            
  0            
  0            
  0            
168 0 0         if (/Client of ([\S]+)/) {
169 0           $self->{MASTER} = NBU::Host->new($1);
170 0           NBU->addMaster($self->{MASTER});
171             }
172             else {
173 0           $self->{MEDIASERVER} = 1;
174             }
175              
176             # OS on this machine
177 0 0         unless (defined($_ = <$pipe>)) { close($pipe); return; } chop; s/[\s]*$//;
  0            
  0            
  0            
  0            
178 0 0         if (/^([\S]+), ([\S]+)$/) {
179 0           $self->{PLATFORM} = $1;
180 0           $self->{OS} = $2;
181             }
182             else {
183 0           $self->{PLATFORM} = $self->{OS} = $_;
184             }
185              
186             # Now get the NetBackup version information
187             # All the hosts in the cluster better be running the same version
188             # but we're not checking for that at this time.
189 0 0         unless (defined($_ = <$pipe>)) { close($pipe); return; } chop; s/[\s]*$//;
  0            
  0            
  0            
  0            
190 0           $self->{NBUVERSION} = $_;
191              
192             # Product identifier
193 0 0         unless (defined($_ = <$pipe>)) { close($pipe); return; } chop; s/[\s]*$//;
  0            
  0            
  0            
  0            
194              
195 0 0         if (defined($_ = <$pipe>)) {
196 0           chop; s/[\s]*$//;
  0            
197 0           $self->{RELEASE} = $_;
198             }
199              
200 0 0 0       if (defined($_ = <$pipe>) && ($_ !~ /^[\s]*$/)) {
201 0           chop; s/[\s]*$//;
  0            
202 0           $self->{RELEASEID} = $_;
203             }
204             else {
205 0           $self->{RELEASEID} = "000000";
206             }
207              
208 0 0         if ($self->releaseID >= "450000") {
209             # Install path
210 0 0         return unless defined($_ = <$pipe>); chop; s/[\s]*$//;
  0            
  0            
211             # Detailed OS
212 0 0         return unless defined($_ = <$pipe>); chop; s/[\s]*$//;
  0            
  0            
213 0           my ($os, $v) = split;
214 0           $self->{OS} = $os;
215             }
216            
217 0           close($pipe);
218              
219             # The -f option used to tell us, when we were media managers,
220             # which host was our master with the "Client of" line. With 4.5 this
221             # feature has been removed. Now we run bpgetconfig against ourselves
222             # and use the "first server in the list must be the master" rule.
223 0           $pipe = NBU->cmd("bpgetconfig -X |");
224 0           while (<$pipe>) {
225 0 0 0       if ((/SERVER = ([\S]+)/) && !defined($self->{MASTER})) {
226 0           $self->{MASTER} = NBU::Host->new($1);
227             }
228 0 0         if (/EMMSERVER = ([\S]+)/) {
229 0           $self->{EMMSERVER} = NBU::Host->new($1);
230             }
231             }
232 0           close($pipe);
233              
234 0           my $detailAvailable;
235 0           $pipe = NBU->cmd("bpclient -All -FI |");
236 0 0         unless (defined($_ = <$pipe>)) { close($pipe); return; } chop; s/[\s]*$//;
  0            
  0            
  0            
  0            
237 0           while (<$pipe>) {
238 0 0         if (/$self->name/i) {
239 0           $detailAvailable = 1;
240 0           last;
241             }
242             }
243 0           close($pipe);
244              
245 0 0         if ($detailAvailable) {
246 0           $pipe = NBU->cmd("bpclient -client ".$self->name." -l |");
247 0 0         unless (defined($_ = <$pipe>)) { close($pipe); return; } chop; s/[\s]*$//;
  0            
  0            
  0            
  0            
248 0           close($pipe);
249             }
250             }
251              
252             sub clientOf {
253 0     0 0   my $self = shift;
254              
255 0           $self->loadConfig;
256 0           return $self->{MASTER};
257             }
258              
259             sub EMMserver {
260 0     0 0   my $self = shift;
261              
262 0           $self->loadConfig;
263 0           return $self->{EMMSERVER};
264             }
265              
266             sub platform {
267 0     0 0   my $self = shift;
268              
269 0 0         if (@_) {
270 0           $self->{PLATFORM} = shift;
271             }
272             else {
273 0           $self->loadConfig;
274             }
275              
276 0           return $self->{PLATFORM};
277             }
278              
279             sub os {
280 0     0 0   my $self = shift;
281              
282 0 0         if (@_) {
283 0           $self->{OS} = shift;
284             }
285             else {
286 0           $self->loadConfig;
287             }
288              
289 0           return $self->{OS};
290             }
291              
292             sub NBUVersion {
293 0     0 0   my $self = shift;
294              
295 0 0         if (@_) {
296 0           $self->{NBUVERSION} = shift;
297             }
298             else {
299 0           $self->loadConfig;
300             }
301              
302 0           return $self->{NBUVERSION};
303             }
304              
305             sub NBUmajorVersion {
306 0     0 0   my $self = shift;
307              
308 0           $self->NBUVersion =~ /^([\d])\.([\d\.]*$)/;
309 0           return $1;
310             }
311              
312             sub IPaddress {
313 0     0 0   my $self = shift;
314              
315 0 0         if (!defined($self->{IPADDRESS})) {
316 0           my $rawAddress = (gethostbyname($self->name))[4];
317 0           my @octets = unpack("C4", $rawAddress);
318 0           $self->{IPADDRESS} = join(".", @octets);
319             }
320              
321 0           return $self->{IPADDRESS};
322             }
323              
324             sub release {
325 0     0 0   my $self = shift;
326              
327 0 0         if (@_) {
328 0           $self->{RELEASE} = shift;
329             }
330             else {
331 0           $self->loadConfig;
332             }
333              
334 0           return $self->{RELEASE};
335             }
336              
337             sub releaseID {
338 0     0 0   my $self = shift;
339              
340 0 0         if (@_) {
341 0           $self->{RELEASEID} = shift;
342             }
343             else {
344 0           $self->loadConfig;
345             }
346              
347 0           return $self->{RELEASEID};
348             }
349              
350             sub loadCoverage {
351 0     0 0   my $self = shift;
352 0           my $name = $self->name;
353              
354 0           my %coverage;
355             my $loadOK;
356              
357 0           my $pipe = NBU->cmd("bpcoverage -c $name -no_cov_header -no_hw_header |");
358 0           while (<$pipe>) {
359 0 0 0       if (!$loadOK) {
    0 0        
360 0 0         if (/^CLIENT: $name/) {
361 0           while (<$pipe>) {
362 0 0 0       last if (/Mount Point/ || /Drive Letter/);
363             }
364 0           $_ = <$pipe>;
365 0           $loadOK = 1;
366             }
367             }
368             elsif ($loadOK && !(/^[\s]*$/) && !(/ Exit status/)) {
369             #
370             # Preserve input line in local variable because some methods called below
371             # open other streams and thus clobber the global $_!
372 0           my $l = $_;
373              
374 0 0         if ($self->os =~ /rs6000_42|SunOS|[Ss]olaris|linux|hp10.20/) {
    0          
375 0           $_ = $l;
376 0           my ($mountPoint, @remainder) = split;
377 0           my ($deviceFile, $className, $status) = @remainder;
378              
379 0 0         next if ($deviceFile !~ /^\//);
380              
381 0 0         if ($className eq "UNCOVERED") {
382 0           $coverage{$mountPoint} = undef;
383             }
384             else {
385 0           $className =~ s/^\*//;
386 0           my $clR = $coverage{$mountPoint};
387 0 0         if (!$clR) {
388 0           $coverage{$mountPoint} = $clR = [];
389             }
390 0           my $class = NBU::Class->byName($className, $self->clientOf);
391 0           $class->providesCoverage(1);
392 0           push @$clR, $class;
393             }
394             }
395             elsif ($self->os =~ /Windows(NET|NT|2000|2003|XP)/) {
396 0           $_ = $l;
397 0           s/^[\s]*([\S].*:.)//; my $mountPoint = $1;
  0            
398 0           my (@remainder) = split;
399 0           my $deviceFile;
400              
401 0 0 0       if ((($self->releaseID eq "451000") && defined($self->{MEDIASERVER}))) {
402 0           $deviceFile = shift @remainder;
403             }
404 0           my ($className, $status) = @remainder;
405 0 0         if ($className eq "UNCOVERED") {
406 0           $coverage{$mountPoint} = undef;
407             }
408             else {
409 0           $className =~ s/^\*//;
410 0           my $clR = $coverage{$mountPoint};
411 0 0         if (!$clR) {
412 0           $coverage{$mountPoint} = $clR = [];
413             }
414 0           my $class = NBU::Class->byName($className, $self->clientOf);
415 0 0         print STDERR "Unknown class referenced: $className\n" if (!defined($class));
416 0           $class->providesCoverage(1);
417 0           push @$clR, $class;
418             }
419             }
420             else {
421 0           print "coverage from ".$self->os.": $_";
422             }
423             }
424             else {
425 0           last;
426             }
427             }
428 0           close($pipe);
429              
430 0           $self->{COVERAGE} = \%coverage;
431             }
432              
433             sub coverage {
434 0     0 0   my $self = shift;
435              
436 0 0         if (!$self->{COVERAGE}) {
437 0           $self->loadCoverage;
438             }
439              
440 0           my $coverageR = $self->{COVERAGE};
441 0           return (%$coverageR);
442             }
443              
444             #
445             # Add an image to a host's list of backup images
446             sub addImage {
447 0     0 0   my $self = shift;
448 0           my $image = shift;
449            
450 0 0         $self->{IMAGES} = {} if (!defined($self->{IMAGES}));
451              
452 0           my $images = $self->{IMAGES};
453              
454 0           $$images{$image->id} = $image;
455             }
456              
457             #
458             # Load the list of images run against this host
459             sub loadImages {
460 0     0 0   my $self = shift;
461              
462 0 0         if (!defined($self->{ALLIMAGES})) {
463 0           NBU::Image->loadImages(NBU->cmd("bpimmedia -l -client ".$self->name." |"));
464             }
465 0           return ($self->{ALLIMAGES} = $self->{IMAGES});
466             }
467              
468             sub images {
469 0     0 0   my $self = shift;
470              
471 0           $self->loadImages;
472              
473 0 0         if (defined(my $images = $self->{IMAGES})) {
474 0           return (values %$images);
475             }
476             else {
477 0           return ();
478             }
479             }
480              
481             1;
482              
483             __END__