Networker

[Networker] Perl script for loading tapes

2002-08-29 10:19:36
Subject: [Networker] Perl script for loading tapes
From: Dale Mayes <dmayes AT KIMBALL DOT COM>
To: NETWORKER AT LISTMAIL.TEMPLE DOT EDU
Date: Thu, 29 Aug 2002 09:22:32 -0500
OK...here's my version...alibi a little more complex *grin*.

Please forgive my coding as I'm a "new" Perl programmer (just went through a
class before writing this script)...AND execute at your own risk...even
though I've tested and have it running in my production environment...please
test and don't yell at me too much if there are issues.

As you'll be able to see...I've got both HP-UX and NT environments so this
script attempts to handle both.
You'll need to change the "she-bang" for your particular landscape.

I've got STK libraries (in this particular case either 9730 or 9714).

Since I've been working with a jukebox that only has 1 I/E CAP port, this
will have to be modified to handle a multi-slot CAP.  It's in my "future"
enhancements to-do list...as soon as I get "a round to-it"...since I also
have 9710's in my environment.

If you make improvements...find bugs...etc... I'd really appreciate any
updates.

I know others out there must have scripts that all of us could use...please
share!!!!

HTH

Dale

#! ./perl
#
# Script Name(s): load_NT.pl
# Written By:     Dale Mayes
# Creation Date:  08/15/2002
#
# Purpose: Provide a means to load tapes into the jukebox. This script
checks
# the CAP and prompts to insert a tape if CAP is empty. The script will
continue
# to prompt for tapes until either all tapes are loaded (and operator enters
X)
# or the jukebox is full.
#
# Usage: load_NT.pl
#
# Modifications:
#
#
#
#
#
#
# Include modules
#
use Mail::Sendmail;
use Config;
use IPC::Open2;
use Sys::Hostname;
#
#
# Init_Vars subroutine initializes variables for later use
#
sub Init_Vars {
  #
  # force autoflush of files
  #
  $|=1;
  #
  # determine hostname
  #
  $HOSTNAME=hostname();
  #
  # determine type of operating system
  #
  $OSNAME=$Config{'osname'};
  #
  # NetWorker server
  #
  $NSR_SERVER="sr74";
  #
  # os specific variables
  #
  if ($OSNAME eq "hpux") {
    #
    # NetWorker binary library and concatenate some commands for later usage
    #
    $NW_LIB='/opt/networker/bin/';
    $NSRMM="$NW_LIB" . "nsrmm -s $NSR_SERVER";
    $NSRJB="$NW_LIB" . "nsrjb -s $NSR_SERVER";
    $MMINFO="$NW_LIB" . "mminfo -s $NSR_SERVER";
    $MMLOCATE="$NW_LIB" . "mmlocate -s $NSR_SERVER";
    $NSRADMIN="$NW_LIB" . "nsradmin -s $NSR_SERVER -i -";
    #
    # set bit-bucket to /dev/null
    #
    $BIT_BUCKET='/dev/null';
    }
  elsif ($OSNAME eq "MSWin32") {
    #
    # NetWorker commands for later usage
    #
    $NW_LIB="C:\\Progra~1\\nsr\\bin\\";
    $NSRMM="$NW_LIB" . "nsrmm -s $NSR_SERVER";
    $NSRJB="$NW_LIB" . "nsrjb -s $NSR_SERVER";
    $MMINFO="$NW_LIB" . "mminfo -s $NSR_SERVER";
    $MMLOCATE="$NW_LIB" . "mmlocate -s $NSR_SERVER";
    $NSRADMIN="$NW_LIB" . "nsradmin -s $NSR_SERVER -i -";
    #
    # set bit-bucket to nul
    #
    $BIT_BUCKET='nul';
    }
  else {
    print "ERROR: Unrecognized operating system ==>", $OSNAME, "<== script
exiting\n";
    exit;
    }
  #
  # utilize nsradmin to determine configuration
  #
  #     first the jukebox...
  #
  print "--> Determining jukebox name...\n";
  open2(*README, *WRITEME, $NSRADMIN);
  print WRITEME "show name:\n print type: NSR jukebox\n quit\n";
  close(WRITEME);
  while(<README>) {
    chomp;
    s/^\t* *//;
    s/^ *//;
    s/:/ /;
    s/;/ /;
    s/\"/ /g;
    if (/.*$HOSTNAME.*/) {
      ($word1, $JUKEBOX, $word3) = split / +/, $_, 3;
      }
    }
  close(README);
  #
  #     then the jukebox details (control port, available and cleaning
slots)...
  #
  print "--> Determining jukebox details...\n";
  open2(*README, *WRITEME, $NSRADMIN);
  print WRITEME "show available slots;cleaning slots;control port:\n print
type: NSR jukebox;name: \"$JUKEBOX\"\n quit\n";
  close(WRITEME);
  while(<README>) {
    chomp;
    s/^\t* *//;
    s/^ *//;
    s/:/ /g;
    s/;/ /;
    s/\"/ /g;
    if (/^control port.*/) {
      ($word1, $word2, $word3, $CONTROL_PORT, $rest) = split / +/, $_, 5;
      }
    elsif (/^available slots.*/) {
      ($word1, $word2, $AVAILABLE_SLOTS, $rest) = split / +/, $_, 4;
      ($FIRST_AVAILABLE_SLOT, $LAST_AVAILABLE_SLOT) = split /-+/,
$AVAILABLE_SLOTS, 2;
      }
    elsif (/^cleaning slots.*/) {
      ($word1, $word2, $CLEANING_SLOTS, $rest) = split / +/, $_, 4;
      }
    }
  close(README);
  #
  #     now the devices...
  #
  print "--> Determining devices...\n";
  $devno=1;
  open2(*README, *WRITEME, $NSRADMIN);
  print WRITEME "show name:\n print type: NSR device\n quit\n";
  close(WRITEME);
  while(<README>) {
    chomp;
    s/^\t* *//;
    s/^ *//;
    s/:/ /;
    s/;/ /;
    s/\"/ /g;
    if (/.*$HOSTNAME.*/) {
      ($word1, $device, $word3) = split / +/, $_, 3;
      $DEVICE{$devno}=$device;
      $NUMBER_DEVICES=$devno;
      $devno++;
      }
    }
  close(README);
  #
  # finish with os specific variables...now that we know the control_port
  #
  if ($OSNAME eq "hpux") {
    #
    # Finish concatenating commands for later usage
    #
    $SJIRELEM="$NW_LIB" . "sjirelem $CONTROL_PORT";
    $SJIRDTAG="$NW_LIB" . "sjirdtag $CONTROL_PORT";
    $SJIRDP="$NW_LIB" . "sjirdp $CONTROL_PORT";
    }
  elsif ($OSNAME eq "MSWin32") {
    #
    # Finish concatenating commands for later usage
    #
    $SJIRELEM="$NW_LIB" . "sjirelem $CONTROL_PORT";
    $SJIRDTAG="$NW_LIB" . "sjirdtag $CONTROL_PORT";
    $SJIRDP="$NW_LIB" . "sjirdp $CONTROL_PORT";
    }
  else {
    print "ERROR: Unrecognized operating system ==>", $OSNAME, "<== script
exiting\n";
    exit;
    }
  #
  # determine how big the CAP is...
  #
  print "--> Determining CAP size...\n";
  open(SS, "$SJIRDP |") or die "Can not run sjirdp program \n";
  while(<SS>) {
    chomp;
    s/^\t* *//;
    s/^ *//;
    if (/.*IMPORT\/EXPORT.*/) {
      ($word1, $word2, $IESLOTS, $rest) = split / +/, $_, 4;
      }
    }
  close(SS);
  #
  # userids that should be notified of issues
  #
  @NOTIFY=('dmayes AT kimball DOT com');
}

#
# cannot_inventory routine mails a message indicating that it was unable to
#   inventory a slot in the jukebox
#
sub Cannot_Inventory {
  %mail = ( To => "@NOTIFY",
          From => 'root AT kimball DOT com',
       Subject => "Unable to inventory $slotpos in $JUKEBOX",
       Message => "The slot $slotpos could not be inventoried in jukebox
$JUKEBOX"
          );
  sendmail(%mail) or die $Mail::Sendmail::error;
}

#
# cannot_deposit routine mails a message indicating that it was unable to
#   deposit a particular tape in the jukebox
#
sub Cannot_Deposit {
  %mail = ( To => "@NOTIFY",
          From => 'root AT kimball DOT com',
       Subject => "Unable to deposit $barcode in slot $slotpos in $JUKEBOX",
       Message => "Tape $barcode could not be deposited."
          );
  sendmail(%mail) or die $Mail::Sendmail::error;
}

#
# IEPort_Status subroutine
#
sub IEPort_Status {
  print "--> Checking CAP status...\n";
  $readnextline="NO";
  $CAPISFULL="NO";
  open(SS, "$SJIRDTAG |") or die "Can not run sjirelem program \n";
  while(<SS>) {
    chomp;
    s/^ *//;
    s/</ /;
    if (/.*Element Type IMPORT\/EXPORT.*/) {
      $readnextline="FIRST";
      }
    elsif ($readnextline eq "FIRST") {
      $readnextline="SECOND";
      ($word1, $word2, $word3, $word4, $word5, $word6, $status, $word8) =
split / +/, $_, 9;
      $CAPISFULL="YES" unless ($status eq "full=0");
      }
    elsif ($readnextline eq "SECOND") {
      $readnextline="DONE";
      ($word1, $word2, $barcode, $word3) = split / +/, $_, 5;
      print "--> Found tape $barcode to deposit\n";
      }
    }
  close(SS);
}

#
# Jukebox_Contents subroutine
#
sub Jukebox_Contents {
  open(MM, "$NSRJB -j $JUKEBOX |") or die "Can not run nsrjb program \n";
  while(<MM>) {
    chomp;
    s/^ *//;
    s/:/ /g;
    s/\(//g;
    s/\)//g;
    if (/^[0-9]+/) {
      ($slot, $volume, $rest) = split / +/, $_, 3;
      next unless ($volume ne "");
      if ($volume eq "Cleaning") {
        ($word1, $word2, $word3, $word4, $volume, $rest) = split / +/,
$rest, 6;
        }
      $SLOT{$slot} = $volume;
      }
    elsif (/^drive /) {
      ($word1, $drivenum, $drivename, $word2, $storslot, $volser, $rest) =
split / +/, $_, 7;
      $DRIVE{$drivenum} = $volser unless ($storslot eq "");
      }
    }
  close(MM);
}

#
# determine_empty_slot subroutine
#
sub Determine_Empty_Slot {
  $slotpos=1;
  while ($SLOT{$slotpos} ne "") {
    if ($slotpos < $LAST_AVAILABLE_SLOT) {
      $slotpos++;
      }
    else {
      print "--> ERROR: no empty slots were found in $JUKEBOX ...
exiting\n";
      exit;
      }
    }
}

#
# Load_Volumes subroutine
#
sub Load_Volumes {
  until ($FINISHED eq "YES") {
    #
    # check the status of the IE Port...
    #
    IEPort_Status;
    until ($CAPISFULL eq "YES") {
      print "--> ERROR:\n";
      print "--> ERROR: The Import-Export CAP is empty...please load a
tape\n";
      print "--> ERROR:\n";
      $resp="N";
      until ($resp eq "Y") {
        print '--> Enter "Y" when CAP is ready: ';
        chomp ($resp = <STDIN>);
        $resp = uc($resp);
        }
      IEPort_Status;
      }
    #
    # determine the next empty slot...
    #
    print "--> Finding an empty slot in jukebox...\n";
    Determine_Empty_Slot;
    #
    # depositing the volume in the jukebox...
    #
    print "--> Depositing tape $barcode in slot $slotpos in jukebox\n";
    open(MM, "$NSRJB -j $JUKEBOX -d -P 1 -S $slotpos |") or die
Cannot_Deposit ($barcode, $slotpos);
      while (<MM>) {}
    close(MM);
    $SLOT{$slotpos}=$barcode;
    #
    # inventory the slot...
    #
    print "--> Checking if tape $barcode is a valid NetWorker volume...";
    open(SS, "$MMLOCATE -n $barcode 2>&1 1>$BIT_BUCKET |") or die "Can not
run mmlocate program to verify volume \n";
      while (<SS>) {
        chomp;
        $ERROR = $_;
        }
    close(SS);
    if ($ERROR eq "") {
      print "It is...inventoring slot $slotpos in $JUKEBOX jukebox...\n";
      open(MM, "$NSRJB -IEj $JUKEBOX -S $slotpos |") or die Cannot_Inventory
($slotpos);
        while (<MM>) {}
      close(MM);
      }
    else {
      print "It is not...skipping inventory...\n";
      }
    #
    # continue or stop...
    #
    print '--> Enter "C" to continue loading tapes or "X" to exit: ';
    chomp ($ans = <STDIN>);
    $ans = uc($ans);
    $FINISHED="YES" unless ($ans eq "C");
    }
}

#
# MAIN
#

$script_name=$0;
$script_name=~ s-.*/-- ;
print
"+-----------------------------------------------------------------+\n";
print "Running script: $script_name\n";
printf("Local date and time: %04d-%02d-%02d %02d:%02d:%02d\n", sub
{($_[5]+1900, $_[4]+1, $_[3], $_[2], $_[1], $_[0])}->(localtime));
print
"+-----------------------------------------------------------------+\n";

#
# Initialize variables
#
print "Initializing variables\n";
print
"+-----------------------------------------------------------------+\n";
&Init_Vars;
print "--> Hostname        : $HOSTNAME \n";
print "--> Operating system: $OSNAME \n";
print "--> Jukebox name    : $JUKEBOX \n";
print "--> Control Port    : $CONTROL_PORT \n";
print "--> Available slots : $AVAILABLE_SLOTS \n";
print "--> Cleaning slots  : $CLEANING_SLOTS \n";
print "--> IE slots        : $IESLOTS \n";
foreach $dd (keys %DEVICE) {
  print "--> Device $dd        : $DEVICE{$dd} \n";
  }

#
# Determine jukebox contents
#
print "Determining jukebox contents\n";
print
"+-----------------------------------------------------------------+\n";
&Jukebox_Contents;

#
# Unload the volumes
#
print "Loading volumes\n";
print
"+-----------------------------------------------------------------+\n";
$FINISHED="NO";
&Load_Volumes;

--
Note: To sign off this list, send a "signoff" command via email
to listserv AT listmail.temple DOT edu or visit the list's Web site at
http://listmail.temple.edu/archives/networker.html where you can
also view and post messages to the list.
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

<Prev in Thread] Current Thread [Next in Thread>
  • [Networker] Perl script for loading tapes, Dale Mayes <=