From: Fiona Ebner <f.ebner@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [PATCH ha-manager v4 14/27] api: resources: migration: support additional migration options
Date: Thu, 15 Oct 2026 14:50:48 +0200 [thread overview]
Message-ID: <20261015125112.174954-15-f.ebner@proxmox.com> (raw)
In-Reply-To: <20261015125112.174954-1-f.ebner@proxmox.com>
Additional migration options can now be passed from the guest API
endpoints to the HA stack. From the HA resource API endpoint, the
options are passed all the way to the resource plugins.
Check that all nodes are recent enough to support the new-style JSON
CRM command, otherwise produce a warning and fall-back to the previous
behavior ignoring the additional migration options.
The migration API endpoints for containers and VMs use different
parameters. For example, the endpoint for containers does not have
the 'with-conntrack-state' option. To keep the schema for the more
abstract endpoint for HA resources clean, separate by type using a
oneOf schema and let the resource plugins declare additional
parameters via a migrate_json_properties() method.
Initially, this will be used to fix #7053 and pass along the
'with-conntrack-state' migration option.
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
Dependency bump for pve-cluster needed!
Changes in v4:
* Add cfs_update() call.
* Import raise_param_exc().
* Ensure error messages are also visible on the CLI.
* Only use JSON-style command if required to avoid fallout in
scenarios with old manager that fails to report its version properly
* Document why continuing when the version-info for a node cannot be
parsed is better than aborting.
src/PVE/API2/HA/Resources.pm | 110 ++++++++++++++++++++++++++++++-----
src/PVE/HA/Resources.pm | 1 +
2 files changed, 97 insertions(+), 14 deletions(-)
diff --git a/src/PVE/API2/HA/Resources.pm b/src/PVE/API2/HA/Resources.pm
index b96572b..6a97b2f 100644
--- a/src/PVE/API2/HA/Resources.pm
+++ b/src/PVE/API2/HA/Resources.pm
@@ -3,15 +3,20 @@ package PVE::API2::HA::Resources;
use strict;
use warnings;
+use JSON qw();
+
+use PVE::Exception qw(raise_param_exc);
use PVE::SafeSyslog;
use PVE::Tools qw(extract_param);
use PVE::Cluster;
use PVE::HA::Config;
+use PVE::HA::Env::PVE2;
use PVE::HA::Resources;
use HTTP::Status qw(:constants);
use Storable qw(dclone);
use PVE::JSONSchema qw(get_standard_option);
use PVE::RPCEnvironment;
+use PVE::RESTEnvironment qw(log_warn);
use PVE::RESTHandler;
@@ -34,6 +39,49 @@ my $api_copy_config = sub {
return $scfg;
};
+my sub migrate_json_properties {
+ my ($type) = @_;
+ my $plugin = PVE::HA::Resources->lookup($type);
+ return $plugin->migrate_json_properties();
+}
+
+my sub json_crm_command_is_supported {
+ PVE::Cluster::cfs_update();
+ my $version_info = PVE::Cluster::get_node_kv('version-info');
+ for my $node (sort keys $version_info->%*) {
+ my $node_info = eval { JSON::decode_json($version_info->{$node}); };
+ if (my $err = $@) {
+ # An updated cluster is the usual situation. An error here should not affect the usual
+ # situation. The unusual situation, where the master is too old and unable to report its
+ # version properly is rare. Submitting a JSON CRM to such a master will lead to warnings
+ # and the command being ignored. Note that migration without extra parameters also still
+ # works.
+ log_warn("failed check for migration options support - cannot parse version info for"
+ . " node '$node' - $err");
+ } elsif (!PVE::Cluster::pvecfg_min_version($node_info->{version}, 9, 2, 22)) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+my sub json_crm_command_is_applicable {
+ my ($sid, $req_node, $param) = @_;
+
+ # FIXME: MAJOR VERSION: use JSON variant even if there are no extra params.
+ if (scalar(keys $param->%*) > 0) {
+ if (json_crm_command_is_supported()) {
+ return 1;
+ } else {
+ log_warn("$sid migration to $req_node: ignoring additional migration options - not"
+ . " supported by CRM on all nodes");
+ }
+ }
+
+ return 0;
+}
+
sub check_service_state {
my ($sid, $req_state) = @_;
@@ -336,20 +384,32 @@ __PACKAGE__->register_method({
check => ['perm', '/', ['Sys.Console']],
},
parameters => {
- additionalProperties => 0,
- properties => {
- sid => get_standard_option(
- 'pve-ha-resource-or-vm-id',
- { completion => \&PVE::HA::Tools::complete_sid },
- ),
- node => get_standard_option(
- 'pve-node',
- {
- completion => \&PVE::Cluster::complete_migration_target,
- description => "Target node.",
- },
- ),
+ 'type-property' => 'resource-type',
+ 'type-property-schema' => {
+ type => 'string',
+ description => 'The resource type. Automatically determined from the service ID.',
+ enum => $resource_type_enum,
},
+ oneOf => [
+ {
+ 'instance-type' => 'ct',
+ additionalProperties => 0,
+ properties => migrate_json_properties('ct'),
+ },
+ {
+ 'instance-type' => 'vm',
+ additionalProperties => 0,
+ properties => migrate_json_properties('vm'),
+ },
+ ],
+ },
+ resolve_type => sub {
+ my ($param) = @_;
+ my $type = (PVE::HA::Config::parse_sid($param->{sid}))[1];
+ if (!($type eq 'ct' || $type eq 'vm')) {
+ die "Unknown service type '$type' for 'migrate' endpoint schema.\n";
+ }
+ return $type;
},
returns => {
type => 'object',
@@ -403,12 +463,34 @@ __PACKAGE__->register_method({
my ($sid, $type, $name) = PVE::HA::Config::parse_sid(extract_param($param, 'sid'));
my $req_node = extract_param($param, 'node');
+ my $resource_type = extract_param($param, 'resource-type');
+ if ($resource_type ne $type) {
+ raise_param_exc({
+ 'resource-type' => "value '$resource_type' does not match type of '$sid'" });
+ }
+
+ # The rest of the parameters in $param are migration options passed along to the plugin.
PVE::HA::Config::service_is_ha_managed($sid);
check_service_state($sid);
- PVE::HA::Config::queue_crm_commands("migrate $sid $req_node");
+ my $crm_command;
+ if (json_crm_command_is_applicable($sid, $req_node, $param)) {
+ $crm_command = JSON::to_json(
+ {
+ kind => 'migrate',
+ sid => $sid,
+ node => $req_node,
+ options => $param,
+ },
+ { canonical => 1 },
+ );
+ } else {
+ $crm_command = "migrate $sid $req_node";
+ }
+
+ PVE::HA::Config::queue_crm_commands($crm_command);
$result->{sid} = $sid;
$result->{'requested-node'} = $req_node;
diff --git a/src/PVE/HA/Resources.pm b/src/PVE/HA/Resources.pm
index 57fde00..ad603dc 100644
--- a/src/PVE/HA/Resources.pm
+++ b/src/PVE/HA/Resources.pm
@@ -3,6 +3,7 @@ package PVE::HA::Resources;
use strict;
use warnings;
+use PVE::Cluster;
use PVE::JSONSchema qw(get_standard_option);
use PVE::SectionConfig;
use PVE::HA::Tools;
--
2.47.3
next prev parent reply other threads:[~2026-10-15 12:54 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-15 12:50 [PATCH-SERIES many v4 00/27] migration: strict config check for intra-cluster migration Fiona Ebner
2026-10-15 12:50 ` [PATCH common v4 01/27] tools: move version_cmp() helper from qemu-server Fiona Ebner
2026-10-15 12:50 ` [PATCH common v4 02/27] rest handler: handle: respect schema's 'type-property' when resolving type Fiona Ebner
2026-10-15 12:50 ` [PATCH cluster v4 03/27] cluster: move pvecfg node version helpers from qemu-server Fiona Ebner
2026-10-15 12:50 ` [PATCH ha-manager v4 04/27] update crm commands: align logging with next state started/stopped Fiona Ebner
2026-10-15 12:50 ` [PATCH ha-manager v4 05/27] manager: factor out helper to check if requested resource motion is valid Fiona Ebner
2026-10-15 12:50 ` [PATCH ha-manager v4 06/27] next state stopped: align logging for motion command with next_state_started() Fiona Ebner
2026-10-15 12:50 ` [PATCH ha-manager v4 07/27] next state {stopped,started}: factor out helper to handle motion command Fiona Ebner
2026-10-15 12:50 ` [PATCH ha-manager v4 08/27] lrm: resource migration: support extra migration options Fiona Ebner
2026-10-15 12:50 ` [PATCH ha-manager v4 09/27] change service state: support hash as a parameter value Fiona Ebner
2026-10-15 12:50 ` [PATCH ha-manager v4 10/27] next state: handle motion command: support migration options Fiona Ebner
2026-10-15 12:50 ` [PATCH ha-manager v4 11/27] resources: add migrate_json_properties() method Fiona Ebner
2026-10-16 9:51 ` Daniel Kral
2026-10-15 12:50 ` [PATCH ha-manager v4 12/27] queue resource motion: support migration options Fiona Ebner
2026-10-15 12:50 ` [PATCH ha-manager v4 13/27] crm command: support JSON-style migrate command Fiona Ebner
2026-10-16 9:53 ` Daniel Kral
2026-10-15 12:50 ` Fiona Ebner [this message]
2026-10-16 9:54 ` [PATCH ha-manager v4 14/27] api: resources: migration: support additional migration options Daniel Kral
2026-10-15 12:50 ` [PATCH ha-manager v4 15/27] test: add test for " Fiona Ebner
2026-10-15 12:50 ` [PATCH qemu-server v4 16/27] helpers: move version_cmp() helper to pve-common Fiona Ebner
2026-10-15 12:50 ` [PATCH qemu-server v4 17/27] helpers: move pvecfg node version helpers to pve-cluster Fiona Ebner
2026-10-15 12:50 ` [PATCH qemu-server v4 18/27] api: migrate: allow forwarding certain migration properties to HA Fiona Ebner
2026-10-15 12:50 ` [PATCH qemu-server v4 19/27] fix #7053: api: migrate: pass 'with-conntrack-state' flag to HA migration Fiona Ebner
2026-10-15 12:50 ` [PATCH qemu-server v4 20/27] qm: mtunnel: reply when a command is unknown Fiona Ebner
2026-10-15 12:50 ` [PATCH qemu-server v4 21/27] qm: mtunnel: add 'conf' command to do strict configuration parsing Fiona Ebner
2026-10-15 12:50 ` [PATCH qemu-server v4 22/27] migration: intra-cluster: check config can be parsed on target node Fiona Ebner
2026-10-15 12:50 ` [PATCH container v4 23/27] api: migrate: allow forwarding certain migration properties to HA Fiona Ebner
2026-10-15 12:50 ` [PATCH container v4 24/27] pct: introduce mtunnel command Fiona Ebner
2026-10-15 12:50 ` [PATCH container v4 25/27] d/control: bump versioned build dependency for libpve-common-perl to 9.0.12 Fiona Ebner
2026-10-15 12:51 ` [PATCH container v4 26/27] migration: intra-cluster: check config can be parsed on target node Fiona Ebner
2026-10-15 12:51 ` [PATCH manager v4 27/27] ui: migrate: add checkbox to allow skipping newly enforced config check Fiona Ebner
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=20261015125112.174954-15-f.ebner@proxmox.com \
--to=f.ebner@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