NAME
App::FuguVM::State - what FuguVM remembers about one VM between runs
SYNOPSIS
use App::FuguVM::State;
my $state = App::FuguVM::State->new($state_dir, 'default')
or die "cannot open the state of 'default'\n";
$state->mark_running;
if ($state->was_unclean_shutdown) {
check_the_disk();
}
DESCRIPTION
Each VM has a directory under the state directory:
<state_dir>/<vm>/status the JSON state, mode 0600
<state_dir>/<vm>/vm.pid the QEMU process
<state_dir>/<vm>/proxy.pid the proxy child
<state_dir>/<vm>/disk.qcow2 the working disk
The JSON blob rides on Fugu::StateFile. The two process IDs ride on Fugu::Pidfile, which takes its lock before it truncates and reaps a zombie before it answers "running". A QEMU that became a zombie therefore reads as stopped, which is what a caller that is about to start a second one needs to know.
The module is persistence only. It starts nothing and stops nothing: the proxy lifecycle belongs to App::FuguVM::Guest. That split is what removed the require cycle between the two modules.
METHODS
new
App::FuguVM::State->new($state_dir, $vm_name)
Open the state of one VM, and create its directory when it is absent.
The VM name becomes a directory name, so it must be one safe path component: no separator, no NUL byte, and not one of the two directory entries. A name that is not returns undef and a message in the log. The method also returns undef when the directory is a symlink, is not a directory, or cannot be created.
load, save
Read and write the JSON state. new loads. A corrupt file gives empty state and does not stop the program that would rewrite it.
store, state_dir, vm_state_dir, vm_name, data
store returns the Fugu::StateFile. App::FuguVM::Guest gives it to the proxy, which keeps its port there.
state_dir returns the directory that holds every VM's state, and vm_state_dir the one that holds this VM's. data returns the state hash reference for a caller that changes several keys at once.
vm_pidfile, proxy_pidfile
Return the Fugu::Pidfile objects. QEMU writes the first itself, through its -pidfile option; the proxy supervisor owns the second.
get_vm_pid, clear_vm_pid, is_vm_running
The QEMU process. QEMU writes the pid file itself, through its -pidfile option, so there is no setter.
disk_path, disk_exists
The working disk of the VM.
is_installed, mark_installed
Whether OpenBSD is installed on the disk. An installed system boots its own disk and never attaches the miniroot again.
set_root_password, get_root_password
The password that the installer set. The store writes at mode 0600.
mark_ssh_key_installed, get_installed_ssh_pubkey
Which SSH public key the guest holds. The state records the key itself, not only that there is one. Thus a key that changed in the configuration is installed again on the next fuguvm up.
mark_running, mark_clean_shutdown, mark_unclean_shutdown, was_unclean_shutdown, clear_shutdown_state
Whether the last stop was clean. was_unclean_shutdown also reports true when the state says running and the process is gone: the VM crashed or was killed, and the disk may need a check.
SEE ALSO
Fugu::Pidfile, Fugu::StateFile, App::FuguVM::Guest
AUTHOR
Dick Olsson <hi@senzilla.io>