From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [IPv6:2a0f:8001:1:32::40]) by lore.proxmox.com (Postfix) with ESMTPS id 734841FF0E6 for ; Fri, 07 Aug 2026 11:12:44 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 3D7B82154A; Fri, 07 Aug 2026 11:12:41 +0200 (CEST) From: Erik Fastermann To: pve-devel@lists.proxmox.com Subject: [PATCH qemu-server v2 0/5] remote migration: extract preconditions and add check endpoint Date: Fri, 7 Aug 2026 11:12:22 +0200 Message-ID: <20260807091227.73614-1-e.fastermann@proxmox.com> X-Mailer: git-send-email 2.47.3 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 1 AWL -0.711 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) KAM_LAZY_DOMAIN_SECURITY 1 Sending domain does not have any anti-forgery methods POISEN_SPAM_PILL 0.1 Meta: its spam POISEN_SPAM_PILL_1 0.1 random spam to be learned in bayes POISEN_SPAM_PILL_3 0.1 random spam to be learned in bayes RDNS_NONE 1.274 Delivered to internal network by a host with no rDNS SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_NONE 0.001 SPF: sender does not publish an SPF Record Message-ID-Hash: 7AAOEKJQDUAWJBFZTD2445UF27QEBIO2 X-Message-ID-Hash: 7AAOEKJQDUAWJBFZTD2445UF27QEBIO2 X-MailFrom: efastermann@ruth.proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Erik Fastermann X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: This series reworks how the QEMU remote-migration precondition checks are structured and exposes them through a new endpoint, so blockers and warnings can be surfaced before a migration is started rather than mid-flight. Thanks to Fiona, Fabian and Daniel for the review and the discussion on the RFC [0]. Motivation ========== Today the checks run at the very start of a remote migration and abort on the first error via die. Two problems follow: - Many prerequisites are not checked up front at all; they only surface once the migration is already running, e.g. local/mapped devices or a VNC clipboard that is not live-migratable. A user fixes one blocker, retries, and hits the next. A forum user collected a checklist of such prerequisites [1] (thanks Arthur Bied-Charreton for pointing this out). - The qm CLI wrapper only ran a subset of the checks the API path ran, so direct API callers (e.g. the web UI) and the CLI disagreed on what was validated. What the series does ==================== 1. Drop the ineffective fingerprint auto-detection. 2. Extract the checks into a validate_remote_migrate_preconditions helper that records findings instead of dying on the first error. 3. Pull the checks that previously lived only in the qm CLI into the endpoint. 4. Register the remote-migrate command against PVE::API2::Qemu directly and drop the CLI wrapper, so CLI and API run the exact same checks. 5. Add a remote_migrate_vm_precondition endpoint that runs the checks without starting a migration and returns the full findings list. It reuses the same helper as the migrate endpoint, so the precheck cannot drift from what is actually enforced. Changes since the RFC ===================== - Pulling the qm-only checks into the endpoint is now its own patch (3/5) instead of being folded into the extraction patch. - The finding field naming the check is now 'type' instead of 'code', matching the {storage}/import-metadata endpoint. - $add_error and $add_warning are now thin wrappers around a shared $add_finding, all taking proper named arguments with a %extra_info hash as the last one, rather than indexing into @_. - $plan is renamed to $migration_info. The findings array is still passed in, as agreed on the RFC. - $remote_migrate_vm_properties is renamed to $remote_migrate_vm_parameters and passed to both endpoints directly instead of being shallow-copied per endpoint. - The new endpoint is registered in the vmdiridx listing, so it shows up in the API directory index next to remote_migrate. - The migrate endpoint no longer aborts on the first finding. All warnings are emitted via log_warn, all errors are collected, and the die message reports how many errors were found followed by the full list, which matches other instances in the codebase. - Failures of the remote /cluster/resources and /nodes/localhost/storage queries are now recorded as 'remote-query' findings instead of dying, so a partially reachable remote still yields the checks that did run. The initial connectivity probe uses the same type, which is why it was renamed from 'remote-conn'. - Document in the commit message that the HA check no longer uses raise_param_exc. This could be discussed more, as this changes the error code from 400 to 500, but unifies the interface for all errors. - chomp() instead of the s/\s+$//r regex, if (my $err = $@) instead of bare $@ checks, for instead of foreach, and postfix dereference. - Further rewording of user-facing messages. - The commit message prefix is now "remote migration:", matching the existing history in this repo. Future work =========== Nothing below is directly part of this series, but is the direction agreed on in the RFC thread. - Capability negotiation over the tunnel. A capabilities command lets the source detect whether the target understands the newer commands, falling back to the current source-side checks when it does not. - A precondition tunnel command on top of that, where the source sends the relevant config and the target runs the checks it can answer better than the source can. Issued both by the precondition endpoint and by the migration itself. - The existing source-side checks stay regardless. They remain the only thing that runs against a target without the capability, so removing them would mean no checks at all for new to old migrations. - More checks moved up front, e.g. local/mapped devices and other things that currently only surface mid-migration. New checks that need target-side knowledge go through the tunnel command, purely source-config-derived ones into the shared helper this series adds. - A similar series for remote container migration. Containers don't support live migration, so it should be simpler. - The findings shape is meant to be reusable for the intra-cluster migration precondition endpoint later, as a map from node to findings list. References ========== [0] https://lore.proxmox.com/pve-devel/20260721115827.163442-1-e.fastermann@proxmox.com/ [1] https://forum.proxmox.com/threads/pdm-cross-cluster-migration-prerequisites-checklist-i-wish-i-had-before-my-first-attempt.184485 Erik Fastermann (5): remote migration: drop ineffective fingerprint auto-detection remote migration: collect preconditions as structured findings remote migration: pull in checks from qm qm: remote-migrate: call API endpoint directly remote migration: add precondition check endpoint src/PVE/API2/Qemu.pm | 490 ++++++++++++++++++++++++++++++------------- src/PVE/CLI/qm.pm | 128 +---------- 2 files changed, 343 insertions(+), 275 deletions(-) -- 2.47.3