[BACK]Return to update_trango.pl CVS log [TXT][DIR] Up to [local] / trango / Net-Telnet-Trango / scripts

Diff for /trango/Net-Telnet-Trango/scripts/update_trango.pl between version 1.30 and 1.31

version 1.30, 2007/02/06 23:00:31 version 1.31, 2007/02/06 23:15:53
Line 1 
Line 1 
 #!/usr/bin/perl  #!/usr/bin/perl
 # $RedRiver: update_trango.pl,v 1.29 2007/02/05 16:37:20 mike Exp $  # $RedRiver: update_trango.pl,v 1.30 2007/02/06 23:00:31 andrew Exp $
 ########################################################################  ########################################################################
 # update_trango.pl *** Updates trango hosts with a new firmware  # update_trango.pl *** Updates trango hosts with a new firmware
 #  #
Line 31 
Line 31 
   
 my $global_tries = $max_tries * 2;  my $global_tries = $max_tries * 2;
 while ($global_tries > 0) {  while ($global_tries > 0) {
   $global_tries--;      $global_tries--;
   my $processed = 0;      my $processed = 0;
   
       foreach my $host (@{ $hosts }) {
   
 foreach my $host (@{ $hosts }) {          if (! exists $host->{retry}) {
               $host->{tries} = 0;
               $host->{retry} = 1;
           }
   
   if (! exists $host->{retry}) {          if ($host->{tries} >= $max_tries) {
     $host->{tries} = 0;              $host->{retry} = 0;
     $host->{retry} = 1;          }
   }  
   
   if ($host->{tries} >= $max_tries) {          if ($host->{retry} <= 0) {
     $host->{retry} = 0;              next;
   }          }
   
   if ($host->{retry} <= 0) {          $host->{tries}++;
     next;          $processed++;
   }  
   
   $host->{tries}++;          $l->sp("");
   $processed++;          $l->sp("Checking: $host->{name} (try $host->{tries})");
           my $needs_reboot = 0;
   
   $l->sp("");          ## Connect and login.
   $l->sp("Checking: $host->{name} (try $host->{tries})");          my $t = new Net::Telnet::Trango (
   my $needs_reboot = 0;              Timeout => 5,
               Errmode => 'return',
           ) or die "Couldn't make new connection: $!";
           $l->p("Connecting to $host->{name}");
           unless ( $t->open($host->{name}) ) {
               $l->sp("Error connecting: $!");
               next;
           }
   
   ## Connect and login.          my $password = $host->{Telnet_Password} || $conf->{general}->{password};
   my $t = new Net::Telnet::Trango (  
     Timeout => 5,  
     Errmode => 'return',  
   ) or die "Couldn't make new connection: $!";  
   $l->p("Connecting to $host->{name}");  
   unless ( $t->open($host->{name}) ) {  
     $l->sp("Error connecting: $!");  
     next;  
   }  
   
   my $password = $host->{Telnet_Password} || $conf->{general}->{password};          $l->p("Logging in");
           $t->login($password);
           unless ($t->logged_in) {
               $l->p('Failed!');
               $t->close;
               next;
           }
   
   $l->p("Logging in");          $l->sp("Getting sudb");
   $t->login($password);          my $sudb = $t->sudb_view;
   unless ($t->logged_in) {          if ($sudb) {
     $l->p('Failed!');              foreach my $su (@{ $sudb }) {
     $t->close;                  $l->p("Getting su info $su->{suid}");
     next;                  my $su_info = $t->su_info( $su->{suid} );
   }                  if ($su_info->{ip}) {
                       if (grep { $_->{name} eq $su_info->{'ip'} } @{ $hosts }) {
   $l->sp("Getting sudb");                          $l->p("Already have $su_info->{ip}");
   my $sudb = $t->sudb_view;                          next;
   if ($sudb) {                      }
     foreach my $su (@{ $sudb }) {                      $l->sp("Adding host $su_info->{ip}");
       $l->p("Getting su info $su->{suid}");                      my $new_host = {
       my $su_info = $t->su_info( $su->{suid} );                          password => $host->{password},
       if ($su_info->{ip}) {                          name     => $su_info->{ip},
         if (grep { $_->{name} eq $su_info->{'ip'} } @{ $hosts }) {                          remarks  => $su_info->{remarks},
           $l->p("Already have $su_info->{ip}");                      };
           next;                      push @{ $hosts }, $new_host;
                   } else {
                       $l->sp("Couldn't get su info for $su->{suid}");
                       $l->sp("ERR: " . $t->last_error);
                   }
               }
         }          }
         $l->sp("Adding host $su_info->{ip}");  
         my $new_host = {  
           password => $host->{password},  
           name     => $su_info->{ip},  
           remarks  => $su_info->{remarks},  
         };  
         push @{ $hosts }, $new_host;  
       } else {  
         $l->sp("Couldn't get su info for $su->{suid}");  
         $l->sp("ERR: " . $t->last_error);  
       }  
     }  
   }  
   
   foreach my $firmware_type ('Firmware', 'FPGA') {          foreach my $firmware_type ('Firmware', 'FPGA') {
   
     if (! exists $conf->{$firmware_type}) {              if (! exists $conf->{$firmware_type}) {
       $l->s("No configs for '$firmware_type'");                  $l->s("No configs for '$firmware_type'");
       $t->close;                  next;
       next;              }
     }  
   
     my $host_type = $t->host_type;              my $host_type = $t->host_type;
     if ($firmware_type eq 'FPGA') {              if ($firmware_type eq 'FPGA') {
       $host_type =~ s/\s.*$//;                  $host_type =~ s/\s.*$//;
     }              }
   
     if (! exists $conf->{$firmware_type}->{$host_type}) {              if (! exists $conf->{$firmware_type}->{$host_type}) {
       $l->sp("No '$firmware_type' config for type $host_type");                  $l->sp("No '$firmware_type' config for type $host_type");
       $t->close;                  next;
       next;              }
     }  
   
     if ($firmware_type eq 'Firmware' &&              if ($firmware_type eq 'Firmware' &&
       $t->firmware_version eq                  $t->firmware_version eq
       $conf->{$firmware_type}->{$host_type}->{ver}                  $conf->{$firmware_type}->{$host_type}->{ver}
     ) {              ) {
       $l->sp("Firmware already up to date");                  $l->sp("Firmware already up to date");
       next;                  next;
     }              }
   
     if (! $t->logged_in) {              if (! $t->logged_in) {
       $l->p("Logging in");                  $l->p("Logging in");
       $t->login($password);                  $t->login($password);
       unless ($t->logged_in) {                  unless ($t->logged_in) {
         $l->p('Failed!');                      $l->p('Failed!');
         $t->close;                      $t->close;
         next;                      last;
       }                  }
     }              }
   
     foreach my $k (keys %{ $conf->{general} }) {              foreach my $k (keys %{ $conf->{general} }) {
       $conf->{$firmware_type}->{$host_type}->{$k} ||= $conf->{general}->{$k};                  $conf->{$firmware_type}->{$host_type}->{$k}
     }                    ||= $conf->{general}->{$k};
     $conf->{$firmware_type}->{$host_type}->{firmware_type} ||= $firmware_type;              }
     $conf->{$firmware_type}->{$host_type}->{type} = $host_type;              $conf->{$firmware_type}->{$host_type}->{firmware_type}
                 ||= $firmware_type;
               $conf->{$firmware_type}->{$host_type}->{type} = $host_type;
   
     $l->sp("$host_type $firmware_type");              $l->sp("$host_type $firmware_type");
     ## Send commands              ## Send commands
     my $rc = upload($t, $conf->{$firmware_type}->{$host_type});              my $rc = upload($t, $conf->{$firmware_type}->{$host_type});
     if ($rc) {              if ($rc) {
       $l->sp("Successfull!");                  $l->sp("Successfull!");
       $host->{retry}--;                  $host->{retry}--;
       $needs_reboot = 1;                  $needs_reboot = 1;
     } elsif (defined $rc) {              } elsif (defined $rc) {
       $l->sp("Already up to date");                  $l->sp("Already up to date");
       $host->{retry}--;                  $host->{retry}--;
     } else {              } else {
       $l->sp("Failed");                  $l->sp("Failed");
       $t->bye;                  $t->bye;
       next;                  next;
               }
   
           }
   
           if ($needs_reboot) {
               $l->sp("Rebooting $host->{name}");
               $t->reboot;
           } else {
               $l->sp("Bye $host->{name}");
               $t->bye();
           }
     }      }
   
   }  
   
   if ($needs_reboot) {      if (! $processed) {
     $l->sp("Rebooting $host->{name}");          $l->sp("");
     $t->reboot;          $l->sp("Finished.  No more hosts.");
   } else {          last;
     $l->sp("Bye $host->{name}");      }
     $t->bye();  
   }  
 }  }
   
   if (! $processed) {  
     $l->sp("");  
     $l->sp("Finished.  No more hosts.");  
     last;  
   }  
 }  
   
 sub upload  sub upload
 {  {
   my $t    = shift;      my $t    = shift;
   my $conf = shift;      my $conf = shift;
   
   my $file = $conf->{firmware_path} . '/' . $conf->{file_name};      my $file = $conf->{firmware_path} . '/' . $conf->{file_name};
   
   my $fw_type = $conf->{firmware_type};      my $fw_type = $conf->{firmware_type};
   
   my $ver = $t->ver;      my $ver = $t->ver;
   
   if (! (      if (! (
     $ver->{$fw_type . ' Version'}  &&              $ver->{$fw_type . ' Version'}  &&
     $ver->{$fw_type . ' Checksum'}              $ver->{$fw_type . ' Checksum'}
   )) {          )) {
     $l->sp("Error getting current version numbers");          $l->sp("Error getting current version numbers");
     return;          return;
   }      }
   
   if (      if (
     $ver->{$fw_type . ' Version'}  eq $conf->{'ver'} &&          $ver->{$fw_type . ' Version'}  eq $conf->{'ver'} &&
     $ver->{$fw_type . ' Checksum'} eq $conf->{'cksum'}          $ver->{$fw_type . ' Checksum'} eq $conf->{'cksum'}
   ) {      ) {
     return 0;          return 0;
   }      }
   
   $l->sp("Updating $fw_type");      $l->sp("Updating $fw_type");
   $l->sp("Config information:");      $l->sp("Config information:");
   $l->sp("  Hardware Type: $conf->{'type'}");      $l->sp("  Hardware Type: $conf->{'type'}");
   $l->sp("  File Name:     $conf->{'file_name'}");      $l->sp("  File Name:     $conf->{'file_name'}");
   $l->sp("  File Size:     $conf->{'file_size'}");      $l->sp("  File Size:     $conf->{'file_size'}");
   $l->sp("  File Checksum: $conf->{'file_cksum'}");      $l->sp("  File Checksum: $conf->{'file_cksum'}");
   $l->sp("  Conf Version:  $conf->{'ver'}");      $l->sp("  Conf Version:  $conf->{'ver'}");
   $l->sp("  Cur  Version:  $ver->{$fw_type . ' Version'}");      $l->sp("  Cur  Version:  $ver->{$fw_type . ' Version'}");
   $l->sp("  Conf Checksum: $conf->{'cksum'}");      $l->sp("  Conf Checksum: $conf->{'cksum'}");
   $l->sp("  Cur  Checksum: $ver->{$fw_type . ' Checksum'}");      $l->sp("  Cur  Checksum: $ver->{$fw_type . ' Checksum'}");
   
   my $try = 0;      my $try = 0;
   while (1) {      while (1) {
     if ($try >= $max_tries) {          if ($try >= $max_tries) {
       $l->sp("Couldn't update in $max_tries tries!");              $l->sp("Couldn't update in $max_tries tries!");
       return;              return;
     }          }
     $try++;          $try++;
   
     $l->p("Enabling TFTPd");          $l->p("Enabling TFTPd");
     unless ($t->enable_tftpd) {          unless ($t->enable_tftpd) {
       $l->sp("Couldn't enable tftpd");              $l->sp("Couldn't enable tftpd");
       next;              next;
     }          }
   
     $l->p("Uploading file ($conf->{file_name})");          $l->p("Uploading file ($conf->{file_name})");
     # use tftp to push the file up          # use tftp to push the file up
     my $tftp = Net::TFTP->new($t->Host, Mode => 'octet');          my $tftp = Net::TFTP->new($t->Host, Mode => 'octet');
   
     unless ($tftp->put($file, $file)) {          unless ($tftp->put($file, $file)) {
       $l->sp("Error uploading: " . $tftp->error);              $l->sp("Error uploading: " . $tftp->error);
       next;              next;
     }          }
   
     $l->p("Checking upload ($conf->{'file_cksum'})");          $l->p("Checking upload ($conf->{'file_cksum'})");
     my $results = $t->tftpd;          my $results = $t->tftpd;
     # check the 'File Length' against ???          # check the 'File Length' against ???
     if (! (          if (! (
       $results->{'File Checksum'} &&                  $results->{'File Checksum'} &&
       $results->{'File Length'}   &&                  $results->{'File Length'}   &&
       $results->{'File Name'}                  $results->{'File Name'}
     )) {              )) {
       $l->sp("Unable to get results of upload");              $l->sp("Unable to get results of upload");
       next;              next;
     }          }
     if ( $results->{'File Checksum'} ne $conf->{'file_cksum'}) {          if ( $results->{'File Checksum'} ne $conf->{'file_cksum'}) {
       $l->sp(              $l->sp(
         "File checksum (" . $results->{'File Checksum'} .                  "File checksum (" . $results->{'File Checksum'} .
         ") does not match config file (" . $conf->{'file_cksum'} . ")!"                  ") does not match config file (" . $conf->{'file_cksum'} . ")!"
       );              );
       next;              next;
     }          }
     $l->p("File checksum matches . . . ");          $l->p("File checksum matches . . . ");
   
     if ($results->{'File Length'}   !~ /^$conf->{'file_size'} bytes/) {          if ($results->{'File Length'}   !~ /^$conf->{'file_size'} bytes/) {
       $l->sp(              $l->sp(
         "File length (" . $results->{'File Length'} .                  "File length (" . $results->{'File Length'} .
         ") does not match config file (" . $conf->{'file_size'} . " bytes)!"                  ") does not match config file (" . $conf->{'file_size'} . " bytes)!"
       );              );
       next;              next;
     }          }
     $l->p("File length matches . . . ");          $l->p("File length matches . . . ");
   
     if ( uc($results->{'File Name'}) ne uc($file) ) {          if ( uc($results->{'File Name'}) ne uc($file) ) {
       $l->sp(              $l->sp(
         "File name (" . $results->{'File Name'} .                  "File name (" . $results->{'File Name'} .
         ") does not match config file (" . $file . ")!"                  ") does not match config file (" . $file . ")!"
       );              );
       next;              next;
     }          }
     $l->p("File name matches . . . ");          $l->p("File name matches . . . ");
   
     my $image_type = 'mainimage';          my $image_type = 'mainimage';
     if ($fw_type eq 'FPGA') {          if ($fw_type eq 'FPGA') {
       $image_type = 'fpgaimage';              $image_type = 'fpgaimage';
     }          }
     $l->p("Updating $image_type (new checksum '$conf->{'cksum'}')");          $l->p("Updating $image_type (new checksum '$conf->{'cksum'}')");
     unless ($results = $t->updateflash(          unless ($results = $t->updateflash(
       args => $image_type . ' ' . $ver->{$fw_type . ' Checksum'} .                  args => $image_type . ' ' . $ver->{$fw_type . ' Checksum'} .
               ' '          . $conf->{'cksum'},                  ' '          . $conf->{'cksum'},
       Timeout => 90,                  Timeout => 90,
     ) ) {              ) ) {
       $l->sp("Couldn't update flash: $!");              $l->sp("Couldn't update flash: $!");
       next;              next;
     }          }
   
     unless (          unless (
       defined $results->{'Checksum'} &&              defined $results->{'Checksum'} &&
       $results->{'Checksum'} eq $conf->{'cksum'}              $results->{'Checksum'} eq $conf->{'cksum'}
     ) {          ) {
       $l->sp("Saved checksum " . $results->{'Checksum'} . " does not match config file " .  $conf->{'cksum'} . "!");              $l->sp("Saved checksum " . $results->{'Checksum'} . " does not match config file " .  $conf->{'cksum'} . "!");
       next;              next;
     }          }
   
     $l->p("$fw_type saved checksum matches . . . ");          $l->p("$fw_type saved checksum matches . . . ");
   
     return 1;          return 1;
   }      }
 }  }
   
 sub parse_hosts  sub parse_hosts
Line 339 
Line 338 
 use constant LOG_SAVE  =>  64;  use constant LOG_SAVE  =>  64;
   
 DESTROY {  DESTROY {
   my $self = shift;      my $self = shift;
   if ($self->{'MYLOG'}) {      if ($self->{'MYLOG'}) {
     $self->p("Closing log ($self->{'log_path'}/$self->{'log_file'})");          $self->p("Closing log ($self->{'log_path'}/$self->{'log_file'})");
     close $self->{'MYLOG'};          close $self->{'MYLOG'};
   }      }
 }  }
   
 sub new {  sub new {
   my $package = shift;      my $package = shift;
   my $self = shift || {};      my $self = shift || {};
   
   $self->{'base_path'}  ||= '.';      $self->{'base_path'}  ||= '.';
   $self->{'log_path'}   ||= $self->{'base_path'};      $self->{'log_path'}   ||= $self->{'base_path'};
   $self->{'log_prefix'} ||= 'LOG';      $self->{'log_prefix'} ||= 'LOG';
   $self->{'log_file'}   ||= GetLogName(      $self->{'log_file'}   ||= GetLogName(
     $self->{'log_prefix'},          $self->{'log_prefix'},
     $self->{'log_path'}          $self->{'log_path'}
   );      );
   bless $self, $package;      bless $self, $package;
 }  }
   
 sub s  sub s
 {  {
   my $self = shift;      my $self = shift;
   my $m = shift;      my $m = shift;
   return $self->mylog($m, LOG_SAVE);      return $self->mylog($m, LOG_SAVE);
 }  }
   
 sub p  sub p
 {  {
   my $self = shift;      my $self = shift;
   my $m = shift;      my $m = shift;
   return $self->mylog($m, LOG_PRINT);      return $self->mylog($m, LOG_PRINT);
 }  }
   
 sub sp  sub sp
 {  {
   my $self = shift;      my $self = shift;
   my $m = shift;      my $m = shift;
   return $self->mylog($m, LOG_SAVE | LOG_PRINT);      return $self->mylog($m, LOG_SAVE | LOG_PRINT);
 }  }
   
 sub mylog  sub mylog
 {  {
   my $self = shift;      my $self = shift;
   
   my $thing = shift;      my $thing = shift;
   chomp $thing;      chomp $thing;
   
   my $which = shift;      my $which = shift;
   
   my $MYLOG;      my $MYLOG;
   if ($which & LOG_PRINT) {      if ($which & LOG_PRINT) {
     print $thing, "\n";          print $thing, "\n";
   }      }
   
   if ($which & LOG_SAVE) {      if ($which & LOG_SAVE) {
     if ($self->{'MYLOG'}) {          if ($self->{'MYLOG'}) {
       $MYLOG = $self->{'MYLOG'};              $MYLOG = $self->{'MYLOG'};
     } else {          } else {
       unless ($MYLOG) {              unless ($MYLOG) {
         open ($MYLOG, '>>', $self->{'log_path'} . '/' . $self->{'log_file'})                  open ($MYLOG, '>>', $self->{'log_path'} . '/' .
           or die "Couldn't open logfile!\n";                      $self->{'log_file'}) or die "Couldn't open logfile!\n";
         my $ofh = select $MYLOG;                  my $ofh = select $MYLOG;
         $|=1;                  $|=1;
         select $ofh;                  select $ofh;
         $self->{'MYLOG'} = $MYLOG;                  $self->{'MYLOG'} = $MYLOG;
   
         $self->p("Opened log ($self->{'log_path'}/$self->{'log_file'})");                  $self->p("Opened log ($self->{'log_path'}/$self->{'log_file'})");
       }              }
           }
           flock($MYLOG, LOCK_EX);
           print $MYLOG (scalar gmtime), "\t", $thing, "\n"
               or die "Couldn't print to MYLOG: $!";
           flock($MYLOG, LOCK_UN);
     }      }
     flock($MYLOG, LOCK_EX);  
     print $MYLOG (scalar gmtime), "\t", $thing, "\n"  
       or die "Couldn't print to MYLOG: $!";  
     flock($MYLOG, LOCK_UN);  
   }  
 }  }
   
 sub GetLogName  sub GetLogName
 {  {
   my $prefix  = shift || die "Invalid prefix passed for log";      my $prefix  = shift || die "Invalid prefix passed for log";
   
   my $logdate = GetLogDate();      my $logdate = GetLogDate();
   my $logver  = 0;      my $logver  = 0;
   my $logname;      my $logname;
   
   do {      do {
     $logname = $prefix . $logdate . sprintf("%02d", $logver) . '.log';          $logname = $prefix . $logdate . sprintf("%02d", $logver) . '.log';
     $logver++;          $logver++;
   } until (not -e $logname);      } until (not -e $logname);
   
   return $logname;      return $logname;
 }  }
   
 sub GetLogDate  sub GetLogDate
 {  {
   my ($sec,$min,$hour,$mday,$mon,$year,,,) = localtime();      my ($sec,$min,$hour,$mday,$mon,$year,,,) = localtime();
   
   $mon++;      $mon++;
   $year += 1900;      $year += 1900;
   
   if ($min  < 10) { $min  = "0$min"  }      if ($min  < 10) { $min  = "0$min"  }
   if ($sec  < 10) { $sec  = "0$sec"  }      if ($sec  < 10) { $sec  = "0$sec"  }
   if ($hour < 10) { $hour = "0$hour" }      if ($hour < 10) { $hour = "0$hour" }
   if ($mday < 10) { $mday = "0$mday" }      if ($mday < 10) { $mday = "0$mday" }
   if ($mon  < 10) { $mon  = "0$mon"  }      if ($mon  < 10) { $mon  = "0$mon"  }
   
   my $time = $year . $mon . $mday;      my $time = $year . $mon . $mday;
   
   return $time;      return $time;
 }  }

Legend:
Removed from v.1.30  
changed lines
  Added in v.1.31

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>