File Coverage

blib/lib/NBU/Class.pm
Criterion Covered Total %
statement 28 305 9.1
branch 0 174 0.0
condition 0 15 0.0
subroutine 8 47 17.0
pod 0 39 0.0
total 36 580 6.2


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::Class;
7              
8 1     1   5 use strict;
  1         1  
  1         31  
9 1     1   6 use Carp;
  1         1  
  1         56  
10              
11 1     1   587 use NBU::Host;
  1         3  
  1         43  
12 1     1   754 use NBU::Schedule;
  1         4  
  1         37  
13              
14             my %classRoom;
15              
16             BEGIN {
17 1     1   7 use Exporter ();
  1         2  
  1         20  
18 1     1   7 use AutoLoader qw(AUTOLOAD);
  1         1  
  1         7  
19 1     1   38 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $AUTOLOAD);
  1         2  
  1         151  
20 1     1   3 $VERSION = do { my @r=(q$Revision: 1.29 $=~/\d+/g); sprintf "%d."."%02d"x$#r,@r };
  1         6  
  1         8  
21 1         20 @ISA = qw();
22 1         3 @EXPORT = qw();
23 1         1 @EXPORT_OK = qw();
24 1         3587 %EXPORT_TAGS = qw();
25             }
26              
27             sub new {
28 0     0 0   my $proto = shift;
29 0           my $class;
30              
31 0 0         if (@_) {
32 0           my $name = shift;
33 0           my $type = shift;
34 0           my $master = shift;
35              
36 0 0 0       if (!exists($classRoom{$name})) {
    0          
37 0           $class = {
38             CLIENTS => [],
39             };
40 0           bless $class, $proto;
41              
42 0           $classRoom{$class->{NAME} = $name} = $class;
43 0           $class->{TYPE} = $type;
44 0           $class->{LOADED} = 0;
45             }
46             elsif (!defined($class = $classRoom{$name}) || ($class->{TYPE} ne $type)) {
47 0           $class = {
48             CLIENTS => [],
49             };
50 0           bless $class, $proto;
51              
52 0           $classRoom{$class->{NAME} = $name} = undef;
53 0           $class->{TYPE} = $type;
54 0           $class->{LOADED} = 0;
55             }
56 0           $class->{MASTER} = $master;
57             }
58 0           return $class;
59             }
60              
61             my %classTypes = (
62             0 => "Standard",
63             3 => "Apollo_WBAK",
64             4 => "Oracle",
65             6 => "Informix",
66             7 => "Sybase",
67             10 => "NetWare",
68             11 => "BackTrack",
69             12 => "Auspex_Fastback",
70             13 => "Windows_NT",
71             14 => "OS2",
72             15 => "SQL_Server",
73             16 => "Exchange",
74             17 => "SAP",
75             18 => "DB2",
76             19 => "NDMP",
77             20 => "FlashBackup",
78             21 => "SplitMirror",
79             22 => "AFS",
80             29 => "VCB",
81             30 => "Vault",
82             35 => "NBU-Catalog",
83             );
84              
85             my $rollCalled = 0;
86             sub populate {
87 0     0 0   my $proto = shift;
88 0 0         my $self = ref($proto) ? $proto : undef;;
89 0           my $master = shift;
90              
91 0 0         if (!defined($master)) {
92 0           my @masters = NBU->masters; $master = $masters[0];
  0            
93             }
94              
95 0           NBU::Pool->populate;
96              
97 0 0         my $source = defined($self) ? $self->name : "-allclasses";
98 0           my $pipe = NBU->cmd("bpcllist $source -l -M ".$master->name." |");
99              
100 0 0         $proto->loadClasses($pipe, defined($self) ? "CLASS" : "ALL", $master);
101              
102             #
103             # If the entire class was being loaded, we'll consider the roll to
104             # have been called.
105 0           $rollCalled = !defined($self);
106             }
107              
108             sub loadClasses {
109 0     0 0   my $proto = shift;
110 0           my $pipe = shift;
111 0           my $focus = shift;
112 0           my $master = shift;
113              
114 0           my $class;
115             my $className;
116 0           my $schedule;
117              
118 0           while (<$pipe>) {
119 0           chop;
120 0 0         if (/^CLASS/) {
121             #
122             # Simply remember the initial class name and defer creating it until we know its
123             # type on the next INFO line. Just to be safe, we'll set the running class variable
124             # to null...
125 0           my ($tag, $name, $ptr1, $u1, $u2, $u3, $ptr2) = split;
126 0           $className = $name;
127 0           $class = undef;
128 0           next;
129             }
130 0 0         if (/^NAMES/) {
131 0           next;
132             }
133 0 0         if (/^INFO/) {
134 0           my ($tag, $type, $networkDrives, $clientCompression, $priority, $ptr1,
135             $u2, $u3, $maxJobs, $crossMounts, $followNFS,
136             $inactive, $TIR, $u6, $u7, $restoreFromRaw, $multipleDataStreams, $ptr2) = split;
137              
138 0           $class = NBU::Class->new($className, $type, $master);
139 0           $class->{LOADED} = $focus =~ /CLASS|ALL/;
140              
141 0           $class->{NETWORKDRIVES} = $networkDrives;
142 0           $class->{COMPRESSION} = $clientCompression;
143 0           $class->{PRIORITY} = $priority;
144 0           $class->{MAXJOBS} = $maxJobs;
145 0           $class->{CROSS} = $crossMounts;
146 0           $class->{FOLLOW} = $followNFS;
147 0           $class->{ACTIVE} = !$inactive;
148 0           $class->{TIR} = $TIR;
149 0           $class->{RESTOREFROMRAW} = $restoreFromRaw;
150 0           $class->{MDS} = $multipleDataStreams;
151 0           next;
152             }
153 0 0         if (/^KEY /) {
154 0           my ($tag, @keys) = split;;
155 0 0         $class->{KEYS} = \@keys unless ($keys[0] eq "*NULL*");
156 0           next;
157             }
158 0 0         if (/^BCMD /) {
159 0           next;
160             }
161 0 0         if (/^RCMD /) {
162 0           next;
163             }
164 0 0         if (/^RES /) {
165 0           my ($tag, @residences) = split;
166 0 0         $class->{RESIDENCE} = NBU::StorageUnit->byLabel($residences[0]) unless ($residences[0] eq "*NULL*");
167 0           next;
168             }
169 0 0         if (/^POOL /) {
170 0           my ($tag, @pools) = split;
171 0 0         $class->{POOL} = NBU::Pool->byName($pools[0]) unless ($pools[0] eq "*NULL*");
172 0           next;
173             }
174 0 0         if (/^CLIENT /) {
175 0           my ($tag, $name, $platform, $os) = split;
176 0           my $client = NBU::Host->new($name);
177 0           $class->loadClient($client);
178 0           $client->makeClassMember($class);
179 0 0         $client->enrolled if ($focus =~ /CLIENT|ALL/);
180 0           next;
181             }
182 0 0         if (/^INCLUDE /) {
183 0           my ($tag, $path) = split(/[\s]+/, $_, 2);
184 0           $class->include($path);
185 0           next;
186             }
187 0 0         if (/^EXCLUDE /) {
188 0           my ($tag, $path) = split(/[\s]+/, $_, 2);
189 0           $class->exclude($path);
190 0           next;
191             }
192 0 0         if (/^SCHED /) {
193 0           my ($tag, $name, $type, @schedAttr) = split;
194 0           $schedule = $class->loadSchedule(NBU::Schedule->new($class, $name, $type, $pipe, @schedAttr));
195 0           next;
196             }
197             }
198 0           close($pipe);
199             }
200              
201             sub byName {
202 0     0 0   my $proto = shift;
203 0           my $name = shift;
204              
205 0 0         $proto->populate if (!$rollCalled);
206 0 0         if (my $class = $classRoom{$name}) {
207 0           return $class;
208             }
209 0           return undef;
210             }
211              
212             sub list {
213 0     0 0   my $proto = shift;
214              
215 0 0         $proto->populate if (!$rollCalled);
216              
217 0           return (values %classRoom);
218             }
219              
220             sub create {
221 0     0 0   my $proto = shift;
222              
223             }
224              
225             sub clone {
226 0     0 0   my $self = shift;
227              
228             }
229              
230             sub update {
231 0     0 0   my $self = shift;
232              
233 0           return $self;
234             }
235              
236             sub delete {
237 0     0 0   my $self = shift;
238              
239 0           return $self;
240             }
241              
242             sub loadClient {
243 0     0 0   my $self = shift;
244 0           my $newClient = shift;
245              
246 0           my $clientListR = $self->{CLIENTS};
247 0           push @$clientListR, $newClient;
248              
249 0           return $newClient;
250             }
251              
252             sub clients {
253 0     0 0   my $self = shift;
254              
255 0 0         $self->populate if (!$self->{LOADED});
256 0           my $clientListR = $self->{CLIENTS};
257 0 0         return (defined($clientListR) ? (@$clientListR) : ());
258             }
259              
260             sub master {
261 0     0 0   my $self = shift;
262              
263 0           return $self->{MASTER};
264             }
265              
266             sub loadSchedule {
267 0     0 0   my $self = shift;
268 0           my $newSchedule = shift;
269 0           my $listR;
270              
271 0 0         print "Policy ".$self->name." has undefined schedule?\n" if (!defined($newSchedule));
272 0 0 0       if ($self->policyAware && ($newSchedule->type eq "UBAK")) {
273 0 0         if (!defined($self->{POLICIES})) {
274 0           $self->{POLICIES} = [];
275             }
276 0           $listR = $self->{POLICIES};
277             }
278             else {
279 0 0         if (!defined($self->{SCHEDULES})) {
280 0           $self->{SCHEDULES} = [];
281             }
282 0           $listR = $self->{SCHEDULES};
283             }
284              
285 0           push @$listR, $newSchedule;
286              
287 0           return $newSchedule;
288             }
289              
290             sub schedules {
291 0     0 0   my $self = shift;
292              
293 0 0         $self->populate if (!$self->{LOADED});
294 0           my $schedulesR = $self->{SCHEDULES};
295 0 0         return (defined($schedulesR) ? (@$schedulesR) : ());
296             }
297              
298             sub policies {
299 0     0 0   my $proto = shift;
300 0 0         my $self = ref($proto) ? $proto : undef;;
301              
302 0 0         $proto->populate if (!$self->{LOADED});
303 0           my $policiesR = $proto->{POLICIES};
304 0 0         return (defined($policiesR) ? (@$policiesR) : ());
305             }
306              
307             sub exclude {
308 0     0 0   my $self = shift;
309              
310 0 0         $self->populate if (!$self->{LOADED});
311 0 0         if (@_) {
312 0 0         if (!defined($self->{EXCLUDE})) {
313 0           $self->{EXCLUDE} = [];
314             }
315 0           my $excludeListR = $self->{EXCLUDE};
316 0           my $newExclude = shift;
317              
318 0           push @$excludeListR, $newExclude;
319             }
320 0           my $excludeListR = $self->{EXCLUDE};
321            
322 0 0         return (defined($excludeListR) ? (@$excludeListR) : ());
323             }
324              
325             sub include {
326 0     0 0   my $self = shift;
327              
328 0 0         $self->populate if (!$self->{LOADED});
329 0 0         if (@_) {
330 0 0         if (!defined($self->{INCLUDE})) {
331 0           $self->{INCLUDE} = [];
332             }
333 0           my $includeListR = $self->{INCLUDE};
334 0           my $newInclude = shift;
335              
336 0           push @$includeListR, $newInclude;
337             }
338 0           my $includeListR = $self->{INCLUDE};
339            
340 0 0         return (defined($includeListR) ? (@$includeListR) : ());
341             }
342              
343             sub pool {
344 0     0 0   my $self = shift;
345              
346 0 0         $self->populate if (!$self->{LOADED});
347 0 0         if (@_) {
348 0 0         print $self->name." already has a pool: ".$self->{POOL}."\n" if ($self->{POOL});
349 0           $self->{POOL} = shift;
350             }
351              
352 0           return $self->{POOL};
353             }
354              
355             sub residence {
356 0     0 0   my $self = shift;
357              
358 0 0         $self->populate if (!$self->{LOADED});
359 0 0         if (@_) {
360 0 0         print $self->name." already has a residence: ".$self->{RESIDENCE}."\n" if ($self->{RESIDENCE});
361 0           $self->{RESIDENCE} = shift;
362             }
363              
364 0           return $self->{RESIDENCE};
365             }
366              
367             sub storageUnit {
368 0     0 0   my $self = shift;
369              
370 0           return $self->residence(@_);
371             }
372              
373             my %policyAware = (
374             4 => "Oracle",
375             6 => "Informix",
376             7 => "Sybase",
377             15 => "SQL_Server",
378             16 => "Exchange",
379             17 => "SAP",
380             18 => "DB2",
381             );
382             sub policyAware {
383 0     0 0   my $self = shift;
384              
385 0 0         $self->populate if (!$self->{LOADED});
386 0           return exists($policyAware{$self->{TYPE}});
387             }
388              
389             sub type {
390 0     0 0   my $self = shift;
391              
392 0 0         $self->populate if (!$self->{LOADED});
393 0 0         if (@_) {
394 0           $self->{TYPE} = shift;
395             }
396 0 0         print STDERR "Asked to return unknown type ".$self->{TYPE}." for ".$self->{NAME}."\n"
397             if !defined($classTypes{$self->{TYPE}});
398 0           return $classTypes{$self->{TYPE}};
399             }
400              
401             sub license {
402 0     0 0   my $self = shift;
403              
404 0           return NBU::Licenses->licenseForClass($self->{TYPE}, $self->master);
405             }
406              
407             sub keywords {
408 0     0 0   my $self = shift;
409              
410 0 0         $self->populate if (!$self->{LOADED});
411 0 0         if (@_) {
412 0           $self->{KEYWORDS} = shift;
413             }
414 0           return $self->{KEYWORDS};
415             }
416              
417             sub DR {
418 0     0 0   my $self = shift;
419              
420 0 0         $self->populate if (!$self->{LOADED});
421 0 0         if (@_) {
422 0           $self->{DR} = shift;
423             }
424 0           return $self->{DR};
425             }
426              
427             sub maxJobs {
428 0     0 0   my $self = shift;
429              
430 0 0         $self->populate if (!$self->{LOADED});
431 0 0         if (@_) {
432 0           $self->{MAXJOBS} = shift;
433             }
434 0           return $self->{MAXJOBS};
435             }
436              
437             sub priority {
438 0     0 0   my $self = shift;
439              
440 0 0         $self->populate if (!$self->{LOADED});
441 0 0         if (@_) {
442 0           $self->{PRIORITY} = shift;
443             }
444 0           return $self->{PRIORITY};
445             }
446              
447             sub multipleDataStreams {
448 0     0 0   my $self = shift;
449              
450 0 0         $self->populate if (!$self->{LOADED});
451 0 0         if (@_) {
452 0           $self->{MDS} = shift;
453             }
454 0           return $self->{MDS};
455             }
456              
457             sub BLIB {
458 0     0 0   my $self = shift;
459              
460 0 0         $self->populate if (!$self->{LOADED});
461 0 0         if (@_) {
462 0           $self->{BLIB} = shift;
463             }
464 0           return $self->{BLIB};
465             }
466              
467             #
468             # TIR codes are:
469             # 0 off
470             # 1 on
471             # 2 on with move detection
472             sub TIR {
473 0     0 0   my $self = shift;
474              
475 0 0         $self->populate if (!$self->{LOADED});
476 0 0         if (@_) {
477 0           $self->{TIR} = shift;
478             }
479 0           return $self->{TIR};
480             }
481              
482             sub crossMountPoints {
483 0     0 0   my $self = shift;
484              
485 0 0         $self->populate if (!$self->{LOADED});
486 0 0         if (@_) {
487 0           $self->{CROSS} = shift;
488             }
489 0           return $self->{CROSS};
490             }
491              
492             sub followNFSMounts {
493 0     0 0   my $self = shift;
494              
495 0 0         $self->populate if (!$self->{LOADED});
496 0 0         if (@_) {
497 0           $self->{FOLLOW} = shift;
498             }
499 0           return $self->{FOLLOW};
500             }
501              
502             sub clientCompression {
503 0     0 0   my $self = shift;
504              
505 0 0         $self->populate if (!$self->{LOADED});
506 0 0         if (@_) {
507 0           $self->{COMPRESSION} = shift;
508             }
509 0           return $self->{COMPRESSION};
510             }
511              
512             sub clientEncrypted {
513 0     0 0   my $self = shift;
514              
515 0 0         $self->populate if (!$self->{LOADED});
516 0 0         if (@_) {
517 0           $self->{ENCRYPTION} = shift;
518             }
519 0           return $self->{ENCRYPTION};
520             }
521              
522             sub active {
523 0     0 0   my $self = shift;
524              
525 0 0         $self->populate if (!$self->{LOADED});
526 0 0         if (@_) {
527 0           my $newState = shift;
528 0 0 0       if (($newState && !$self->{ACTIVE}) || (!$newState && $self->{ACTIVE})) {
      0        
      0        
529 0 0         if ($self->{ACTIVE} = $newState) {
530 0           NBU->cmd("bpclinfo ".$self->name." -update -active");
531             }
532             else {
533 0           NBU->cmd("bpclinfo ".$self->name." -update -inactive");
534             }
535             }
536             }
537 0           return $self->{ACTIVE};
538             }
539              
540             sub name {
541 0     0 0   my $self = shift;
542              
543 0 0         if (@_) {
544 0 0         if (defined($self->{NAME})) {
545 0           delete $classRoom{$self->{NAME}};
546             }
547 0           $self->{NAME} = shift;
548 0           $classRoom{$self->{NAME}} = $self;
549             }
550 0           return $self->{NAME};
551             }
552              
553             sub providesCoverage {
554 0     0 0   my $self = shift;
555              
556 0 0         $self->populate if (!$self->{LOADED});
557 0 0         if (@_) {
558 0           $self->{COVERS} = shift;
559             }
560              
561 0           return $self->{COVERS};
562             }
563              
564             #
565             # Load the list of images of this class
566             sub loadImages {
567 0     0 0   my $self = shift;
568              
569 0           NBU::Image->loadImages(NBU->cmd("bpimmedia -l -class ".$self->name." |"));
570             }
571              
572             sub images {
573 0     0 0   my $self = shift;
574              
575 0 0         if (!defined($self->{IMAGES})) {
576 0           $self->loadImages;
577              
578 0           my @images;
579 0           for my $client ($self->clients) {
580 0           for my $image ($client->images) {
581 0 0         push @images, $image if ($image->class == $self);
582             }
583             }
584              
585 0           $self->{IMAGES} = \@images;
586             }
587 0           my $imageListR = $self->{IMAGES};
588              
589 0           return (@$imageListR);
590             }
591              
592             1;
593              
594             __END__