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

Annotation of trango/Net-Telnet-Trango/scripts/update_trango.pl, Revision 1.22

1.16      mike        1: #!/usr/bin/perl
1.22    ! andrew      2: # $RedRiver: update_trango.pl,v 1.21 2007/02/01 17:08:44 mike Exp $
1.16      mike        3: ########################################################################
                      4: # update_trango.pl *** Updates trango foxes with a new firmware
                      5: #
                      6: # 2005.11.15 #*#*# andrew fresh <andrew@mad-techies.org>
                      7: ########################################################################
                      8: use strict;
                      9: use warnings;
                     10:
1.22    ! andrew     11: use YAML qw/ Dump LoadFile /;
1.16      mike       12: use Net::TFTP;
                     13: use lib '.';
                     14: use Net::Telnet::Trango;
                     15:
1.22    ! andrew     16: my $config_file = shift || 'update_trango.yaml';
1.16      mike       17: my $max_tries = 3;
                     18:
                     19:
                     20: my $l = Mylogger->new( { log_prefix => 'UT' } );
                     21:
                     22:
                     23: $l->sp("Reading config file '$config_file'");
1.22    ! andrew     24: my $conf = LoadFile($config_file);
1.16      mike       25:
1.22    ! andrew     26: #$l->sp("  Hardware Type: $conf->{'type'}");
        !            27: #$l->sp("  File Name:     $conf->{'file_name'}");
        !            28: #$l->sp("  File Size:     $conf->{'file_size'}");
        !            29: #$l->sp("  File Checksum: $conf->{'file_cksum'}");
        !            30: #$l->sp("  FW Version:    $conf->{'ver'}");
        !            31: #$l->sp("  FW Checksum:   $conf->{'cksum'}");
        !            32: #$l->sp("");
        !            33:
        !            34: my @foxes = (
        !            35: '10.100.1.2',
        !            36: '10.100.2.2',
        !            37: '10.100.3.2',
        !            38: '10.100.4.2',
        !            39: );
        !            40:
        !            41: foreach my $fox (@foxes) {
        !            42:   $l->sp("Checking: $fox");
        !            43:   my $needs_reboot = 0;
1.16      mike       44:
                     45:   ## Connect and login.
                     46:   my $t = new Net::Telnet::Trango (
                     47:     Timeout => 5,
                     48:     Errmode => 'return',
                     49:   ) or die "Couldn't make new connection: $!";
                     50:   $l->p("Connecting to $fox");
                     51:   unless ( $t->open($fox) ) {
                     52:     $l->sp("Error connecting: $!");
                     53:     next;
                     54:   }
                     55:
1.22    ! andrew     56:   foreach my $firmware_type ('Firmware', 'FPGA') {
1.21      mike       57:
1.22    ! andrew     58:     if (! exists $conf->{$firmware_type}) {
        !            59:          $l->s("No configs for '$firmware_type'");
        !            60:          $t->close();
        !            61:          next;
        !            62:        }
        !            63:
        !            64:     my $host_type = $t->host_type;
        !            65:     if (uc($conf->{'firmware_type'}) eq 'FPGA') {
        !            66:       $host_type =~ s/\s.*$//;
        !            67:     }
        !            68:
        !            69:     if (! exists $conf->{$firmware_type}->{$host_type}) {
        !            70:          $l->sp("No '$firmware_type' config for type $host_type");
        !            71:          $t->close();
        !            72:          next;
        !            73:        }
        !            74:
        !            75:     unless ($t->logged_in) {
        !            76:       $l->p("Logging in");
        !            77:       $t->login($conf->{general}->{'password'}) || die "Couldn't login: $!";
        !            78:          $t->exit();
        !            79:     }
        !            80:
        !            81:        foreach my $k (keys %{ $conf->{general} }) {
        !            82:          $conf->{$firmware_type}->{$host_type}->{$k} ||= $conf->{general}->{$k};
        !            83:     }
        !            84:        $conf->{$firmware_type}->{$host_type}->{firmware_type} ||= $firmware_type;
        !            85:        $conf->{$firmware_type}->{$host_type}->{type} ||= $host_type;
        !            86:
        !            87:     $l->sp("Updating: $host_type $firmware_type on $fox");
        !            88:     $l->p("Sending commands");
        !            89:     ## Send commands
        !            90:     if ( upload($t, $conf->{$firmware_type}->{$host_type}) ) {
        !            91:       $l->sp("Successfull!");
        !            92:          $needs_reboot = 1;
        !            93:     } else {
        !            94:          $l->sp("Failed");
        !            95:     }
        !            96:
        !            97:     $l->sp("");
1.21      mike       98:   }
                     99:
1.22    ! andrew    100:   if ($needs_reboot) {
        !           101:     $l->sp("Rebooting $fox");
1.17      mike      102:     $t->reboot;
                    103:   } else {
1.22    ! andrew    104:     $l->sp("Exiting $fox");
        !           105:     $t->exit();
1.17      mike      106:   }
1.22    ! andrew    107:   exit;
1.16      mike      108: }
                    109:
                    110: sub upload
                    111: {
                    112:   my $t    = shift;
1.22    ! andrew    113:   my $conf = shift;
1.16      mike      114:
1.22    ! andrew    115:   my $file = $conf->{firmware_path} . '/' . $conf->{file_name};
        !           116:
        !           117:   my $fw_type = $conf->{firmware_type};
1.19      andrew    118:
1.16      mike      119:   my $ver = $t->ver;
1.22    ! andrew    120:   print Dump $ver;
1.19      andrew    121:   $l->p("Current version '" . $ver->{$fw_type . ' Version'} . "'");
1.22    ! andrew    122:   exit;
1.16      mike      123:
                    124:   if (
1.19      andrew    125:     $ver->{$fw_type . ' Version'}  eq $conf->{'ver'} &&
                    126:     $ver->{$fw_type . ' Checksum'} eq $conf->{'cksum'}
1.16      mike      127:   ) {
                    128:     $l->sp("Already updated!");
1.21      mike      129:     return 0;
1.16      mike      130:   }
                    131:
                    132:   my $try = 0;
                    133:   while (1) {
                    134:     if ($try >= $max_tries) {
                    135:       $l->sp("Couldn't update in $max_tries tries!");
                    136:       return undef;
                    137:     }
                    138:     $try++;
                    139:
                    140:     #sysinfo($self->{'_host'});
                    141:
                    142:     $l->p("Enabling TFTPd");
1.22    ! andrew    143:     unless ($t->enable_tftpd) {
        !           144:       $l->sp("Couldn't enable tftpd");
        !           145:       next;
        !           146:     }
1.16      mike      147:
                    148:     $l->p("Uploading file ($file)");
                    149:     # use tftp to push the file up
                    150:     my $tftp = Net::TFTP->new($t->Host, Mode => 'octet');
                    151:
1.21      mike      152:     unless ($tftp->put($file, $file)) {
1.22    ! andrew    153:       $l->sp("Error uploading: " . $tftp->error);
1.21      mike      154:       next;
                    155:     }
1.16      mike      156:
                    157:     $l->p("Checking upload ($conf->{'file_cksum'})");
                    158:     my $results = $t->tftpd;
                    159:     # check the 'File Length' against ???
                    160:     if ( $results->{'File Checksum'} ne $conf->{'file_cksum'}) {
                    161:       $l->sp(
                    162:         "File checksum '" . $results->{'File Checksum'} .
1.20      mike      163:         " does not match config file '" . $conf->{'file_cksum'} . "'!"
1.16      mike      164:       );
                    165:       next;
                    166:     }
                    167:     $l->p("File checksum matches . . . ");
                    168:
                    169:     if ($results->{'File Length'}   !~ /^$conf->{'file_size'} bytes/) {
                    170:       $l->sp(
                    171:         "File length '" . $results->{'File Length'} .
                    172:         "does not match config file '" . $conf->{'file_size'} . " bytes'!"
                    173:       );
                    174:       next;
                    175:     }
                    176:     $l->p("File length matches . . . ");
                    177:
                    178:     if ( uc($results->{'File Name'}) ne uc($conf->{'file_name'}) ) {
                    179:       $l->sp(
                    180:         "File name '" . $results->{'File Name'} .
                    181:         "' does not match config file '" . $conf->{'file_name'} . "'!"
                    182:       );
                    183:       next;
                    184:     }
                    185:     $l->p("File name  matches . . . ");
                    186:
1.19      andrew    187:     my $image_type = 'mainimage';
                    188:     if ($fw_type eq 'FPGA') {
                    189:       $image_type = 'fpgaimage';
                    190:     }
                    191:     $l->p("Updating $image_type (new checksum '$conf->{'cksum'}')");
1.16      mike      192:     unless ($results = $t->updateflash(
1.19      andrew    193:       args => $image_type . ' ' . $ver->{$fw_type . ' Checksum'} .
1.16      mike      194:               ' '          . $conf->{'cksum'},
                    195:       Timeout => 90,
                    196:     ) ) {
                    197:       $l->sp("Couldn't update flash: $!");
                    198:       next;
                    199:     }
                    200:
                    201:     unless (
                    202:       defined $results->{'Checksum'} &&
                    203:       $results->{'Checksum'} eq $conf->{'cksum'}
                    204:     ) {
1.17      mike      205:       $l->sp("Saved checksum " . $results->{'Checksum'} . " does not match config file " .  $conf->{'cksum'} . "!");
1.16      mike      206:       next;
                    207:     }
                    208:     $l->p("Uploaded checksum ($results->{'Checksum'}) " .
                    209:           "matches ($conf->{'cksum'})");
                    210:
                    211:     $l->sp("Successfully updated!");
                    212:     return 1;
                    213:   }
                    214: }
                    215:
                    216: package Mylogger;
                    217:
                    218: use Fcntl ':flock'; # import LOCK_* constants
                    219: #use YAML;
                    220: use constant LOG_PRINT => 128;
                    221: use constant LOG_SAVE  =>  64;
                    222:
                    223: DESTROY {
                    224:   my $self = shift;
                    225:   if ($self->{'MYLOG'}) {
                    226:     $self->p("Closing log ($self->{'log_path'}/$self->{'log_file'})");
                    227:     close $self->{'MYLOG'};
                    228:   }
                    229: }
                    230:
                    231: sub new {
                    232:   my $package = shift;
                    233:   my $self = shift || {};
                    234:
                    235:   $self->{'base_path'}  ||= '.';
                    236:   $self->{'log_path'}   ||= $self->{'base_path'};
                    237:   $self->{'log_prefix'} ||= 'LOG';
                    238:   $self->{'log_file'}   ||= GetLogName(
                    239:     $self->{'log_prefix'},
                    240:     $self->{'log_path'}
                    241:   );
                    242:   bless $self, $package;
                    243: }
                    244:
                    245: sub s
                    246: {
                    247:   my $self = shift;
                    248:   my $m = shift;
                    249:   return $self->mylog($m, LOG_SAVE);
                    250: }
                    251:
                    252: sub p
                    253: {
                    254:   my $self = shift;
                    255:   my $m = shift;
                    256:   return $self->mylog($m, LOG_PRINT);
                    257: }
                    258:
                    259: sub sp
                    260: {
                    261:   my $self = shift;
                    262:   my $m = shift;
                    263:   return $self->mylog($m, LOG_SAVE | LOG_PRINT);
                    264: }
                    265:
                    266: sub mylog
                    267: {
                    268:   my $self = shift;
                    269:
                    270:   my $thing = shift;
                    271:   chomp $thing;
                    272:
                    273:   my $which = shift;
                    274:
                    275:   my $MYLOG;
                    276:   if ($which & LOG_PRINT) {
                    277:     print $thing, "\n";
                    278:   }
                    279:
                    280:   if ($which & LOG_SAVE) {
                    281:     if ($self->{'MYLOG'}) {
                    282:       $MYLOG = $self->{'MYLOG'};
                    283:     } else {
                    284:       unless ($MYLOG) {
                    285:                open ($MYLOG, '>>', $self->{'log_path'} . '/' . $self->{'log_file'})
                    286:           or die "Couldn't open logfile!\n";
                    287:         my $ofh = select $MYLOG;
                    288:         $|=1;
                    289:         select $ofh;
                    290:         $self->{'MYLOG'} = $MYLOG;
                    291:
                    292:         $self->p("Opened log ($self->{'log_path'}/$self->{'log_file'})");
                    293:       }
                    294:     }
                    295:     flock($MYLOG, LOCK_EX);
                    296:     print $MYLOG (scalar gmtime), "\t", $thing, "\n"
                    297:       or die "Couldn't print to MYLOG: $!";
                    298:     flock($MYLOG, LOCK_UN);
                    299:   }
                    300: }
                    301:
                    302: sub GetLogName
                    303: {
                    304:   my $prefix  = shift || die "Invalid prefix passed for log";
                    305:
                    306:   my $logdate = GetLogDate();
                    307:   my $logver  = 0;
                    308:   my $logname;
                    309:
                    310:   do {
                    311:     $logname = $prefix . $logdate . sprintf("%02d", $logver) . '.log';
                    312:     $logver++;
                    313:   } until (not -e $logname);
                    314:
                    315:   return $logname;
                    316: }
                    317:
                    318: sub GetLogDate
                    319: {
                    320:   my ($sec,$min,$hour,$mday,$mon,$year,,,) = localtime();
                    321:
                    322:   $mon++;
                    323:   $year += 1900;
                    324:
                    325:   if ($min  < 10) { $min  = "0$min"  }
                    326:   if ($sec  < 10) { $sec  = "0$sec"  }
                    327:   if ($hour < 10) { $hour = "0$hour" }
                    328:   if ($mday < 10) { $mday = "0$mday" }
                    329:   if ($mon  < 10) { $mon  = "0$mon"  }
                    330:
                    331:   my $time = $year . $mon . $mday;
                    332:
                    333:   return $time;
                    334: }

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