#!/usr/bin/perl
my
$url
;
my
$domain
;
my
$target_state_name
;
sub
help {
say
<<~
'HELP'
;
Usage:
wait
-domain-state [-c URI] domain state
Waits
for
the domain to reach the
given
state.
State
values
:
none
running
blocked
paused
shutdown
shutoff
crashed
suspended
Falls back to the LIBVIRT_DEFAULT_URI environment variable
when
no
URI is
given
.
HELP
}
Log::Any::Adapter->set(
'Stdout'
,
log_level
=>
'error'
);
GetOptions(
'c=s'
=> \
$url
);
unless
(
@ARGV
== 2) {
help();
exit
1;
}
$domain
=
shift
@ARGV
;
$target_state_name
=
shift
@ARGV
;
my
$loop
= IO::Async::Loop->new;
my
$virt
= Sys::Async::Virt->new(
);
$loop
->add(
$virt
);
$log
->trace(
'Created libvirt client application layer'
);
my
%states
= (
Sys::Async::Virt::Domain->
NOSTATE
=>
'no state'
,
Sys::Async::Virt::Domain->
RUNNING
=>
'running'
,
Sys::Async::Virt::Domain->
BLOCKED
=>
'blocked'
,
Sys::Async::Virt::Domain->
PAUSED
=>
'paused'
,
Sys::Async::Virt::Domain->
SHUTDOWN
=>
'shutting down'
,
Sys::Async::Virt::Domain->
SHUTOFF
=>
'shut off'
,
Sys::Async::Virt::Domain->
CRASHED
=>
'crashed'
,
Sys::Async::Virt::Domain->
PMSUSPENDED
=>
'suspended'
,
);
my
%state_args
= (
'none'
=> Sys::Async::Virt::Domain->NOSTATE,
'running'
=> Sys::Async::Virt::Domain->RUNNING,
'blocked'
=> Sys::Async::Virt::Domain->BLOCKED,
'paused'
=> Sys::Async::Virt::Domain->PAUSED,
'shutdown'
=> Sys::Async::Virt::Domain->SHUTDOWN,
'shutoff'
=> Sys::Async::Virt::Domain->SHUTOFF,
'crashed'
=> Sys::Async::Virt::Domain->CRASHED,
'suspended'
=> Sys::Async::Virt::Domain->PMSUSPENDED,
);
my
$target_state
=
$state_args
{
$target_state_name
};
try
{
await
$virt
->
connect
;
my
$dom
= await
$virt
->domain_lookup_by_name(
'releaser'
);
my
$cb
= await
$virt
->domain_event_register_any(
$virt
->DOMAIN_EVENT_ID_LIFECYCLE,
$dom
);
my
$event_f
;
my
$state
;
do
{
$event_f
=
$cb
->next_event;
$state
= await
$dom
->get_state;
}
while
(
$event_f
->is_ready);
say
"Current state: $states{$state->{state}}"
;
if
(
$state
->{state} !=
$target_state
) {
while
(
my
$event_data
= await
$event_f
) {
$state
= await
$dom
->get_state;
say
"Lifecycle event; current state: $states{$state->{state}}"
;
if
(
$state
->{state} ==
$target_state
) {
await
$cb
->cancel;
}
$event_f
=
$cb
->next_event;
}
}
await
$virt
->
close
;
}
catch
(
$e
) {
say
"Error: $e"
;
exit
1;
}