GetVersion() is equivalent to Ping() but can be used to perform version checks.
Signed-off-by: Francois Gouget fgouget@codeweavers.com --- testbot/bin/LibvirtTool.pl | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-)
diff --git a/testbot/bin/LibvirtTool.pl b/testbot/bin/LibvirtTool.pl index 46354439a..dd330a5ab 100755 --- a/testbot/bin/LibvirtTool.pl +++ b/testbot/bin/LibvirtTool.pl @@ -365,6 +365,23 @@ sub CheckOff() return ChangeStatus("dirty", "off", "done"); }
+sub SetupTestAgentd($$) +{ + my ($VM, $Booting) = @_; + + Debug(Elapsed($Start), " Setting up the $VMKey TestAgent server\n"); + LogMsg "Setting up the $VMKey TestAgent server\n"; + my $TA = $VM->GetAgent(); + $TA->SetConnectTimeout(undef, undef, $WaitForBoot) if ($Booting); + my $Version = $TA->GetVersion(); + if (!$Version) + { + my $ErrMessage = $TA->GetLastError(); + FatalError("Could not connect to the $VMKey TestAgent: $ErrMessage\n"); + } + $TA->Disconnect(); +} + sub Revert() { my $VM = CreateVMs()->GetItem($VMKey); @@ -402,18 +419,8 @@ sub Revert() # The VM is now sleeping which may allow some tasks to run return 1 if (ChangeStatus("reverting", "sleeping"));
- # Verify that the TestAgent server accepts connections - Debug(Elapsed($Start), " Verifying the TestAgent server\n"); - LogMsg "Verifying the $VMKey TestAgent server\n"; - my $TA = $VM->GetAgent(); - $TA->SetConnectTimeout(undef, undef, $WaitForBoot) if ($Booting); - my $Success = $TA->Ping(); - $TA->Disconnect(); - if (!$Success) - { - $ErrMessage = $TA->GetLastError(); - FatalError("Cannot connect to the $VMKey TestAgent: $ErrMessage\n"); - } + # Set up the TestAgent server + SetupTestAgentd($VM, $Booting);
if ($SleepAfterRevert != 0) {
Live snapshots have to save the content of the VM's memory which takes space in the disk image. They may also be specific to the host they are running on (e.g. AMD vs. Intel CPU). And they may need to be recreated after QEmu upgrades. So VMs always have a powered off snapshot as reference and backups made from the powered off state. With VMs that are configured for autologin and autostart of TestAgentd this patch removes the need for the administrator to manually recreate the live snapshots.
Signed-off-by: Francois Gouget fgouget@codeweavers.com --- testbot/bin/LibvirtTool.pl | 85 ++++++++++++++++++++---- testbot/lib/WineTestBot/Config.pm | 7 +- testbot/lib/WineTestBot/LibvirtDomain.pm | 5 +- 3 files changed, 79 insertions(+), 18 deletions(-)
diff --git a/testbot/bin/LibvirtTool.pl b/testbot/bin/LibvirtTool.pl index dd330a5ab..72075ae5e 100755 --- a/testbot/bin/LibvirtTool.pl +++ b/testbot/bin/LibvirtTool.pl @@ -6,7 +6,7 @@ # network trouble, and thus are best performed in a separate process. # # Copyright 2009 Ge van Geldorp -# Copyright 2012-2017 Francois Gouget +# Copyright 2012-2019 Francois Gouget # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -382,6 +382,25 @@ sub SetupTestAgentd($$) $TA->Disconnect(); }
+sub CreateSnapshot($$) +{ + my ($Domain, $SnapshotName) = @_; + + if ($SleepAfterBoot != 0) + { + Debug(Elapsed($Start), " Sleeping for the $SnapshotName snapshot\n"); + LogMsg "Letting $VMKey settle down for the $SnapshotName snapshot\n"; + sleep($SleepAfterBoot); + } + + Debug(Elapsed($Start), " Creating the $SnapshotName snapshot\n"); + my $ErrMessage = $Domain->CreateSnapshot($SnapshotName); + if (defined $ErrMessage) + { + FatalError("Could not recreate the $SnapshotName snapshot on $VMKey: $ErrMessage\n"); + } +} + sub Revert() { my $VM = CreateVMs()->GetItem($VMKey); @@ -391,11 +410,34 @@ sub Revert() return 1; } $CurrentStatus = "reverting"; + my $DomainSnapshot = $VM->IdleSnapshot; + my $ExtraTimeout = 0; + my $CreateSnapshot;
- # Revert the VM (and power it on if necessary) my $Domain = $VM->GetDomain(); - Debug(Elapsed($Start), " Reverting $VMKey to ", $VM->IdleSnapshot, "\n"); - my ($ErrMessage, $Booting) = $Domain->RevertToSnapshot(); + if (!$Domain->HasSnapshot($DomainSnapshot) and $DomainSnapshot =~ s/-live$//) + { + # Add some extra time to boot the VM and create the live snapshot + $ExtraTimeout += $WaitForBoot + $VMToolTimeout / 2; + $CreateSnapshot = 1; + Debug(Elapsed($Start), " $VMKey does not yet have a $DomainSnapshot-live snapshot\n"); + } + if (!$Domain->HasSnapshot($DomainSnapshot)) + { + FatalError("Could not find $VMKey's $DomainSnapshot snapshot\n"); + } + if ($ExtraTimeout) + { + Debug(Elapsed($Start), " Extend the $VMKey revert deadline by $ExtraTimeout\n"); + my $Deadline = $VM->Status eq "maintenance" ? (time() + $VMToolTimeout) : + $VM->ChildDeadline; + $VM->ChildDeadline($Deadline + $ExtraTimeout); + $VM->Save(); + } + + # Revert the VM (and power it on if necessary) + Debug(Elapsed($Start), " Reverting $VMKey to $DomainSnapshot\n"); + my ($ErrMessage, $Booting) = $Domain->RevertToSnapshot($DomainSnapshot); if (defined $ErrMessage) { # Libvirt/QEmu is buggy and cannot revert a running VM from one hardware @@ -408,28 +450,45 @@ sub Revert() FatalError("Could not power off $VMKey: $ErrMessage\n"); }
- Debug(Elapsed($Start), " Reverting $VMKey to ", $VM->IdleSnapshot, "... again\n"); - ($ErrMessage, $Booting) = $Domain->RevertToSnapshot(); + Debug(Elapsed($Start), " Reverting $VMKey to $DomainSnapshot... again\n"); + ($ErrMessage, $Booting) = $Domain->RevertToSnapshot($DomainSnapshot); } if (defined $ErrMessage) { - FatalError("Could not revert $VMKey to ". $VM->IdleSnapshot .": $ErrMessage\n"); + FatalError("Could not revert $VMKey to $DomainSnapshot: $ErrMessage\n"); }
- # The VM is now sleeping which may allow some tasks to run - return 1 if (ChangeStatus("reverting", "sleeping")); + # Mark the VM as sleeping which allows the scheduler to abort the revert in + # favor of higher priority tasks. But don't allow interruptions in the + # middle of snapshot creation! + if (!$CreateSnapshot) + { + return 1 if (ChangeStatus("reverting", "sleeping")); + }
# Set up the TestAgent server SetupTestAgentd($VM, $Booting);
- if ($SleepAfterRevert != 0) + if ($CreateSnapshot) { + CreateSnapshot($Domain, $VM->IdleSnapshot); + } + else + { + my $Sleep = ($Booting and $SleepAfterBoot > $SleepAfterRevert) ? + $SleepAfterBoot : $SleepAfterRevert; Debug(Elapsed($Start), " Sleeping\n"); - LogMsg "Letting ". $VM->Name ." settle down for ${SleepAfterRevert}s\n"; - sleep($SleepAfterRevert); + LogMsg "Letting $VMKey settle down for ${Sleep}s\n"; + sleep($Sleep); + } + + if ($CreateSnapshot) + { + # The activity monitor does not like it when VMs skip the sleeping step + return 1 if (ChangeStatus("reverting", "sleeping")); }
- return ChangeStatus("sleeping", "idle", "done"); + return ChangeStatus($CurrentStatus, "idle", "done"); }
diff --git a/testbot/lib/WineTestBot/Config.pm b/testbot/lib/WineTestBot/Config.pm index 3496c310e..bcfa9ae82 100644 --- a/testbot/lib/WineTestBot/Config.pm +++ b/testbot/lib/WineTestBot/Config.pm @@ -28,7 +28,7 @@ WineTestBot::Config - Site-independent configuration settings use vars qw (@ISA @EXPORT @EXPORT_OK $UseSSL $LogDir $DataDir $BinDir %RepoURLs $DbDataSource $DbUsername $DbPassword $MaxRevertingVMs $MaxRevertsWhileRunningVMs $MaxActiveVMs $MaxRunningVMs - $MaxVMsWhenIdle $SleepAfterRevert $WaitForBoot + $MaxVMsWhenIdle $WaitForBoot $SleepAfterBoot $SleepAfterRevert $VMToolTimeout $MaxVMErrors $MaxTaskTries $AdminEMail $RobotEMail $WinePatchToOverride $WinePatchCc $ExeBuildNativeTimeout $ExeBuildTestTimeout $ExeModuleTimeout @@ -44,7 +44,8 @@ require Exporter; @ISA = qw(Exporter); @EXPORT = qw($UseSSL $LogDir $DataDir $BinDir %RepoURLs $MaxRevertingVMs $MaxRevertsWhileRunningVMs $MaxActiveVMs - $MaxRunningVMs $MaxVMsWhenIdle $SleepAfterRevert $WaitForBoot + $MaxRunningVMs $MaxVMsWhenIdle $WaitForBoot $SleepAfterBoot + $SleepAfterRevert $VMToolTimeout $MaxVMErrors $MaxTaskTries $AdminEMail $RobotEMail $WinePatchToOverride $WinePatchCc $SuiteTimeout $ExeBuildNativeTimeout $ExeBuildTestTimeout $ExeModuleTimeout @@ -92,6 +93,8 @@ $MaxVMsWhenIdle = undef;
# How long to attempt to connect to the TestAgent while the VM is booting. $WaitForBoot = 90; +# How long to let the VM settle down after booting it before taking a snapshot. +$SleepAfterBoot = 30; # How long to let the VM settle down after a revert before starting a task on # it (in seconds). $SleepAfterRevert = 0; diff --git a/testbot/lib/WineTestBot/LibvirtDomain.pm b/testbot/lib/WineTestBot/LibvirtDomain.pm index dbb2a39ea..207dc6d45 100644 --- a/testbot/lib/WineTestBot/LibvirtDomain.pm +++ b/testbot/lib/WineTestBot/LibvirtDomain.pm @@ -309,11 +309,10 @@ sub GetSnapshotName($) return (undef, $SnapshotName); }
-sub RevertToSnapshot($) +sub RevertToSnapshot($$) { - my ($self) = @_; + my ($self, $SnapshotName) = @_;
- my $SnapshotName = $self->{VM}->IdleSnapshot; my ($ErrMessage, $Domain, $Snapshot) = $self->_GetSnapshot($SnapshotName); return ($ErrMessage, undef) if (defined $ErrMessage);
The TestAgentd server may start before the X session. But we need the latter to run the Wine tests so make sure the X session has started before creating the live snapshot.
Signed-off-by: Francois Gouget fgouget@codeweavers.com --- testbot/bin/LibvirtTool.pl | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
diff --git a/testbot/bin/LibvirtTool.pl b/testbot/bin/LibvirtTool.pl index 72075ae5e..d1402bc49 100755 --- a/testbot/bin/LibvirtTool.pl +++ b/testbot/bin/LibvirtTool.pl @@ -386,6 +386,29 @@ sub CreateSnapshot($$) { my ($Domain, $SnapshotName) = @_;
+ if ($VM->Type eq "wine") + { + # Make sure an X session has started before taking the snapshot + Debug(Elapsed($Start), " Waiting for the X session\n"); + LogMsg "Waiting for the $VMKey X session\n"; + my $TA = $VM->GetAgent(); + my $Pid = $TA->Run(["sh", "-c", "while ! xset -display :0.0 q >/dev/null; do sleep 1; done"], 0); + if (!$Pid) + { + FatalError("Could not check for the X session on the $VMKey VM\n"); + } + if (!defined $TA->Wait($Pid, $SleepAfterBoot)) + { + my $ErrMessage = $TA->GetLastError(); + if ($ErrMessage =~ /timed out waiting for the child process/) + { + FatalError("Timed out waiting for the X session\n"); + } + FatalError("An error occurred while waiting for the X session: $ErrMessage\n"); + } + $TA->Disconnect(); + } + if ($SleepAfterBoot != 0) { Debug(Elapsed($Start), " Sleeping for the $SnapshotName snapshot\n");