NAME

App::FuguVM::Console - drive the serial console of a guest

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');

DESCRIPTION

The console answers no protocol, so an expect(1) script types at it. The module runs the OpenBSD installer that way, and it runs any other script the operator names: fuguvm expect is that second verb. The scripts ship under share/fuguvm/expect, and 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.

METHODS

new

App::FuguVM::Console->new(host => ..., port => ...)

The host and port name the serial console. Each script reads its timeout from FUGUVM_TIMEOUT in the environment and carries its own default.

attach

$console->attach

Attach the terminal of the caller to this console, with 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, Ctrl-], and then 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 fuguvm expect each hold the same port, so an operator must not attach while one runs.

script_path

App::FuguVM::Console->script_path($name)

Return the path of a shipped script, or undef. The method also works on the class: App::FuguVM::DiskCache hashes the installer script into its cache key, so it must resolve the script the same way run_install does.

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 (yes or no, default yes). The method passes them to 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 verify set to 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 no, the script answers yes and writes a warning that the guest installs unverified sets.

run_autoinstall

$console->run_autoinstall(\%config)

Start an autoinstall(8) over the console. The configuration gives autoinstall_url, the URL that the guest fetches the response file from, and the architecture. The method passes them to 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 _expect directly, like run_install, and it must not use run_script: run_script needs the execute bit, and an installed share tree does not keep it.

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.

SEE ALSO

expect(1), Fugu::File, Fugu::Process, App::FuguVM::Guest

AUTHOR

Dick Olsson <hi@senzilla.io>