App-FuguVM
view release on metacpan or search on metacpan
lib/App/FuguVM/Console.pod view on Meta::CPAN
=head1 NAME
App::FuguVM::Console - drive the serial console of a guest
=head1 SYNOPSIS
use App::FuguVM::Console;
my $console = App::FuguVM::Console->new(
host => '127.0.0.1',
port => $console_port,
);
$console->run_install({
root_password => $password,
proxy_url => $proxy->guest_url,
arch => 'arm64',
verify => 'yes',
}) or die "installation failed\n";
$console->run_script('reboot.exp');
=head1 DESCRIPTION
The console answers no protocol, so an L<expect(1)> script types at it.
The module runs the OpenBSD installer that way, and it runs any other
script the operator names: C<fuguvm expect> is that second verb. The
scripts ship under F<share/fuguvm/expect>, and L<Fugu::File> resolves
them against the install root.
The run is a passthrough: the child writes straight to the terminal of
the caller. An installation writes for tens of minutes, and an
operator who waits needs to see the progress while it happens.
=head1 METHODS
=head2 new
App::FuguVM::Console->new(host => ..., port => ...)
The host and port name the serial console. Each script reads its
timeout from C<FUGUVM_TIMEOUT> in the environment and carries its own
default.
=head2 attach
$console->attach
Attach the terminal of the caller to this console, with L<telnet(1)>.
The method returns the exit code of telnet(1).
The guest never closes the console, so no end of file ends the
attachment. The operator ends it with the telnet escape key,
C<Ctrl-]>, and then C<quit>. The method saves the terminal attributes
of standard input first, and it restores them on every exit path, the
signal path included, because telnet(1) leaves the terminal raw when
a signal kills it. A signal that kills the tool also ends telnet(1),
so no raw orphan keeps the terminal.
The console takes one client. An installation and C<fuguvm expect>
each hold the same port, so an operator must not attach while one
runs.
=head2 script_path
App::FuguVM::Console->script_path($name)
Return the path of a shipped script, or C<undef>. The method also
works on the class: L<App::FuguVM::DiskCache> hashes the installer script
into its cache key, so it must resolve the script the same way
C<run_install> does.
=head2 run_install
$console->run_install(\%config)
Drive a complete installation. The configuration gives the root
password, the proxy URL that the guest fetches its sets through, the
architecture, and the verify word (C<yes> or C<no>, default C<yes>).
The method passes them to F<install.exp> in that order, after the
host and the port. The script reads its arguments by position, so the
tool and the script land in one commit.
With C<verify> set to C<yes>, the script does not answer the
"Continue without verification?" prompt of the installer: the
installer of a numbered release verifies each set by itself, so the
prompt reports a broken mirror, and the script exits 1. With C<no>,
the script answers yes and writes a warning that the guest installs
unverified sets.
=head2 run_autoinstall
$console->run_autoinstall(\%config)
Start an autoinstall(8) over the console. The configuration gives
C<autoinstall_url>, the URL that the guest fetches the response file
from, and the architecture. The method passes them to
F<autoinstall.exp> in that order, after the host and the port. The
script answers the install prompt and the response-file prompt, and
the response file answers every other installer question.
The method calls C<_expect> directly, like C<run_install>, and it
must not use C<run_script>: C<run_script> needs the execute bit, and
an installed share tree does not keep it.
=head2 run_script
$console->run_script($script, @args)
Run one script against this console. The argument is a path, or the
name of a shipped script.
=head1 SEE ALSO
( run in 3.408 seconds using v1.01-cache-2.11-cpan-54e63673c56 )