fix(xo-server): keep VIF trunks when vif.set recreates the VIF

vif.set deletes and recreates the VIF on a MAC change, or when VIF.move fails, and the new VIF
only gets the fields the recreation copies: the VLANs the VIF was restricted to were lost.

Copy them. And refuse to move a restricted VIF to a network with a VLAN, as XAPI does
(NETWORK_INCOMPATIBLE_WITH_TRUNKS): VIF.move fails there, and the recreation would drop the
VLANs without a word, so a VIF moved back later to a network without VLAN would see every VLAN.
This commit is contained in:
KAN-vates
2026-11-04 10:44:44 +01:00
parent 2ff2ef1fa1
commit 85c15572b4
2 changed files with 12 additions and 0 deletions

View File

@@ -18,6 +18,7 @@
- [Pool/Traffic rules] Display traffic rules by priority within their network (PR [#10688](https://github.com/vatesfr/xen-orchestra/pull/10688))
- [VMs/Hosts] Show a loader in VM and host icons while their power state is changing, with the operation in progress in the tooltip, and move the header loader next to the name (PR [#10720](https://github.com/vatesfr/xen-orchestra/pull/10720))
- [REST API/VIFs] VIFs can be restricted to a list of VLANs (VLAN filtering, XCP-ng 8.3) (PR [#10742](https://github.com/vatesfr/xen-orchestra/pull/10742))
- [VM/Network] Changing the MAC address of a VIF keeps the VLANs it is restricted to, and moving it to a network with a VLAN is refused until they are removed (PR [#10742](https://github.com/vatesfr/xen-orchestra/pull/10742))
### Bug fixes

View File

@@ -1,5 +1,6 @@
import { createLogger } from '@xen-orchestra/log'
import { ignoreErrors } from 'promise-toolbox'
import { invalidParameters } from 'xo-common/api-errors.js'
import { diffItems } from '../utils.mjs'
@@ -108,6 +109,15 @@ export async function set({
const xapi = this.getXapi(vif)
// XAPI refuses trunks on a network with a VLAN (NETWORK_INCOMPATIBLE_WITH_TRUNKS), and the delete+create
// fallback below would recreate the VIF without them: moved back later to a network without VLAN, it would
// see every VLAN. Refuse, as XAPI does
if (isNetworkChanged && vif.trunks?.length > 0 && xapi.getObject(network.id).$PIFs.some(pif => pif.VLAN !== -1)) {
throw invalidParameters(
`remove the VLANs VIF ${vif.id} is restricted to before moving it to a network with a VLAN`
)
}
// If only the network is changing (not MAC), try to use VIF.move which is non-destructive
// VIF.move was introduced in XenServer 7.1 and keeps the VIF UUID, avoiding network downtime
if (isNetworkChanged && mac === undefined) {
@@ -184,6 +194,7 @@ export async function set({
qos_algorithm_params: newRateLimit != null ? { kbps: String(newRateLimit) } : undefined,
network: network.$ref,
other_config: otherConfig,
trunks: vif.trunks,
VM: vm.$ref,
MTU: vif.MTU,
device: vif.device,