]> rtime.felk.cvut.cz Git - novaboot.git/blobdiff - novaboot
server: Ensure that configuration can depend on logged-in user name
[novaboot.git] / novaboot
index aa7b035c76020f8f3959604ca8b00c4576bf5180..b86dba0b3adedd1d60f6ee667234c2434188b7ec 100755 (executable)
--- a/novaboot
+++ b/novaboot
@@ -58,7 +58,7 @@ $CFG::default_target = '';
     "novabox" => '--ssh=novabox@rtime.felk.cvut.cz',
     "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\""',
+    "ryuglab" => '--target ryu --ssh=ryu@pc-sojkam.felk.cvut.cz',
     "ryulocal" => '--target ryu --dhcp-tftp --serial --reset-cmd="if which dtrrts; then dtrrts $NB_SERIAL 0 1; sleep 0.1; dtrrts $NB_SERIAL 1 1; fi"',
     );
 
@@ -129,7 +129,7 @@ my $explicit_target = $ENV{'NOVABOOT_TARGET'};
 GetOptions ("target|t=s" => \$explicit_target);
 
 # Variables for command line options
-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);
+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, $uboot_stop_key);
 
 my ($target_reset, $target_power_on, $target_power_off);
 
@@ -141,7 +141,7 @@ my ($target_reset, $target_power_on, $target_power_off);
     );
 $rsync_flags = '';
 $rom_prefix = 'rom://';
-$stty = 'raw -crtscts -onlcr 115200';
+$stty = 'raw -crtscts -onlcr -echo 115200';
 $reset = 1;                    # Reset target by default
 $interaction = 1;              # Perform target interaction by default
 $final_eol = 1;
@@ -176,8 +176,12 @@ my %opt_spec_safe = (
     "prefix|grub-prefix=s" => \$grub_prefix,
     "pulsar-root=s"  => \$pulsar_root,
     "pulsar|p:s"     => \$pulsar,
+    "remote-expect=s"=> \$remote_expect,
+    "remote-expect-silent=s"=> sub { $remote_expect=$_[1]; $remote_expect_silent=1; },
+    "remote-expect-timeout=i"=> \$remote_expect_timeout,
     "uboot-addr=s"   => \%uboot_addr,
     "uboot-cmd=s"    => \$uboot_cmd,
+    "uboot-stop-key=s" => \$uboot_stop_key,
     "uboot-init=s"   => sub { push @uboot_init, { command => $_[1] }; },
     "uboot:s"       => \$uboot,
     );
@@ -218,9 +222,6 @@ my %opt_spec = (
     "qemu-append=s"  => \$qemu_append,
     "qemu-flags|q=s" => \$qemu_flags_cmd,
     "remote-cmd=s"   => sub { @remote_cmd = ($_[1]); },
-    "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"    => sub { @reset_cmd = ($_[1]); },
     "reset-send=s"   => \$reset_send,
@@ -994,7 +995,7 @@ foreach my $script (@scripts) {
            $hostname = "";
        }
        my $files = join(" ", map({ ($file) = m/([^ ]*)/; $file; } ( @$modules, @bootloader_configs, @$copy)));
-       map({ my $file = (split)[0]; die "$file: $!" if ! -f $file; } @$modules);
+       map({ my $file = (split)[0]; die "Not a file: $file: $!" if ! -f $file; } @$modules);
        my $istty = -t STDOUT && ($ENV{'TERM'} || 'dumb') ne 'dumb';
        my $progress = $istty ? "--progress" : "";
        if ($files) {
@@ -1170,7 +1171,7 @@ if (defined $ider) {
 ### Reset target (IP relay, AMT, ...)
 
 if (defined $target_reset && $reset) {
-    print STDERR "novaboot: Reseting the test box... ";
+    print STDERR "novaboot: Resetting the test box... ";
     &$target_reset();
     print STDERR "done\n";
     if (defined $exp) {
@@ -1197,7 +1198,9 @@ if (defined $uboot) {
     $exp->log_stdout(1);
     #$exp->exp_internal(1);
     $exp->expect(20,
-                [qr/Hit any key to stop autoboot:/, sub { $exp->send("\n"); exp_continue; }],
+                [qr/Hit any key to stop autoboot:/, sub {
+                    $exp->send($uboot_stop_key // "\n");
+                    exp_continue; }],
                 $uboot_prompt) || die "No U-Boot prompt deteceted";
     foreach my $cmdspec (@uboot_init) {
        my ($cmd, $timeout);
@@ -1246,14 +1249,14 @@ if (defined $uboot) {
        if (defined $kbin) {
            die "No '--uboot-addr kernel' given" unless $uboot_addr{kernel};
            $exp->send("tftpboot $uboot_addr{kernel} $prefix$kbin\n");
-           $exp->expect(10,
+           $exp->expect(15,
                         [qr/##/, sub { exp_continue; }],
                         $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,
+           $exp->expect(15,
                         [qr/##/, sub { exp_continue; }],
                         $uboot_prompt) || die "Device tree load: " . ($! || "timeout");
        } else  {
@@ -1262,7 +1265,7 @@ if (defined $uboot) {
        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,
+           $exp->expect(15,
                         [qr/##/, sub { exp_continue; }],
                         $uboot_prompt) || die "Initrd load: " . ($! || "timeout");
        } else {
@@ -1376,6 +1379,40 @@ having per-system, per-user or per-project configurations.
 Configuration file syntax is described in section L</"CONFIGURATION
 FILES">.
 
+Novaboot newcomers may be confused by a large number of configuration
+options. Understanding all these options is not always needed,
+depending on the used setup. The L<figure from the doc directory
+|https://github.com/wentasah/novaboot/blob/master/doc/typical-setups.svg>
+shows different setups that vary in how much effort is needed
+configure novaboot for them. The setups are:
+
+=over 3
+
+=item A: Laptop and target device only
+
+This requires to configure everything on the laptop side, including a
+serial line connection (L</--serial>, L</--remote-cmd>, ...), power
+on/off/reset commands (L</--reset-cmd>, ...), TFTP server
+(L</--server>, L</--prefix>...), device IP addresses, etc.
+
+=item B: Laptop, target device and external TFTP server
+
+Like the previous setup, but the TFTP (and maybe DHCP) configuration
+is handled by a server. Novaboot users need to understand where to
+copy their files to the TFTP server (L</--server>) and which IP
+addresses their target will get, but do not need to configure the
+servers themselves.
+
+=item C: Novaboot server running novaboot-shell
+
+With this setup, the configuration is done on the server. Users only
+need to know the SSH account (L</--ssh>) used to communicate between
+novaboot and novaboot server. The server is implemented as a
+restricted shell (L<novaboot-shell(1)>) on the server. No need to give
+full shell access to novaboot users on the server.
+
+=back
+
 =head2 Simple examples of using C<novaboot>:
 
 To boot Linux (files F<bzImage> and F<rootfs.cpio> in current
@@ -1451,7 +1488,7 @@ I<script2> configurations.
 
 =head1 PHASES AND OPTIONS
 
-Novaboot performs its work in several phases. Command like options
+Novaboot performs its work in several phases. Command line options
 described bellow influence the execution of each phase or allow their
 skipping. The list of phases (in the execution order) is as follows.
 
@@ -1779,10 +1816,23 @@ example C<ssh server 'cu -l /dev/ttyS0'>.
 
 =item --remote-expect=I<string>
 
-Wait for reception of I<string> after establishing the remote
-connection. This option is needed when novaboot should wait for
-confirmation before deploying files to the target, e.g. to not
-overwrite other user's files when they are using the target.
+Wait for reception of I<string> after establishing the remote serial
+line connection. Novaboot assumes that after establishing the serial
+line connection, the user running novaboot has exclusive access to the
+target. If establishing of the serial line connection happens
+asynchronously (e.g. running a command remotely via SSH), we need this
+option to wait until the exclusive access is confirmed by the remote
+side.
+
+Depending on target configuration, this option can solve two practical
+problems: 1) Overwriting of files deployed by another user currently
+using the target. 2) Resetting the target board before serial line
+connection is established and thus missing bootloader interaction.
+
+Example of usage with the L<sterm
+tool|https://rtime.felk.cvut.cz/gitweb/sojka/sterm.git>:
+
+  --remote-cmd='ssh -tt example.com sterm -v /dev/ttyUSB0' --remote-expect='sterm: Connected'
 
 =item --remote-expect-silent=I<string>
 
@@ -1940,6 +1990,12 @@ novaboot script. I<prompt> specifies the U-Boot's prompt (default is
 
 Disable U-Boot interaction previously enabled with B<--uboot>.
 
+=item --uboot-stop-key=I<key>
+
+Character, which is sent as a response to U-Boot's "Hit any key to
+stop autoboot" message. The default value is newline, but some devices
+(e.g. TP-Link TD-W8970) require a specific key to be pressed.
+
 =item --uboot-init
 
 Command(s) to send the U-Boot bootloader before loading the images and
@@ -2001,7 +2057,7 @@ The same as --exiton -re --exiton I<regex>.
 =item --exiton-timeout=I<seconds>
 
 By default B<--exiton> waits for the string match forever. When this
-option is specified, "exiton" timeouts after the specifies the number of
+option is specified, "exiton" timeouts after the specified number of
 seconds and novaboot returns non-zero exit code.
 
 =item -i, --interactive