use strict;
use warnings;
use warnings (exists $ENV{NOVABOOT_TEST} ? (FATAL => 'all') : ());
-use Getopt::Long qw(GetOptionsFromString);
+use Getopt::Long qw(GetOptionsFromString GetOptionsFromArray);
use Pod::Usage;
use File::Basename;
use File::Spec;
"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.86.92: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)\'"',
- "ryuglab" => '--server=pc-sojkam.felk.cvut.cz:/srv/tftp --uboot --uboot-init="mw f0000b00 \${psc_cfg}; sleep 1" --remote-cmd="ssh -tt pc-sojkam.felk.cvut.cz \"sterm -d -s 115200 /dev/ttyUSB0\""',
- "ryulocal" => '--dhcp-tftp --serial --uboot --uboot-init="dhcp; mw f0000b00 \${psc_cfg}; sleep 1" --reset-cmd="if which dtrrts; then dtrrts $NB_SERIAL 0 1; sleep 0.1; dtrrts $NB_SERIAL 1 1; fi"',
-
+ "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\""',
+ "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"',
);
chomp(my $nproc = `nproc`);
$CFG::scons = "scons -j$nproc";
my @dirs = File::Spec->splitdir($dir);
$dir = File::Spec->catdir(@dirs[0..$#dirs-1]);
}
+ @cfgs = reverse @cfgs;
+ $dir = $ENV{'NOVABOOT_CONFIG_DIR'} || '/etc/novaboot.d';
+ if (opendir(my $dh, $dir)) {
+ my @etccfg = map { "$dir/$_" } grep { /^[-_a-zA-Z0-9]+$/ && -f "$dir/$_" } readdir($dh);
+ closedir $dh;
+ @etccfg = sort(@etccfg);
+ @cfgs = ( @etccfg, @cfgs );
+ }
}
my $cfg = $ENV{'NOVABOOT_CONFIG'};
Getopt::Long::Configure(qw/no_ignore_case pass_through/);
GetOptions ("config|c=s" => \$cfg);
-read_config($_) foreach $cfg or reverse @cfgs;
+read_config($_) foreach $cfg or @cfgs;
## Command line handling
my $explicit_target;
GetOptions ("target|t=s" => \$explicit_target);
-my ($amt, @append, $bender, @chainloaders, $concat, $config_name_opt, $dhcp_tftp, $dump_opt, $dump_config, @exiton, @expect_raw, $gen_only, $grub_config, $grub_prefix, $grub_preamble, $grub2_prolog, $grub2_config, $help, $iprelay, $iso_image, $interactive, $kernel_opt, $make, $man, $no_file_gen, $off_opt, $on_opt, $pulsar, $pulsar_root, $qemu, $qemu_append, $qemu_flags_cmd, $remote_cmd, $remote_expect, $reset_cmd, $rom_prefix, $rsync_flags, @scriptmod, $scons, $serial, $server, $stty, $tftp, $uboot, @uboot_init);
+my ($amt, @append, $bender, @chainloaders, $concat, $config_name_opt, $dhcp_tftp, $dump_opt, $dump_config, @exiton, @expect_raw, $gen_only, $grub_config, $grub_prefix, $grub_preamble, $grub2_prolog, $grub2_config, $help, $ider, $iprelay, $iso_image, $interactive, $kernel_opt, $make, $man, $no_file_gen, $off_opt, $on_opt, $pulsar, $pulsar_root, $qemu, $qemu_append, $qemu_flags_cmd, $remote_cmd, $remote_expect, $reset_cmd, $rom_prefix, $rsync_flags, @scriptmod, $scons, $serial, $server, $stty, $tftp, $tftp_port, $uboot, %uboot_addr, @uboot_init);
$rsync_flags = '';
$rom_prefix = 'rom://';
@expect_seen = ();
}
-Getopt::Long::Configure(qw/no_ignore_case no_pass_through/);
my %opt_spec;
%opt_spec = (
"amt=s" => \$amt,
"gen-only" => \$gen_only,
"grub|g:s" => \$grub_config,
"grub-preamble=s"=> \$grub_preamble,
- "grub-prefix=s" => \$grub_prefix,
+ "prefix|grub-prefix=s" => \$grub_prefix,
"grub2:s" => \$grub2_config,
"grub2-prolog=s" => \$grub2_prolog,
+ "ider" => \$ider,
"iprelay=s" => \$iprelay,
"iso:s" => \$iso_image,
"kernel|k=s" => \$kernel_opt,
"strip-rom" => sub { $rom_prefix = ''; },
"stty=s" => \$stty,
"tftp" => \$tftp,
+ "tftp-port=i" => \$tftp_port,
"uboot:s" => \$uboot,
+ "uboot-addr=s" => \%uboot_addr,
"uboot-init=s" => \@uboot_init,
"h" => \$help,
"help" => \$man,
# First process target options
{
my $t = defined($explicit_target) ? $explicit_target : $CFG::default_target;
- if ($t) {
+ my @target_expanded;
+ Getopt::Long::Configure(qw/no_ignore_case pass_through/);
+ while ($t) {
exists $CFG::targets{$t} or die("Unknown target '$t' (valid targets are: ".join(", ", sort keys(%CFG::targets)).")");
- GetOptionsFromString($CFG::targets{$t}, %opt_spec);
+
+ undef $explicit_target;
+ my ($ret, $remaining_args) = GetOptionsFromString ($CFG::targets{$t}, ("target|t=s" => \$explicit_target));
+ if (!$ret) { die "Error parsing target $t option"; }
+ push(@target_expanded, @$remaining_args);
+ $t = $explicit_target;
}
+ Getopt::Long::Configure(qw/no_ignore_case no_pass_through/);
+ GetOptionsFromArray(\@target_expanded, %opt_spec) or die ("Error in target definition");
}
# Then process other command line options - some of them may override
if (defined $config_name_opt && scalar(@ARGV) > 1) { die "You cannot use --name with multiple scripts"; }
+if ($ider) {
+ $iso_image //= ''; # IDE-R needs an ISO image
+ if (!defined $amt) { die "Error: --ider requires --amt"; }
+}
+
# Default options
if (defined $serial) {
$serial ||= "/dev/ttyUSB0";
my $file;
my $EOF;
my $last_fn = '';
-my ($modules, $variables, $generated, $continuation);
+my ($modules, $variables, $generated, $continuation) = ([], {}, []);
my $skip_reading = defined($on_opt) || defined($off_opt);
while (!$skip_reading && ($_ = <>)) {
if ($ARGV ne $last_fn) { # New script
if ($ret) { die("Command failure $ret"); }
}
-## WvTest handline
+## WvTest headline
if (exists $variables->{WVDESC}) {
print "Testing \"$variables->{WVDESC}\" in $last_fn:\n";
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;
return sendPOST($host, $username, $password, $content);
}
- my ($user,$amt_password,$host,$port) = ($amt =~ /(?:(.*?)(?::(.*))?@)?([^:]*)(?::([0-9]*))?/);;
- $user ||= "admin";
+ ($amt_user,$amt_password,$amt_host,$amt_port) = ($amt =~ /(?:(.*?)(?::(.*))?@)?([^:]*)(?::([0-9]*))?/);;
+ $amt_user ||= "admin";
$amt_password ||= $ENV{'AMT_PASSWORD'} || die "AMT password not specified";
- $host || die "AMT host not specified";
- $port ||= 16994;
+ $amt_host || die "AMT host not specified";
+ $amt_port ||= 16994;
+
$target_power_off = sub {
$exp->close();
- my $result = powerChange($host,$user,$amt_password, "off");
+ my $result = powerChange($amt_host,$amt_user,$amt_password, "off");
die "AMT power off failed (ReturnValue $result)" if $result != 0;
};
$target_power_on = sub {
- my $result = powerChange($host,$user,$amt_password, "on");
+ my $result = powerChange($amt_host,$amt_user,$amt_password, "on");
die "AMT power on failed (ReturnValue $result)" if $result != 0;
};
$target_reset = sub {
- my $result = powerChange($host,$user,$amt_password, "reset");
+ my $result = powerChange($amt_host,$amt_user,$amt_password, "reset");
if ($result != 0) {
- print STDERR "Warning: Cannot reset $host, trying power on. ";
- $result = powerChange($host,$user,$amt_password, "on");
+ print STDERR "Warning: Cannot reset $amt_host, trying power on. ";
+ $result = powerChange($amt_host,$amt_user,$amt_password, "on");
}
die "AMT reset failed (ReturnValue $result)" if $result != 0;
};
- my $cmd = "amtterm -u $user -p $amt_password $host $port";
+ my $cmd = "amtterm -u $amt_user -p $amt_password $amt_host $amt_port";
print "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";
+
}
+
if ($remote_expect) {
$exp->expect(10, $remote_expect) || die "Expect for '$remote_expect' timed out";
}
if (defined $builddir) {
chdir($builddir) or die "Can't change directory to $builddir: $!";
print "novaboot: Entering directory `$builddir'\n";
+} else {
+ $builddir = $invocation_dir;
}
## File generation phase
my (%files_iso, $menu_iso, $filename);
my $config_name = '';
+my $prefix = '';
foreach my $script (@scripts) {
$filename = $$script{filename};
print "novaboot: Entering directory `$builddir'\n";
}
- my $prefix;
- ($prefix = $grub_prefix) =~ s/\$NAME/$config_name/ if defined $grub_prefix;
- $prefix ||= $builddir;
+ if ($grub_prefix) {
+ $prefix = $grub_prefix;
+ $prefix =~ s/\$NAME/$config_name/;
+ $prefix =~ s/\$BUILDDIR/$builddir/;
+ }
# TODO: use $grub_prefix as first parameter if some switch is given
generate_configs('', $generated, $filename);
## Generate ISO image
if (defined $iso_image) {
system_verbose("mkdir -p isolinux");
- system_verbose('cp /usr/lib/syslinux/isolinux.bin /usr/lib/syslinux/mboot.c32 /usr/lib/syslinux/menu.c32 isolinux');
+
+ my @files;
+ if (-f '/usr/lib/ISOLINUX/isolinux.bin') {
+ # Newer ISOLINUX version
+ @files = qw(/usr/lib/ISOLINUX/isolinux.bin /usr/lib/syslinux/modules/bios/mboot.c32 /usr/lib/syslinux/modules/bios/libcom32.c32 /usr/lib/syslinux/modules/bios/menu.c32 /usr/lib/syslinux/modules/bios/ldlinux.c32);
+ } else {
+ # Older ISOLINUX version
+ @files = qw(/usr/lib/syslinux/isolinux.bin /usr/lib/syslinux/mboot.c32 /usr/lib/syslinux/menu.c32);
+ }
+ system_verbose("cp @files isolinux");
open(my $fh, ">isolinux/isolinux.cfg");
if ($#scripts) {
print $fh "TIMEOUT 50\n";
print $fh "$menu_iso";
close($fh);
- my $files = join(" ", map("$_=$_", (keys(%files_iso), 'isolinux/isolinux.bin', 'isolinux/isolinux.cfg', 'isolinux/mboot.c32', 'isolinux/menu.c32')));
+ my $files = join(" ", map("$_=$_", (keys(%files_iso), 'isolinux/isolinux.cfg', map(s|.*/|isolinux/|r, @files))));
$iso_image ||= "$config_name.iso";
# Note: We use -U flag below to "Allow 'untranslated' filenames,
my ($dhcpd_pid, $tftpd_pid);
+$tftp=1 if $tftp_port;
+
if (defined $dhcp_tftp)
{
generate_configs("(nd)", $generated, $filename);
}
if (defined $dhcp_tftp || defined $tftp) {
- system_verbose("sudo in.tftpd --listen --secure -v -v -v --pidfile tftpd.pid $builddir");
+ $tftp_port ||= 69;
+ # Unfortunately, tftpd requires root privileges even with
+ # non-privileged (>1023) port due to initgroups().
+ system_verbose("sudo in.tftpd --listen --secure -v -v -v --pidfile tftpd.pid --address :$tftp_port $builddir");
# Kill server when we die
$SIG{__DIE__} = sub { system_verbose('sudo pkill --pidfile=dhcpd.pid') if (defined $dhcp_tftp);
$SIG{INT} = sub { system_verbose('sudo pkill --pidfile=tftpd.pid'); exit(0); };
}
+### AMT IDE-R
+if (defined $ider) {
+ my $ider_cmd= "amtider -c $iso_image -u $amt_user -p $amt_password $amt_host $amt_port" ;
+ print "novaboot: Running: $ider_cmd\n" =~ s/\Q$amt_password\E/???/r;
+ my $ider_pid = fork();
+ if ($ider_pid == 0) {
+ exec($ider_cmd);
+ die "IDE redirection failed";
+ }
+ # FIXME: This collides with --tftp option. Hopefully, nobody needs
+ # to use both simultaneously.
+ $SIG{__DIE__} = sub { system_verbose('kill $ider_pid'); };
+}
+
### Reset target (IP relay, AMT, ...)
if (defined $target_reset) {
### U-boot conversation
if (defined $uboot) {
my $uboot_prompt = $uboot || '=> ';
- print "novaboot: Waiting for uBoot prompt...\n";
+ print "novaboot: Waiting for U-Boot prompt...\n";
$exp->log_stdout(1);
#$exp->exp_internal(1);
$exp->expect(20,
[qr/Hit any key to stop autoboot:/, sub { $exp->send("\n"); exp_continue; }],
- $uboot_prompt) || die "No uBoot prompt deteceted";
- while (@uboot_init) {
- my $cmd = shift @uboot_init;
+ $uboot_prompt) || die "No U-Boot prompt deteceted";
+ foreach my $cmd (@uboot_init) {
+ if ($cmd =~ /\$NB_MYIP/) {
+ my $ip = (grep /inet /, `ip addr show eth0`)[0] || die "Problem determining our IP address";
+ $ip =~ s/\s*inet ([0-9.]*).*/$1/;
+ $cmd =~ s/\$NB_MYIP/$ip/g;
+ }
+ chomp($cmd);
$exp->send("$cmd\n");
- $exp->expect(10, $uboot_prompt) || die "uBoot prompt timeout";
+ $exp->expect(10, $uboot_prompt) || die "U-Boot prompt timeout";
}
# Boot the system if there are some load lines in the script
@$modules = map { if (/\.dtb$/) { $dtb=$_; (); } else { $_ } } @$modules;
my $initrd = shift @$modules;
- my $kern_addr = '800000';
- my $initrd_addr = '-';
- my $dtb_addr = '';
+ my ($ramdisk_addr, $fdt_addr) = ('-', '');
- $exp->send("tftp $kern_addr $kbin\n");
+ die "No '--uboot-addr kernel' given" unless $uboot_addr{kernel};
+ $exp->send("tftpboot $uboot_addr{kernel} $prefix$kbin\n");
$exp->expect(10,
- [qr/#/, sub { exp_continue; }],
- $uboot_prompt) || die "Kernel load failed";
+ [qr/##/, sub { exp_continue; }],
+ $uboot_prompt) || die "Kernel load timeout";
if (defined $dtb) {
- $dtb_addr = '7f0000';
- $exp->send("tftp $dtb_addr $dtb\n");
+ die "No '--uboot-addr fdt' given" unless $uboot_addr{fdt};
+ $fdt_addr = $uboot_addr{fdt};
+ $exp->send("tftpboot $fdt_addr $prefix$dtb\n");
$exp->expect(10,
- [qr/#/, sub { exp_continue; }],
- $uboot_prompt) || die "Device tree load failed";
+ [qr/##/, sub { exp_continue; }],
+ $uboot_prompt) || die "Device tree load timeout";
}
if (defined $initrd) {
- $initrd_addr = 'b00000';
- $exp->send("tftp $initrd_addr $initrd\n");
+ die "No '--uboot-addr ramdisk' given" unless $uboot_addr{ramdisk};
+ $ramdisk_addr = $uboot_addr{ramdisk};
+ $exp->send("tftpboot $ramdisk_addr $prefix$initrd\n");
$exp->expect(10,
[qr/#/, sub { exp_continue; }],
- $uboot_prompt) || die "Initrd load failed";
+ $uboot_prompt) || die "Initrd load timeout";
}
- $exp->send("set bootargs '$kcmd'\n");
- $exp->expect(5, $uboot_prompt) || die "uBoot prompt timeout";
- $exp->send("bootm $kern_addr $initrd_addr $dtb_addr\n");
- $exp->expect(5, "\n") || die "uBoot command timeout";
+ $exp->send("echo $kcmd\n");
+ $exp->expect(1, '-re', qr{echo .*\n(.*)\n$uboot_prompt}) || die "Command line test timeout";
+ my $args = ($exp->matchlist)[0];
+ if ($args =~ /^setenv\s+bootargs/) {
+ $exp->send("$args\n");
+ } else {
+ $exp->send("setenv bootargs $kcmd\n");
+ }
+ $exp->expect(5, $uboot_prompt) || die "U-Boot prompt timeout";
+ $exp->send("bootm $uboot_addr{kernel} $ramdisk_addr $fdt_addr\n");
+ $exp->expect(5, "\n") || die "U-Boot command timeout";
}
}
=item 2.
Create a bootloader configuration file (currently supported
-bootloaders are GRUB, GRUB2, Pulsar and U-Boot) and copy it with all
-other files needed for booting to a remote boot server.
+bootloaders are GRUB, GRUB2, ISOLINUX, Pulsar and U-Boot) and copy it
+with all other files needed for booting to a remote boot server.
./script --server=192.168.1.1:/tftp --iprelay=192.168.1.2
=item 3.
Run DHCP and TFTP server on developer's machine to PXE-boot the target
-host from it. E.g.
+machine from it. E.g.
./script --dhcp-tftp
When a PXE-bootable machine is connected via Ethernet to developer's
-machine, it will boot the configuration described in I<script>.
+machine, it will boot the configuration described in the I<script>.
=item 4.
novaboot --iso -- script1 script2
-The created ISO image will have GRUB bootloader installed on it and
+The created ISO image will use ISOLINUX bootloader installed on it and
the boot menu will allow selecting between I<script1> and I<script2>
configurations.
=head1 PHASES AND OPTIONS
Novaboot performs its work in several phases. Each phase can be
-influenced by several options, certain phases can be skipped. The list
-of phases (in the execution order) and the corresponding options
-follow.
+influenced by several command line options, certain phases can be
+skipped. The list of phases (in the execution order) and the
+corresponding options follow.
=head2 Configuration reading phase
-After starting, novaboot reads configuration files. By default, it
-searches for files named F<.novaboot> starting from the directory of
-the novaboot script (or working directory, see bellow) and continuing
-upwards up to the root directory. The configuration files are read in
-order from the root directory downwards with latter files overriding
-settings from the former ones.
+After starting, novaboot reads configuration files. Their content is
+described in section L</"CONFIGURATION FILE">. By default,
+configuration is read from two locations. First from the configuration
+directory and second from F<.novaboot> files along the path to the
+current directory. The later read files override settings from the
+former ones.
+
+Configuration directory is determined by the content of
+NOVABOOT_CONFIG_DIR environment variable defaulting to
+F</etc/novaboot.d>. Files in this directory with names consisting
+solely from English letters, numbers, dashes '-' and underscores '_'
+(note that dot '.' is not included) are read in alphabetical order.
+
+Then novaboot searches for files named F<.novaboot> starting from the
+directory of the novaboot script (or working directory, see bellow)
+and continuing upwards up to the root directory. The found
+configuration files are then read in the opposite order (i.e. from the
+root directory downwards). This allows to have, for example, user
+specific configuration in F<~/.novaboot> and project specific one in
+F<~/project/.novaboot>.
In certain cases, the location of the novaboot script cannot be
determined in this early phase. This happens either when the script is
-read from the standard input or when novaboot is invoked explicitly
-and options precede the script name, as in the example L</"4."> above.
-In this case the current working directory is used as a starting point
-for configuration file search.
+read from the standard input or when novaboot is invoked explicitly as
+in the example L</"4."> above. In this case the current working
+directory is used as a starting point for configuration file search
+instead of the novaboot script directory.
=over 8
Append a string to the first C<load> line in the novaboot script. This
can be used to append parameters to the kernel's or root task's
-command line. Can appear multiple times.
+command line. This option can appear multiple times.
=item -b, --bender
=item --chainloader=I<chainloader>
-Chainloader that is loaded before the kernel and other files specified
-in the novaboot script. E.g. 'bin/boot/bender promisc'.
+Specifies a chainloader that is loaded before the kernel and other
+files specified in the novaboot script. E.g. 'bin/boot/bender
+promisc'.
=item --dump
GRUB or GRUB2 config files. This is useful for specifying GRUB's
timeout.
-=item --grub-prefix=I<prefix>
+=item --prefix=I<prefix>
-Specifies I<prefix> that is put in front of every file name in GRUB's
-F<menu.lst>. The default value is the absolute path to the build directory.
+Specifies I<prefix> (e.g. F</srv/tftp>) that is put in front of every
+file name in generated bootloader configuration files (or in U-Boot
+commands).
If the I<prefix> contains string $NAME, it will be replaced with the
name of the novaboot script (see also B<--name>).
+If the I<prefix> contains string $BUILDDIR, it will be replaced with
+the build directory (see also B<--build-dir>).
+
+=item --grub-prefix
+
+Alias for B<--prefix>.
+
=item --grub2[=I<filename>]
-Generate GRUB2 menuentry in I<filename>. If I<filename> is not
-specified F<grub.cfg> is used. The content of the menuentry can be
-customized with B<--grub-preable>, B<--grub2-prolog> or
+Generate GRUB2 menu entry in I<filename>. If I<filename> is not
+specified F<grub.cfg> is used. The content of the menu entry can be
+customized with B<--grub-preamble>, B<--grub2-prolog> or
B<--grub_prefix> options.
-In order to use the the generated menuentry on your development
+In order to use the the generated menu entry on your development
machine that uses GRUB2, append the following snippet to
F</etc/grub.d/40_custom> file and regenerate your grub configuration,
i.e. run update-grub on Debian/Ubuntu.
=item --grub2-prolog=I<prolog>
-Specifies text I<preable> that is put at the beginning of the entry
-GRUB2 entry.
+Specifies text that is put at the beginning of the GRUB2 menu entry.
=item -m, --make[=make command]
be booted via PXE BIOS (or similar mechanism) on the test machine
directly connected by a plain Ethernet cable to your workstation.
-The DHCP and TFTP servers require root privileges and C<novaboot>
+The DHCP and TFTP servers requires root privileges and C<novaboot>
uses C<sudo> command to obtain those. You can put the following to
-I</etc/sudoers> to allow running the necessary commands without
-asking for password.
+I</etc/sudoers> to allow running the necessary commands without asking
+for password.
Cmnd_Alias NOVABOOT = /bin/ip a add 10.23.23.1/24 dev eth0, /bin/ip l set dev eth0 up, /usr/sbin/dhcpd -d -cf dhcpd.conf -lf dhcpd.leases -pf dhcpd.pid, /usr/sbin/in.tftpd --listen --secure -v -v -v --pidfile tftpd.pid *, /usr/bin/touch dhcpd.leases, /usr/bin/pkill --pidfile=dhcpd.pid, /usr/bin/pkill --pidfile=tftpd.pid
your_login ALL=NOPASSWD: NOVABOOT
Starts a TFTP server on your workstation. This is similar to
B<--dhcp-tftp> except that DHCP server is not started.
-The TFTP server require root privileges in order to listen on TFTP
-port and C<novaboot> uses C<sudo> command to obtain those. You can put
-the following to I</etc/sudoers> to allow running the necessary
-commands without asking for password.
+The TFTP server require root privileges and C<novaboot> uses C<sudo>
+command to obtain those. You can put the following to I</etc/sudoers>
+to allow running the necessary commands without asking for password.
Cmnd_Alias NOVABOOT = /usr/sbin/in.tftpd --listen --secure -v -v -v --pidfile tftpd.pid *, /usr/bin/pkill --pidfile=tftpd.pid
your_login ALL=NOPASSWD: NOVABOOT
+=item --tftp-port=I<port>
+
+Port to run the TFTP server on. Implies B<--tftp>.
+
=item --iso[=filename]
Generates the ISO image that boots NOVA system via GRUB. If no filename
=item --server[=[[user@]server:]path]
-Copy all files needed for booting to another location (implies B<-g>
-unless B<--grub2> is given). The files will be copied (by B<rsync>
-tool) to the directory I<path>. If the I<path> contains string $NAME,
-it will be replaced with the name of the novaboot script (see also
-B<--name>).
+Copy all files needed for booting to another location. The files will
+be copied (by B<rsync> tool) to the directory I<path>. If the I<path>
+contains string $NAME, it will be replaced with the name of the
+novaboot script (see also B<--name>).
+
+=item --rsync-flags=I<flags>
+
+Specifies which I<flags> are appended to F<rsync> command line when
+copying files as a result of I<--server> option.
=item --concat
concatenating all files of the same name from all subdirectories of
I<path-wo-name> found on the "server".
-=item --rsync-flags=I<flags>
+=item --ider
-Specifies which I<flags> are appended to F<rsync> command line when
-copying files as a result of I<--server> option.
+Use Intel AMT technology for IDE redirection. This allows the target
+machine to boot from novaboot created ISO image. Implies B<--iso>.
+
+The experimental C<amtider> utility needed by this option can be
+obtained from https://github.com/wentasah/amtterm.
=back
=head2 Target power-on and reset phase
+At this point, the target is reset (or switched on/off). There is
+several ways how this can be accomplished. Resetting a physical target
+can currently be accomplished by the following options: B<--amt>,
+B<--iprelay>, B<--reset-cmd>.
+
=over 8
=item --on, --off
=item --uboot[=I<prompt>]
-Interact with uBoot bootloader to boot the thing described in the
+Interact with U-Boot bootloader to boot the thing described in the
novaboot script. I<prompt> specifies the U-Boot's prompt (default is
"=> ", other common prompts are "U-Boot> " or "U-Boot# ").
Implementation of this option is currently tied to a particular board
booting them. This option can be given multiple times. After sending
commands from each option novaboot waits for U-Boot I<prompt>.
+If the command contains string I<$NB_MYIP> then this string is
+replaced by IPv4 address of eth0 interface.
+
+=item --uboot-addr I<name>=I<address>
+
+Load address of U-Boot's C<tftpboot> command for loading I<name>,
+where name is one of I<kernel>, I<ramdisk> or I<fdt> (flattened device
+tree).
+
=back
=head2 Target interaction phase
=item WVDESC
-Description of the wvtest-compliant program.
+Description of the WvTest-compliant program.
=item WVTEST_TIMEOUT
Novaboot can read its configuration from one or more files. By
default, novaboot looks for files named F<.novaboot> as described in
-L</Configuration reading phase>. Alternatively, its location can be
-specified with the B<-c> switch or with the NOVABOOT_CONFIG
-environment variable. The configuration file has perl syntax and
-should set values of certain Perl variables. The current configuration
-can be dumped with the B<--dump-config> switch. Some configuration
-variables can be overridden by environment variables (see below) or by
-command line switches.
+L</Configuration reading phase>. Alternatively, configuration file
+location can be specified with the B<-c> switch or with the
+NOVABOOT_CONFIG environment variable. The configuration file has Perl
+syntax and should set values of certain Perl variables. The current
+configuration can be dumped with the B<--dump-config> switch. Some
+configuration variables can be overridden by environment variables
+(see below) or by command line switches.
Supported configuration variables include:
=item %targets
-Hash of shortcuts to be used with the B<--target> option. If the hash
-contains, for instance, the following pair of values
+Hash of target definitions to be used with the B<--target> option. The
+key is the identifier of the target, the value is the string with
+command line options. For instance, if the configuration file contains:
- 'mybox' => '--server=boot:/tftproot --serial=/dev/ttyUSB0 --grub',
+ $targets{'mybox'} = '--server=boot:/tftproot --serial=/dev/ttyUSB0 --grub',
then the following two commands are equivalent:
Name of the novaboot configuration file to use instead of the default
one(s).
+=item NOVABOOT_CONFIG_DIR
+
+Name of the novaboot configuration directory. When not specified
+F</etc/novaboot.d> is used.
+
=item NOVABOOT_BENDER
Defining this variable has the same meaning as B<--bender> option.
=head1 AUTHORS
Michal Sojka <sojka@os.inf.tu-dresden.de>
+
+=cut
+
+# LocalWords: novaboot Novaboot NOVABOOT TFTP PXE DHCP filename stty
+# LocalWords: chainloader stdout Qemu qemu preprocessing ISOLINUX bootable
+# LocalWords: config subprocesses sudo sudoers tftp dhcp IDE stdin
+# LocalWords: subdirectories TTY whitespace heredoc POSIX WvTest