]> rtime.felk.cvut.cz Git - novaboot.git/blobdiff - novaboot
shell: Improve error messages
[novaboot.git] / novaboot
index b0235b1fd4cedaf4d33585f3ebe5fd1fa61c2b7f..b06971cf2fc0e4e5cc039cc7deef076de149b73a 100755 (executable)
--- a/novaboot
+++ b/novaboot
@@ -47,7 +47,7 @@ $CFG::default_target = '';
 %CFG::targets = (
     'qemu' => '--qemu',
     "tud" => '--server=erwin.inf.tu-dresden.de:~sojka/boot/novaboot --rsync-flags="--chmod=Dg+s,ug+w,o-w,+rX --rsync-path=\"umask 002 && rsync\"" --grub --grub-prefix=(nd)/tftpboot/sojka/novaboot --grub-preamble="timeout 0" --concat --iprelay=141.76.48.80:2324 --scriptmod=s/\\\\bhostserial\\\\b/hostserialpci/g',
-    "novabox" => '--server=rtime.felk.cvut.cz:/srv/tftp/novaboot --rsync-flags="--chmod=Dg+s,ug+w,o-w,+rX --rsync-path=\"umask 002 && rsync\"" --pulsar --iprelay=147.32.87.159:2324',
+    "novabox" => '--server=novabox@rtime.felk.cvut.cz:/srv/tftp/novaboot --rsync-flags="--chmod=Dg+s,ug+w,o-w,+rX --rsync-path=\"umask 002 && rsync\"" --pulsar --iprelay-cmd="ssh -tt novabox@rtime.felk.cvut.cz nc localhost 2324"',
     "localhost" => '--scriptmod=s/console=tty[A-Z0-9,]+// --server=/boot/novaboot/$NAME --grub2 --grub-prefix=/boot/novaboot/$NAME --grub2-prolog="  set root=\'(hd0,msdos1)\'"',
     "ryu" =>  '--uboot --uboot-init="mw f0000b00 \${psc_cfg}; sleep 1" --uboot-addr kernel=800000 --uboot-addr ramdisk=b00000 --uboot-addr fdt=7f0000',
     "ryuglab" => '--target ryu --server=pc-sojkam.felk.cvut.cz:/srv/tftp --remote-cmd="ssh -tt pc-sojkam.felk.cvut.cz \"sterm -d -s 115200 /dev/ttyUSB0\""',
@@ -120,7 +120,7 @@ read_config($_) foreach $cfg or @cfgs;
 my $explicit_target = $ENV{'NOVABOOT_TARGET'};
 GetOptions ("target|t=s" => \$explicit_target);
 
-my ($amt, @append, $bender, @chainloaders, $concat, $config_name_opt, $dhcp_tftp, $dump_opt, $dump_config, @exiton, $exiton_timeout, @expect_raw, $final_eol, $gen_only, $grub_config, $grub_prefix, $grub_preamble, $grub2_prolog, $grub2_config, $help, $ider, $interaction, $iprelay, $iso_image, $interactive, $kernel_opt, $make, $man, $netif, $no_file_gen, $off_opt, $on_opt, $pulsar, $pulsar_root, $qemu, $qemu_append, $qemu_flags_cmd, $remote_cmd, $remote_expect, $remote_expect_silent, $reset, $reset_cmd, $reset_send, $rom_prefix, $rsync_flags, @scriptmod, $scons, $serial, $server, $stty, $tftp, $tftp_port, $uboot, %uboot_addr, $uboot_cmd, @uboot_init);
+my ($amt, @append, $bender, @chainloaders, $concat, $config_name_opt, $dhcp_tftp, $dump_opt, $dump_config, @exiton, $exiton_timeout, @expect_raw, $final_eol, $gen_only, $grub_config, $grub_prefix, $grub_preamble, $grub2_prolog, $grub2_config, $help, $ider, $interaction, $iprelay, $iprelay_cmd, $iso_image, $interactive, $kernel_opt, $make, $man, $netif, $no_file_gen, $off_opt, $on_opt, $pulsar, $pulsar_root, $qemu, $qemu_append, $qemu_flags_cmd, $remote_cmd, $remote_expect, $remote_expect_silent, $remote_expect_timeout, $reset, $reset_cmd, $reset_send, $rom_prefix, $rsync_flags, @scriptmod, $scons, $serial, $server, $stty, $tftp, $tftp_port, $uboot, %uboot_addr, $uboot_cmd, @uboot_init);
 
 # Default values of certain command line options
 %uboot_addr = (
@@ -135,6 +135,7 @@ $reset = 1;                 # Reset target by default
 $interaction = 1;              # Perform target interaction by default
 $final_eol = 1;
 $netif = 'eth0';
+$remote_expect_timeout = 180;
 
 my @expect_seen = ();
 sub handle_expect
@@ -181,6 +182,7 @@ my %opt_spec;
     "ider"           => \$ider,
     "interaction!"   => \$interaction,
     "iprelay=s"             => \$iprelay,
+    "iprelay-cmd=s"  => \$iprelay_cmd,
     "iso:s"         => \$iso_image,
     "kernel|k=s"     => \$kernel_opt,
     "interactive|i"  => \$interactive,
@@ -198,6 +200,7 @@ my %opt_spec;
     "remote-cmd=s"   => \$remote_cmd,
     "remote-expect=s"=> \$remote_expect,
     "remote-expect-silent=s"=> sub { $remote_expect=$_[1]; $remote_expect_silent=1; },
+    "remote-expect-timeout=i"=> \$remote_expect_timeout,
     "reset!"         => \$reset,
     "reset-cmd=s"    => \$reset_cmd,
     "reset-send=s"   => \$reset_send,
@@ -236,8 +239,7 @@ my %opt_spec;
        $t = $explicit_target;
     }
 
-    (undef, my @args) = @ARGV;
-    @args = (@target_expanded, @args);
+    my @args = (@target_expanded, @ARGV);
     print STDERR "novaboot: Effective options: @args\n";
 
     Getopt::Long::Configure(qw/no_ignore_case no_pass_through/);
@@ -280,6 +282,7 @@ if ($ider) {
 
 {
     my %input_opts = ('--iprelay'    => \$iprelay,
+                     '--iprelay-cmd'=> \$iprelay_cmd,
                      '--serial'     => \$serial,
                      '--remote-cmd' => \$remote_cmd,
                      '--amt'        => \$amt);
@@ -618,25 +621,34 @@ my $exp; # Expect object to communicate with the target over serial line
 my ($target_reset, $target_power_on, $target_power_off);
 my ($amt_user, $amt_password, $amt_host, $amt_port);
 
-if (defined $iprelay) {
-    my $IPRELAY;
-    $iprelay =~ /([.0-9]+)(:([0-9]+))?/;
-    my $addr = $1;
-    my $port = $3 || 23;
-    my $paddr   = sockaddr_in($port, inet_aton($addr));
-    my $proto   = getprotobyname('tcp');
-    socket($IPRELAY, PF_INET, SOCK_STREAM, $proto)  || die "socket: $!";
-    print STDERR "novaboot: Connecting to IP relay... ";
-    connect($IPRELAY, $paddr)    || die "connect: $!";
-    print STDERR "done\n";
-    $exp = Expect->init(\*$IPRELAY);
-    $exp->log_stdout(1);
+if (defined $iprelay || defined $iprelay_cmd) {
+    if (defined $iprelay) {
+       my $IPRELAY;
+       $iprelay =~ /([.0-9]+)(:([0-9]+))?/;
+       my $addr = $1;
+       my $port = $3 || 23;
+       my $paddr   = sockaddr_in($port, inet_aton($addr));
+       my $proto   = getprotobyname('tcp');
+       socket($IPRELAY, PF_INET, SOCK_STREAM, $proto)  || die "socket: $!";
+       print STDERR "novaboot: Connecting to IP relay... ";
+       connect($IPRELAY, $paddr)    || die "connect: $!";
+       print STDERR "done\n";
+       $exp = Expect->init(\*$IPRELAY);
+       $exp->log_stdout(1);
+    }
+    if (defined $iprelay_cmd) {
+       print STDERR "novaboot: Running: $iprelay_cmd\n";
+       $exp = new Expect;
+       $exp->raw_pty(1);
+       $exp->spawn($iprelay_cmd);
+    }
 
     while (1) {
        print $exp "\xFF\xF6";  # AYT
        my $connected = $exp->expect(20, # Timeout in seconds
                                     '<iprelayd: connected>',
-                                    '-re', '<WEB51 HW[^>]*>');
+                                    '-re', '<WEB51 HW[^>]*>')
+           || die "iprelay connection: " . ($! || "timeout");
        last if $connected;
     }
 
@@ -661,7 +673,8 @@ if (defined $iprelay) {
        $exp->log_stdout(0);
        print $exp relaycmd($relay, $onoff);
        my $confirmed = $exp->expect(20, # Timeout in seconds
-                                    relayconf($relay, $onoff));
+                                    relayconf($relay, $onoff))
+           || die "iprelay command: " . ($! || "timeout");
        if (!$confirmed) {
            if ($can_giveup) {
                print("Relay confirmation timeout - ignoring\n");
@@ -797,8 +810,7 @@ END
     my $cmd = "amtterm -u $amt_user -p $amt_password $amt_host $amt_port";
     print STDERR "novaboot: Running: $cmd\n" =~ s/\Q$amt_password\E/???/r;
     $exp = Expect->spawn($cmd);
-    $exp->expect(10, "RUN_SOL") || die "Expect for 'RUN_SOL' timed out";
-
+    $exp->expect(10, "RUN_SOL") || die "Expect for 'RUN_SOL': " . ($! || "timeout");
 }
 
 
@@ -808,7 +820,8 @@ if ($remote_expect) {
     if (defined $remote_expect_silent) {
        $exp->log_stdout(0);
     }
-    $exp->expect(180, $remote_expect) || die "Expect for '$remote_expect' timed out";
+    $exp->expect($remote_expect_timeout >= 0 ? $remote_expect_timeout : undef,
+                $remote_expect) || die "Expect for '$remote_expect':" . ($! || "timeout");;
     if (defined $remote_expect_silent) {
        $exp->log_stdout($log);
        print $exp->after() if $log;
@@ -1159,28 +1172,30 @@ if (defined $uboot) {
            $exp->send("tftpboot $uboot_addr{kernel} $prefix$kbin\n");
            $exp->expect(10,
                         [qr/##/, sub { exp_continue; }],
-                        $uboot_prompt) || die "Kernel load timeout";
+                        $uboot_prompt) || die "Kernel load: " . ($! || "timeout");
        }
        if (defined $dtb) {
            die "No '--uboot-addr fdt' given" unless $uboot_addr{fdt};
            $exp->send("tftpboot $uboot_addr{fdt} $prefix$dtb\n");
            $exp->expect(10,
                         [qr/##/, sub { exp_continue; }],
-                        $uboot_prompt) || die "Device tree load timeout";
+                        $uboot_prompt) || die "Device tree load: " . ($! || "timeout");
+       } else  {
+           $uboot_addr{fdt} = '';
        }
        if (defined $initrd) {
            die "No '--uboot-addr ramdisk' given" unless $uboot_addr{ramdisk};
            $exp->send("tftpboot $uboot_addr{ramdisk} $prefix$initrd\n");
            $exp->expect(10,
                         [qr/##/, sub { exp_continue; }],
-                        $uboot_prompt) || die "Initrd load timeout";
+                        $uboot_prompt) || die "Initrd load: " . ($! || "timeout");
        } else {
            $uboot_addr{ramdisk} = '-';
        }
 
        $kcmd //= '';
        $exp->send("setenv bootargs $kcmd\n");
-       $exp->expect(5, $uboot_prompt)  || die "U-Boot prompt timeout";
+       $exp->expect(5, $uboot_prompt)  || die "U-Boot prompt: " . ($! || "timeout");
 
     }
     $uboot_cmd //= $variables->{UBOOT_CMD} // 'bootm $kernel_addr $ramdisk_addr $fdt_addr';
@@ -1190,7 +1205,7 @@ if (defined $uboot) {
        $uboot_cmd =~ s/\$fdt_addr/$uboot_addr{fdt}/g;
 
        $exp->send($uboot_cmd . "\n");
-       $exp->expect(5, "\n")  || die "U-Boot command timeout";
+       $exp->expect(5, "\n")  || die "U-Boot command: " . ($! || "timeout");
     }
 }
 
@@ -1204,7 +1219,7 @@ if ($interaction && defined $exp) {
     print STDERR "novaboot: Serial line interaction (press $interrupt to interrupt)...\n";
     $exp->log_stdout(1);
     if (@exiton) {
-       $exp->expect($exiton_timeout, @expect_raw, @exiton) || die("exiton timeout");
+       $exp->expect($exiton_timeout, @expect_raw, @exiton) || die("exiton: " . ($! || "timeout"));
     } else {
        my @inputs = ($exp);
        my $infile = new IO::File;
@@ -1620,6 +1635,11 @@ the relay. If I<port> is not specified, it defaults to 23.
 
 Note: This option is supposed to work with HWG-ER02a IP relays.
 
+=item --iprelay-cmd=I<command>
+
+Similar to B<--iprelay> but uses I<command> to talk to the iprelay
+rather than direct network connection.
+
 =item -s, --serial[=device]
 
 Target's serial line is connected to host's serial line (device). The
@@ -1653,6 +1673,12 @@ echoed to stdout while waiting for the I<string>. Everything after the
 matched string is printed to stdout, so you may want to include line
 end characters in the I<string> as well.
 
+=item --remote-expect-timeout=I<seconds>
+
+Timeout in seconds for B<--remote-expect> or
+B<--remote-expect-seconds>. When negative, waits forever. The default
+is 180 seconds.
+
 =back
 
 =head2 File deployment phase
@@ -1862,12 +1888,12 @@ seconds and novaboot returns non-zero exit code.
 
 =item -i, --interactive
 
-Setup things for the interactive use of the target. Your terminal will be
-switched to raw mode. In raw mode, your system does not process input
-in any way (no echoing of entered characters, no interpretation
-special characters). This, among others, means that Ctrl-C is passed
-to the target and does no longer interrupt novaboot. Use "~~."
-sequence to exit novaboot.
+Setup things for the interactive use of the target. Your terminal will
+be switched to raw mode. In raw mode, your local terminal does not
+process input in any way (no echoing of entered characters, no
+interpretation of special characters). This, among others, means that
+Ctrl-C is passed to the target and does not interrupt novaboot. To
+exit from novaboot interactive mode type "~~.".
 
 =item --no-interaction, --interaction