Video Screencast Help

PERL script to print out schedule information in format for import to a spreadsheet.

Created: 03 Oct 2010 • Updated: 08 Oct 2010 | 19 comments
sandy321's picture
+10 10 Votes
Login to vote

Descripttion:

Use the Veritas NetBackup master server schedule data to create a comma separated version (.csv) file. Then Excel or other spreadsheet may be used to view schedules. Usefull to provide management persons with information.

===========================================================================================

THE SCRIPT IS AS FOLLOWS

============================================================================================

 

 

#!/usr/local/bin/perl -w
#
# Use on Veritas' NetBackup master server
#
# print out schedule information in format for import
# to a spreadsheet.
#

my @DAYS = (
	"Sun",
	"Sat",
	"Mon",
	"Tue",
	"Wed",
	"Thu",
	"Fri",
);

my @TYPE = (
	"FULL",
	"Unknown",
	"Unknown",
	"Unknown",
	"Cummulative-Incremental",
);

# this is the default install dir for netbackup class data
# yes, readdir is more efficient...
my @class = glob("/usr/openv/netbackup/db/class/*");

my $day_secs = 3600 * 24;
print "CLASS,CLIENT,TYPE,SCHEDULE,DAY,DAYN,WINDOWSTART,WINDOWLENGTH,STRT_SECS,END_SECS\n";
foreach $cls (@class) {
	my @clients = ();
	my $tmp = $cls;
	$tmp =~ s,.*/,,;

	# get client list
	if ( -f "${cls}/clients" ) {
		open(IN,"<${cls}/clients") or die;
		while (<IN>) {
			my ($clnt) = split(/ /,$_);
			push(@clients,$clnt);
		}
		close(IN);
	} else {
		push(@clients,"none");
	}

	my @scheds = glob("${cls}/schedule/*");
	foreach $schd (@scheds) {
		my @days = ();
		my $type = '';

		if ( -f "${schd}/days" ) {
			open (IN,"<${schd}/days") or die;
			while (<IN>) {
				my $strt_secs = 0;
				my $end_secs = 0;
				chomp;
				($dy,$start,$duration) = 
					split(/\s+/,$_);
				next if $duration == 0;

				$strt_secs = ($dy * $day_secs) + $start;
				$end_secs = $strt_secs + $duration;
				$dy = "$DAYS[$dy],$dy";
				$start = secs($start);
				$duration = secs($duration);

				push(@days,"$dy,$start,$duration,$strt_secs,$end_secs");
			}
			close(IN);
		}

		if ( -f "${schd}/info" ) {
			open (IN,"<${schd}/info") or die;
			while (<IN>) {
				chomp;
				($key,$type) = split(/\s+/,$_);
				if ( $key eq "SCHED_TYPE" ) {
					last;
				}
			}
			close(IN);
		}

		$type = $TYPE[$type];
		my $schd_tmp = $schd;
		$schd_tmp =~ s,.*/,,;
		foreach $clnt (@clients) {
			foreach $start_stop (@days) {
	  			# output comma delimited lines
	  			print "$tmp,$clnt,$type,$schd_tmp,$start_stop\n";
			}
		}
		#print "Schedule: $schd\n";
	}

}

sub secs {
	my $hr = '';
	my $min = '';
	my $sec = '';
	my $tm = shift;

	# convert from sec's to hr:min:sec for printout
	if ( $tm > 59 ) {
		my $hr = 0;
		my $sec = $tm % 60;
		my $min = $tm / 60;
		if ( $min > 59 ) {
		  my $tmp = $min % 60;
		  $hr = $min / 60;
		  $min = $tmp;
		}
		$tm = sprintf "%02d:%02d:%02d",$hr,$min,$sec;
	} else {
		$tm = sprintf "%02d:%02d:%02d",0,0,$tm;
	}
	return $tm;
}


#END OF SCRIPT

Comments 19 CommentsJump to latest comment

Don Wilder's picture

Thank you

Nice script

Do you have a way to add the storage unit to your script?

0
Login to vote
Don Wilder's picture

I figured out the proper settings and made the changes to have it output what I needed. :)
Here is the finished product... note fixed a couple bugs in your original script:

 

#!/usr/bin/perl -w
#
# Use on Veritas' NetBackup master server
#
# print out schedule information in format for import
# to a spreadsheet.
#

my @DAYS = (
        "Sun",
        "Mon",
        "Tue",
        "Wed",
        "Thu",
        "Fri",
        "Sat",
);

my @TYPE = (
        "FULL",
        "Differential-Incremental",
        "Cumulative-Incremental",
        "User-Backup",
        "User-Archive",
);

# this is the default install dir for netbackup class data
# yes, readdir is more efficient...
my @class = glob("/usr/openv/netbackup/db/class/*");

my $day_secs = 3600 * 24;
print "POLICY,STORAGEUNIT,CLIENT,TYPE,SCHEDULE,DAY,DAYN,WINDOWSTART,WINDOWLENGTH,STRT_SECS,END_SECS\n";
foreach $cls (@class) {
        my @clients = ();
        my $sto = '';
        my $tmp = $cls;
        $tmp =~ s,.*/,,;

        # get client list
        if ( -f "${cls}/clients" ) {
                open(IN,"<${cls}/clients") or die;
                while (<IN>) {
                        my ($clnt) = split(/ /,$_);
                        push(@clients,$clnt);
                }
                close(IN);
        } else {
                push(@clients,"none");
        }

        # get storage unit
        if ( -f "${cls}/info" ) {
                open(IN,"<${cls}/info") or die;
                while (<IN>) {
                        chomp;
                        ($key,$sto) = split(/\s+/,$_);
                        if ( $key eq "RESIDENCE" ) {
                                last;
                        }
                }
                close(IN);
        }

        my @scheds = glob("${cls}/schedule/*");
        foreach $schd (@scheds) {
                my @days = ();
                my $type = '';

                if ( -f "${schd}/days" ) {
                        open (IN,"<${schd}/days") or die;
                        while (<IN>) {
                                my $strt_secs = 0;
                                my $end_secs = 0;
                                chomp;
                                ($dy,$start,$duration) =
                                        split(/\s+/,$_);
                                next if $duration == 0;

                                $strt_secs = ($dy * $day_secs) + $start;
                                $end_secs = $strt_secs + $duration;
                                $dy = "$DAYS[$dy],$dy";
                                $start = secs($start);
                                $duration = secs($duration);

                                push(@days,"$dy,$start,$duration,$strt_secs,$end_secs");
                        }
                        close(IN);
                }

                if ( -f "${schd}/info" ) {
                        open (IN,"<${schd}/info") or die;
                        while (<IN>) {
                                chomp;
                                ($key,$type) = split(/\s+/,$_);
                                if ( $key eq "SCHED_TYPE" ) {
                                        last;
                                }
                        }
                        close(IN);
                }

                $type = $TYPE[$type];
                my $schd_tmp = $schd;
                $schd_tmp =~ s,.*/,,;
               foreach $clnt (@clients) {
                        foreach $start_stop (@days) {
                                # output comma delimited lines
# orig                          print "$tmp,$clnt,$type,$schd_tmp,$start_stop\n";
                                print "$tmp,$sto,$clnt,$type,$schd_tmp,$start_stop\n";
                        }
               }
                #print "Schedule: $schd\n";
        }

}

sub secs {
        my $hr = '';
        my $min = '';
        my $sec = '';
        my $tm = shift;

        # convert from sec's to hr:min:sec for printout
        if ( $tm > 59 ) {
                my $hr = 0;
                my $sec = $tm % 60;
                my $min = $tm / 60;
                if ( $min > 59 ) {
                  my $tmp = $min % 60;
                  $hr = $min / 60;
                  $min = $tmp;
                }
                $tm = sprintf "%02d:%02d:%02d",$hr,$min,$sec;
        } else {
                $tm = sprintf "%02d:%02d:%02d",0,0,$tm;
        }
        return $tm;
}

#END OF SCRIPT

 

AttachmentSize
nbu_schedule_info_pl.txt 4.42 KB
0
Login to vote
NetbackupXBS's picture

Don,

The script is great.  I am not a perl scriptor and I would like to add a field to your script but I'm having difficulties getting it to work.  In the directory /usr/openv/netbackup/db/class/, for each policy, there is file called includes.  I would like to see the contents of this file in the final output as one field with each line separated by a space so it will not interfere with the CSV output.  Can you include this in your script?

Rob

0
Login to vote
Don Wilder's picture

Rob,

I'll take a look and see what I can do.

Don

0
Login to vote
Don Wilder's picture

Rob,

Not sure this is what you are looking for, but this will put out the includes also...

 

#!/usr/bin/perl -w
#
# Use on Veritas' NetBackup master server
#
# print out schedule information in format for import
# to a spreadsheet.
#

my @DAYS = (
        "Sun",
        "Mon",
        "Tue",
        "Wed",
        "Thu",
        "Fri",
        "Sat",
);

my @TYPE = (
        "FULL",
        "Differential-Incremental",
        "Cumulative-Incremental",
        "User-Backup",
        "User-Archive",
);

# this is the default install dir for netbackup class data
# yes, readdir is more efficient...
my @class = glob("/usr/openv/netbackup/db/class/*");

my $day_secs = 3600 * 24;
# Orig -- print "CLASS,CLIENT,TYPE,SCHEDULE,DAY,DAYN,WINDOWSTART,WINDOWLENGTH,STRT_SECS,END_SECS\n";
#print "POLICY,STORAGEUNIT,CLIENT,TYPE,SCHEDULE,DAY,DAYN,WINDOWSTART,WINDOWLENGTH,STRT_SECS,END_SECS\n";
print "CLIENT,POLICY,STORAGEUNIT,TYPE,SCHEDULE,DAY,DAYN,WINDOWSTART,WINDOWLENGTH,INCLUDES\n";
foreach $cls (@class) {
        my @includes = ();
        my @clients = ();
        my $sto = '';
        my $tmp = $cls;
        $tmp =~ s,.*/,,;

        # get includes list
        if ( -f "${cls}/includes" ) {
                open(IN,"<${cls}/includes") or die;
                while (<IN>) {
                        my ($incl) = split(/^/,$_);
                        push(@includes,$incl);
                }
                close(IN);
        } else {
                push(@includes,"none");
        }

        # get client list
        if ( -f "${cls}/clients" ) {
                open(IN,"<${cls}/clients") or die;
                while (<IN>) {
                        my ($clnt) = split(/ /,$_);
                        push(@clients,$clnt);
                }
                close(IN);
        } else {
                push(@clients,"none");
        }

        # get storage unit
        if ( -f "${cls}/info" ) {
                open(IN,"<${cls}/info") or die;
                while (<IN>) {
                        chomp;
                        ($key,$sto) = split(/\s+/,$_);
                        if ( $key eq "RESIDENCE" ) {
                                last;
                        }
                }
                close(IN);
        }

        my @scheds = glob("${cls}/schedule/*");
        foreach $schd (@scheds) {
                my @days = ();
                my $type = '';

                if ( -f "${schd}/days" ) {
                        open (IN,"<${schd}/days") or die;
                        while (<IN>) {
                                my $strt_secs = 0;
                                my $end_secs = 0;
                                chomp;
                                ($dy,$start,$duration) =
                                        split(/\s+/,$_);
                                next if $duration == 0;

                                $strt_secs = ($dy * $day_secs) + $start;
                                $end_secs = $strt_secs + $duration;
                                $dy = "$DAYS[$dy],$dy";
                                $start = secs($start);
                                $duration = secs($duration);

#                                push(@days,"$dy,$start,$duration,$strt_secs,$end_secs");
                                push(@days,"$dy,$start,$duration");
                        }
                        close(IN);
                }

                if ( -f "${schd}/info" ) {
                        open (IN,"<${schd}/info") or die;
                        while (<IN>) {
                                chomp;
                                ($key,$type) = split(/\s+/,$_);
                                if ( $key eq "SCHED_TYPE" ) {
                                        last;
                                }
                        }
                        close(IN);
                }

                $type = $TYPE[$type];
                my $schd_tmp = $schd;
                $schd_tmp =~ s,.*/,,;
                foreach $clnt (@clients) {
                        foreach $start_stop (@days) {
                                foreach $incl (@includes) {
                                        # output comma delimited lines
        # orig                          print "$tmp,$clnt,$type,$schd_tmp,$start_stop\n";
        #                                print "$tmp,$sto,$clnt,$type,$schd_tmp,$start_stop\n";
                                        print "$clnt,$tmp,$sto,$type,$schd_tmp,$start_stop,$incl\n";
                                }
                        }
                }
                #print "Schedule: $schd\n";
        }

}

sub secs {
        my $hr = '';
        my $min = '';
        my $sec = '';
        my $tm = shift;

        # convert from sec's to hr:min:sec for printout
        if ( $tm > 59 ) {
                my $hr = 0;
                my $sec = $tm % 60;
                my $min = $tm / 60;
                if ( $min > 59 ) {
                  my $tmp = $min % 60;
                  $hr = $min / 60;
                  $min = $tmp;
                }
                $tm = sprintf "%02d:%02d:%02d",$hr,$min,$sec;
        } else {
                $tm = sprintf "%02d:%02d:%02d",0,0,$tm;
        }
        return $tm;
}

#END OF SCRIPT

 

0
Login to vote
NetbackupXBS's picture

Don,

This is very close to what I am looking for.  The include directories are listed as requested.  Is there a way to have multiple directories reported on one line?  For example, when we back up the base file systems out open systems servers, we back up specific directories.  The script above lists each directory on its own line of output like I have pasted below:

chssnbt03p,Open-Media-Servers,nbu_master_sbnm,FULL,Weekly-Full,Mon,1,10:00:00,06:00:00,/
chssnbt03p,Open-Media-Servers,nbu_master_sbnm,FULL,Weekly-Full,Mon,1,10:00:00,06:00:00,/var
chssnbt03p,Open-Media-Servers,nbu_master_sbnm,FULL,Weekly-Full,Mon,1,10:00:00,06:00:00,/opt
chssnbt03p,Open-Media-Servers,nbu_master_sbnm,FULL,Weekly-Full,Mon,1,10:00:00,06:00:00,/boot
chssnbt03p,Open-Media-Servers,nbu_master_sbnm,FULL,Weekly-Full,Mon,1,10:00:00,06:00:00,/usr/openv
 

Can the script produce a one line output for all of the directories like I created below?

chssnbt03p,Open-Media-Servers,nbu_master_sbnm,FULL,Weekly-Full,Mon,1,10:00:00,06:00:00,/ /var /opt /boot /use/openv

If it is possible, can the serarator between directories be something other then a comma so when it is ported into an excel spreadsheet, all of the directories will be in one cell instean of multiple cells?  If it isn't possible,

Rob

0
Login to vote
Don Wilder's picture

Been playing with it... what you are looking for will take some work to create that kind of output. Take a look at this version... you may be able to create a wrapper to join lines together with sed...

 

#!/usr/bin/perl -w
#
# Use on Veritas' NetBackup master server
#
# print out schedule information in format for import
# to a spreadsheet.
#

my @DAYS = (
        "Sun",
        "Mon",
        "Tue",
        "Wed",
        "Thu",
        "Fri",
        "Sat",
);

my @TYPE = (
        "FULL",
        "Differential-Incremental",
        "Cumulative-Incremental",
        "User-Backup",
        "User-Archive",
);

# this is the default install dir for netbackup class data
# yes, readdir is more efficient...
my @class = glob("/usr/openv/netbackup/db/class/*");

my $day_secs = 3600 * 24;
print "CLIENT,POLICY,STORAGEUNIT,TYPE,SCHEDULE,DAY,DAYN,WINDOWSTART,WINDOWLENGTH,INCLUDES\n";
foreach $cls (@class) {
        my @includes = ();
        my @clients = ();
        my $sto = '';
        my $tmp = $cls;
        $tmp =~ s,.*/,,;

        # get includes list
        if ( -f "${cls}/includes" ) {
                open(IN,"<${cls}/includes") or die;
                while (<IN>) {
                        my ($incl) = split(/^/m,$_,1);
                        push(@includes,$incl);
                }
                close(IN);
        } else {
                push(@includes,"none");
        }

        # get client list
        if ( -f "${cls}/clients" ) {
                open(IN,"<${cls}/clients") or die;
                while (<IN>) {
                        my ($clnt) = split(/ /,$_);
                        push(@clients,$clnt);
                }
                close(IN);
        } else {
                push(@clients,"none");
        }

        # get storage unit
        if ( -f "${cls}/info" ) {
                open(IN,"<${cls}/info") or die;
                while (<IN>) {
                        chomp;
                        ($key,$sto) = split(/\s+/,$_);
                        if ( $key eq "RESIDENCE" ) {
                                last;
                        }
                }
                close(IN);
        }

        my @scheds = glob("${cls}/schedule/*");
        foreach $schd (@scheds) {
                my @days = ();
                my $type = '';

                if ( -f "${schd}/days" ) {
                        open (IN,"<${schd}/days") or die;
                        while (<IN>) {
                                my $strt_secs = 0;
                                my $end_secs = 0;
                                chomp;
                                ($dy,$start,$duration) =
                                        split(/\s+/,$_);
                                next if $duration == 0;

                                $strt_secs = ($dy * $day_secs) + $start;
                                $end_secs = $strt_secs + $duration;
                                $dy = "$DAYS[$dy],$dy";
                                $start = secs($start);
                                $duration = secs($duration);

                                push(@days,"$dy,$start,$duration");
                        }
                        close(IN);
                }

                if ( -f "${schd}/info" ) {
                        open (IN,"<${schd}/info") or die;
                        while (<IN>) {
                                chomp;
                                ($key,$type) = split(/\s+/,$_);
                                if ( $key eq "SCHED_TYPE" ) {
                                        last;
                                }
                        }
                        close(IN);
                }

                $type = $TYPE[$type];
                my $schd_tmp = $schd;
                $schd_tmp =~ s,.*/,,;
                foreach $clnt (@clients) {
                        foreach $start_stop (@days) {
                                # output comma delimited lines
                                print "$clnt,$tmp,$sto,$type,$schd_tmp,$start_stop,";
                                foreach $incl (@includes) {
                                        print "$incl ";
                                }
                                print "\n";
                        }
                }
                #print "Schedule: $schd\n";
        }

}

sub secs {
        my $hr = '';
        my $min = '';
        my $sec = '';
        my $tm = shift;

        # convert from sec's to hr:min:sec for printout
        if ( $tm > 59 ) {
                my $hr = 0;
                my $sec = $tm % 60;
                my $min = $tm / 60;
                if ( $min > 59 ) {
                  my $tmp = $min % 60;
                  $hr = $min / 60;
                  $min = $tmp;
                }
                $tm = sprintf "%02d:%02d:%02d",$hr,$min,$sec;
        } else {
                $tm = sprintf "%02d:%02d:%02d",0,0,$tm;
        }
        return $tm;
}

#END OF SCRIPT
 

0
Login to vote
Don Wilder's picture

This output will create one line for the schedule info and any extra "includes" will be prefaced with a "^ " to allow for a search and replace via sed to join the affected lines.

0
Login to vote
NetbackupXBS's picture

Don,

Thanks.  I'll work with it to see what I can come up with.

 

0
Login to vote
gmadanmohn82@gmail.com's picture

Don

we need  same perl script  windows master server.

We need  same scpit  unix master server but  i want run  remote media server

can  help me ..... 

 

0
Login to vote
Don Wilder's picture

The beauty of perl... it will work in either environment. It must be run on the master server.

The only change you should have to make is the "my @class = glob("/usr/openv/netbackup/db/class/*");" to point to where ever you installed the NetBackup Software at.

0
Login to vote
gmadanmohn82@gmail.com's picture

Don,

 

We faceing  below error

Unrecognized escape \V passed through at D:\VERITAS\TEST\copy.pl line 29.
Unrecognized escape \d passed through at D:\VERITAS\TEST\copy.pl line 29.
Missing braces on \N{} at D:\VERITAS\TEST\copy.pl line 29, within string
BEGIN not safe after errors--compilation aborted at D:\VERITAS\TEST\copy.pl line 29.

D:\perl\bin>

0
Login to vote
Don Wilder's picture

Please post what you changed the line 29 to.

0
Login to vote
gmadanmohn82@gmail.com's picture

my @class = glob("D:\veritas\netbackup\db\class\*");

0
Login to vote
Don Wilder's picture

Ok,

I think what you really want there is:

my @class = glob("/D/veritas/netbackup/db/class/*");

Give that a try... I can't test it as I don't have a windows master to test it on.

0
Login to vote
Don Wilder's picture

Got a working version... Use this as your line 29...

my @class = glob("D:\\veritas\\netbackup\\db\\class\\*");
 
 
0
Login to vote
gmadanmohn82@gmail.com's picture

Thanks Don

it's working fine...

but  in report showing  client name showing  None

 

0
Login to vote
Don Wilder's picture

hmm... what kinds of policies are you running? If you are running VMWARE with a query for the client selector the name of the client is not contained in this tree and thus should show as none.

Another thing you can check is what flavor of perl you have installed on the windows. I tested with "Strawberry" and it seems to work on my system with a copy of the folder off my UNIX master.

0
Login to vote