From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 4EC791FF17A for ; Fri, 4 Jul 2025 20:22:30 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 7C5EE3DF0F; Fri, 4 Jul 2025 20:21:51 +0200 (CEST) From: Daniel Kral To: pve-devel@lists.proxmox.com Date: Fri, 4 Jul 2025 20:21:01 +0200 Message-Id: <20250704182102.467624-19-d.kral@proxmox.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250704182102.467624-1-d.kral@proxmox.com> References: <20250704182102.467624-1-d.kral@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.012 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pve-devel] [PATCH container v3 1/1] api: introduce migration preconditions api endpoint X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox VE development discussion Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" Add a migration preconditions api endpoint for containers in similar vein to the one which is already present for virtual machines. This is needed to inform callees about positive and negative ha resource affinity rules, which the container is part of. These inform callees about any comigrated resources or blocking resources that are caused by the resource affinity rules. Signed-off-by: Daniel Kral --- src/PVE/API2/LXC.pm | 141 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) diff --git a/src/PVE/API2/LXC.pm b/src/PVE/API2/LXC.pm index 28f7fdd..dd20604 100644 --- a/src/PVE/API2/LXC.pm +++ b/src/PVE/API2/LXC.pm @@ -1395,6 +1395,147 @@ __PACKAGE__->register_method({ }, }); +__PACKAGE__->register_method({ + name => 'migrate_vm_precondition', + path => '{vmid}/migrate', + method => 'GET', + protected => 1, + proxyto => 'node', + description => "Get preconditions for migration.", + permissions => { + check => ['perm', '/vms/{vmid}', ['VM.Migrate']], + }, + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option('pve-node'), + vmid => + get_standard_option('pve-vmid', { completion => \&PVE::LXC::complete_ctid }), + target => get_standard_option( + 'pve-node', + { + description => "Target node.", + completion => \&PVE::Cluster::complete_migration_target, + optional => 1, + }, + ), + }, + }, + returns => { + type => "object", + properties => { + running => { + type => 'boolean', + description => "Determines if the container is running.", + }, + 'allowed-nodes' => { + type => 'array', + items => { + type => 'string', + description => "An allowed node", + }, + optional => 1, + description => "List of nodes allowed for migration.", + }, + 'not-allowed-nodes' => { + type => 'object', + optional => 1, + properties => { + 'blocking-ha-resources' => { + description => "HA resources, which are blocking the" + . " container from being migrated to the node.", + type => 'array', + optional => 1, + items => { + description => "A blocking HA resource", + type => 'object', + properties => { + sid => { + type => 'string', + description => "The blocking HA resource id", + }, + cause => { + type => 'string', + description => "The reason why the HA" + . " resource is blocking the migration.", + enum => ['resource-affinity'], + }, + }, + }, + }, + }, + description => "List of not allowed nodes with additional information.", + }, + 'comigrated-ha-resources' => { + description => "HA resources, which will be migrated to the" + . " same target node as the container, because these are in" + . " positive affinity with the container.", + type => 'array', + optional => 1, + items => { + type => 'string', + description => "A comigrated HA resource", + }, + }, + }, + }, + code => sub { + my ($param) = @_; + + my $rpcenv = PVE::RPCEnvironment::get(); + + my $authuser = $rpcenv->get_user(); + + PVE::Cluster::check_cfs_quorum(); + + my $res = {}; + + my $vmid = extract_param($param, 'vmid'); + my $target = extract_param($param, 'target'); + my $localnode = PVE::INotify::nodename(); + + # test if VM exists + my $vmconf = PVE::LXC::Config->load_config($vmid); + my $storecfg = PVE::Storage::config(); + + # try to detect errors early + PVE::LXC::Config->check_lock($vmconf); + + $res->{running} = PVE::LXC::check_running($vmid) ? 1 : 0; + + $res->{'allowed-nodes'} = []; + $res->{'not-allowed-nodes'} = {}; + + my $comigrated_ha_resources = {}; + my $blocking_ha_resources_by_node = {}; + + if (PVE::HA::Config::vm_is_ha_managed($vmid)) { + ($comigrated_ha_resources, $blocking_ha_resources_by_node) = + PVE::HA::Config::get_resource_motion_info("ct:$vmid"); + } + + my $nodelist = PVE::Cluster::get_nodelist(); + for my $node ($nodelist->@*) { + next if $node eq $localnode; + + # extracting blocking resources for current node + if (my $blocking_ha_resources = $blocking_ha_resources_by_node->{$node}) { + $res->{'not-allowed-nodes'}->{$node}->{'blocking-ha-resources'} = + $blocking_ha_resources; + } + + # if nothing came up, add it to the allowed nodes + if (!defined($res->{'not-allowed-nodes'}->{$node})) { + push $res->{'allowed-nodes'}->@*, $node; + } + } + + $res->{'comigrated-ha-resources'} = $comigrated_ha_resources; + + return $res; + }, +}); + __PACKAGE__->register_method({ name => 'migrate_vm', path => '{vmid}/migrate', -- 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel