[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.24

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

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