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 ($target_reset, $target_power_on, $target_power_off);
+
# Default values of certain command line options
%uboot_addr = (
'kernel' => '${kernel_addr_r}',
@expect_seen = ();
}
-my %opt_spec;
-%opt_spec = (
+# Options which can be safely specified on the server (via --ssh),
+# i.e. which cannot cause unwanted local code execution etc.
+my %opt_spec_safe = (
+ "grub|g:s" => \$grub_config,
+ "grub-preamble=s"=> \$grub_preamble,
+ "grub2-prolog=s" => \$grub2_prolog,
+ "grub2:s" => \$grub2_config,
+ "prefix|grub-prefix=s" => \$grub_prefix,
+ "pulsar-root=s" => \$pulsar_root,
+ "pulsar|p:s" => \$pulsar,
+ "uboot-addr=s" => \%uboot_addr,
+ "uboot-cmd=s" => \$uboot_cmd,
+ "uboot-init=s" => sub { push @uboot_init, { command => $_[1] }; },
+ "uboot:s" => \$uboot,
+ );
+
+my %opt_spec = (
+ %opt_spec_safe,
"amt=s" => \$amt,
"append|a=s" => \@append,
"bender|b" => \$bender,
"expect-raw=s" => sub { my ($n, $v) = @_; unshift(@expect_raw, eval($v)); },
"final-eol!" => \$final_eol,
"gen-only" => \$gen_only,
- "grub|g:s" => \$grub_config,
- "grub-preamble=s"=> \$grub_preamble,
- "prefix|grub-prefix=s" => \$grub_prefix,
- "grub2:s" => \$grub2_config,
- "grub2-prolog=s" => \$grub2_prolog,
"ider" => \$ider,
"interaction!" => \$interaction,
"iprelay=s" => \$iprelay,
"no-file-gen" => \$no_file_gen,
"off" => \$off_opt,
"on" => \$on_opt,
- "pulsar|p:s" => \$pulsar,
- "pulsar-root=s" => \$pulsar_root,
"qemu|Q:s" => \$qemu,
"qemu-append=s" => \$qemu_append,
"qemu-flags|q=s" => \$qemu_flags_cmd,
"sendcont=s" => \&handle_send,
"serial|s:s" => \$serial,
"server:s" => \$server,
+ "ssh:s" => \&handle_novaboot_server,
"strip-rom" => sub { $rom_prefix = ''; },
"stty=s" => \$stty,
"tftp" => \$tftp,
"tftp-port=i" => \$tftp_port,
- "uboot:s" => \$uboot,
"no-uboot" => sub { undef $uboot; },
- "uboot-addr=s" => \%uboot_addr,
- "uboot-cmd=s" => \$uboot_cmd,
- "uboot-init=s" => sub { push @uboot_init, { command => $_[1] }; },
"h" => \$help,
"help" => \$man,
);
+sub handle_novaboot_server
+{
+ my ($n, $val) = @_;
+ my $xdg_runtime_dir = $ENV{XDG_RUNTIME_DIR} || '/var/run';
+ my $ssh_ctl_path = "${xdg_runtime_dir}/novaboot-%r@%h%p";
+
+ $remote_cmd = "ssh -tt -M -S '${ssh_ctl_path}' '${val}' console";
+ $remote_expect = "novaboot-shell: Connected";
+ $server = "$val:";
+ $rsync_flags = "--rsh='ssh -S \'${ssh_ctl_path}\''";
+ ($grub_prefix = $val) =~ s/@.*// if index($val, '@') != -1;
+ $reset_cmd = "ssh -tt -S '${ssh_ctl_path}' '${val}' reset";
+
+ $target_power_off = sub { system_verbose("ssh -tt -S '${ssh_ctl_path}' '${val}' off"); };
+ $target_power_on = sub { system_verbose("ssh -tt -S '${ssh_ctl_path}' '${val}' on"); };
+
+ my $cmd = "ssh '${val}' get-config";
+ print STDERR "novaboot: Running: $cmd\n";
+ my @target_config = qx($cmd < /dev/null);
+ if ($?) { die("Cannot get target configuration from the server"); }
+ printf "novaboot: Received configuration from the server:%s\n", (!@target_config) ? " empty" : "";
+ foreach (@target_config) { chomp; print " $_\n"; }
+
+ GetOptionsFromArray(\@target_config, %opt_spec_safe) or die("Error processing configuration from the server");
+ if (scalar @target_config) { die "Unsuported configuration received from the server: ".join(", ", @target_config); }
+}
+
# First process target options
{
my $t = defined($explicit_target) ? $explicit_target : $CFG::default_target;
$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/);
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 || defined $iprelay_cmd) {
to use from either B<NOVABOOT_TARGET> environment variable or
B<$default_target> configuration file variable.
+=item --ssh=I<user@hostname>
+
+Configures novaboot to control the target via C<novaboot-shell>
+running remotely via SSH.
+
+Using this option is the same as specifying B<--remote-cmd>,
+B<--remote-expect>, B<--server> B<--rsync-flags>, B<--prefix> and
+B<--reset-cmd> manually in a way compatible with V<novaboot-shell>.
+
+Currently, this in an initial experimental implementation. We plan to
+change/extend this feature soon!
+
=back
=head2 Script preprocessing phase
=item --on, --off
Switch on/off the target machine and exit. The script (if any) is
-completely ignored. Currently, it works only with B<--iprelay> or
-B<--amt>.
+completely ignored. Currently, it works only with the following
+options: B<--iprelay>, B<--amt>, B<--ssh>.
=item -Q, --qemu[=I<qemu-binary>]