From: Stefan Hanreich <s.hanreich@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH v2 pve-container 2/2] add migration hooks to container migration process
Date: Thu, 6 Oct 2022 14:44:42 +0200 [thread overview]
Message-ID: <20221006124447.120701-4-s.hanreich@proxmox.com> (raw)
In-Reply-To: <20221006124447.120701-1-s.hanreich@proxmox.com>
Using the pct commands implemented in the previous commit, this commit
adds running the migration-hooks during the container migration process.
I am redirecting STDERR from the pct mtunnel to /dev/null since it is
not captured by the current fork_ssh_tunnel function and can then
pollute the output of the migration task. The STDERR of the
migrate-hookscript is not affected, since it is captured by the remote
mtunnel command and gets transferred via the query-migrate-hook command.
Signed-off-by: Stefan Hanreich <s.hanreich@proxmox.com>
---
src/PVE/LXC/Migrate.pm | 119 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 119 insertions(+)
diff --git a/src/PVE/LXC/Migrate.pm b/src/PVE/LXC/Migrate.pm
index 2ef1cce..fdde180 100644
--- a/src/PVE/LXC/Migrate.pm
+++ b/src/PVE/LXC/Migrate.pm
@@ -89,6 +89,8 @@ sub prepare {
if !$target_scfg->{content}->{rootdir};
});
+ $self->migration_hook($vmid, 'pre');
+
# todo: test if VM uses local resources
# test ssh connection
@@ -384,6 +386,15 @@ sub phase3 {
}
}
+# only called when phase1 was successful
+sub phase3_cleanup {
+ my ($self, $vmid, $err) = @_;
+
+ if (!$self->{errors}) {
+ $self->migration_hook($vmid, 'post');
+ }
+}
+
sub final_cleanup {
my ($self, $vmid) = @_;
@@ -413,7 +424,115 @@ sub final_cleanup {
$self->cmd($cmd);
}
}
+}
+
+sub fork_tunnel {
+ my ($self, $ssh_forward_info) = @_;
+
+ my $cmd = ['/usr/sbin/pct', 'mtunnel', '2>', '/dev/null'];
+ my $log = sub {
+ my ($level, $msg) = @_;
+ $self->log($level, $msg);
+ };
+
+ return PVE::Tunnel::fork_ssh_tunnel($self->{rem_ssh}, $cmd, $ssh_forward_info, $log);
+}
+
+sub migration_hook {
+ my ($self, $vmid, $phase) = @_;
+
+ if (!$self->{vmconf}->{hookscript}) {
+ return;
+ }
+
+ my $stop_on_error = $phase eq 'pre';
+
+ PVE::GuestHelpers::exec_hookscript(
+ $self->{vmconf},
+ $vmid,
+ "$phase-migrate",
+ $stop_on_error,
+ );
+
+ my $tunnel;
+
+ eval {
+ $tunnel = $self->{tunnel} // $self->fork_tunnel();
+ };
+ if ($@ =~ /can't open tunnel/) {
+ $self->log('warn', 'Target node does not support mtunnel. Not running hookscript on target, but still continuing with migration.');
+ return;
+ } elsif ($@) {
+ die $@;
+ }
+
+ my $close_tunnel = sub {
+ if (!$self->{tunnel}) {
+ eval {
+ $self->log('info', "closing tunnel for migration hook");
+ PVE::Tunnel::finish_tunnel($tunnel);
+ };
+ if ($@) {
+ $self->log('warn', 'could not close tunnel to remote host');
+ }
+ }
+ };
+
+ my $result;
+
+ eval {
+ $self->log('info', "starting hook $phase-migrate on target");
+
+ $result = PVE::Tunnel::write_tunnel($tunnel, 30, "migrate-hook", {
+ vmid => $vmid,
+ phase => $phase,
+ source => PVE::INotify::nodename(),
+ target => $self->{node},
+ });
+ };
+ my $err = $@;
+
+ if ($err) {
+ $close_tunnel->();
+ die $err;
+ }
+
+ $self->log('info', "successfully started hook $phase-migrate on target");
+
+ my $running = 1;
+
+ while ($running) {
+ eval {
+ $result = PVE::Tunnel::write_tunnel($tunnel, 30, "query-migrate-hook");
+
+ if (!exists $result->{status}) {
+ die "Invalid response!";
+ } elsif ($result->{status} eq 'running') {
+ sleep(5);
+ } elsif ($result->{status} eq 'finished') {
+ $self->log('info', "$phase-migrate hook ran successfully on target:\n$result->{output}");
+ } elsif ($result->{status} eq 'error') {
+ my $msg = "An error occured during running the hookscript:\n" . $result->{output};
+
+ if ($stop_on_error) {
+ die $msg;
+ } else {
+ $self->log('warn', $msg)
+ }
+ } else {
+ die "Invalid response!";
+ }
+
+ $running = $result->{status} eq 'running';
+ };
+ if ($@) {
+ $err = $@;
+ last;
+ }
+ }
+ $close_tunnel->();
+ die $err if $err;
}
1;
--
2.30.2
next prev parent reply other threads:[~2022-10-06 12:45 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-06 12:44 [pve-devel] [PATCH v2 pve-container/qemu-server/pve-docs/pve-guest-common 0/8] Add pre/post-migrate hooks Stefan Hanreich
2022-10-06 12:44 ` [pve-devel] [PATCH v2 pve-guest-common 1/1] Add run_params to exec_hookscript function Stefan Hanreich
2022-10-06 12:44 ` [pve-devel] [PATCH v2 pve-container 1/2] add pct mtunnel command to the CLI Stefan Hanreich
2022-10-06 12:44 ` Stefan Hanreich [this message]
2022-10-06 12:44 ` [pve-devel] [PATCH v2 pve-docs 1/3] Add pre/post-migrate events to hookscript example Stefan Hanreich
2022-10-06 12:44 ` [pve-devel] [PATCH v2 pve-docs 2/3] Add hookscript section to container documentation Stefan Hanreich
2022-10-06 12:44 ` [pve-devel] [PATCH v2 pve-docs 3/3] Add pre/post-migrate section to VM hookscript documentation Stefan Hanreich
2022-10-06 12:44 ` [pve-devel] [PATCH v2 qemu-server 1/2] add migrate-hook and query-migrate-hook commands to CLI Stefan Hanreich
2022-10-06 12:44 ` [pve-devel] [PATCH v2 qemu-server 2/2] add migration hooks to VM migration process Stefan Hanreich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20221006124447.120701-4-s.hanreich@proxmox.com \
--to=s.hanreich@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox