This is an automated email from the ASF dual-hosted git repository.

Pearl1594 pushed a commit to branch support-multi-vlan-guestnet
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/support-multi-vlan-guestnet by 
this push:
     new a44771c6acc Clear nic-vlan-mapping metadata file instead of skipping 
it when exposure condition is false
a44771c6acc is described below

commit a44771c6acca5b642eb045ae5fc003d722508243
Author: Pearl1594 <[email protected]>
AuthorDate: Wed Oct 21 15:13:45 2026 -0400

    Clear nic-vlan-mapping metadata file instead of skipping it when exposure 
condition is false
---
 .../cloud/network/router/CommandSetupHelper.java   | 22 +++++++++++++++-------
 .../network/router/CommandSetupHelperTest.java     | 14 ++++++++++----
 2 files changed, 25 insertions(+), 11 deletions(-)

diff --git 
a/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java 
b/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java
index 9875e33be36..c1397c08d93 100644
--- a/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java
+++ b/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java
@@ -25,6 +25,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.function.Supplier;
 
 import javax.inject.Inject;
 
@@ -1415,9 +1416,11 @@ public class CommandSetupHelper {
     }
 
     protected void addNicVlanMappingToVmData(VmDataCommand cmd, UserVm vm, 
NicVO nic) {
-        if (!nic.getMultiNetwork() || 
!VirtualMachineManager.AllowExposeNicVlanMapping.valueIn(vm.getAccountId())) {
-            return;
-        }
+        boolean exposeMapping = nic.getMultiNetwork() && 
VirtualMachineManager.AllowExposeNicVlanMapping.valueIn(vm.getAccountId());
+        setOrClearVmData(cmd, NetworkModel.METATDATA_DIR, 
NetworkModel.NIC_VLAN_MAPPING_FILE, exposeMapping, () -> 
buildNicVlanMappingJson(nic));
+    }
+
+    private String buildNicVlanMappingJson(NicVO nic) {
         List<NicNetworkMapVO> associations = 
_nicNetworkMapDao.listByNicId(nic.getId());
         List<NicVlanMappingEntry> mappings = new ArrayList<>();
         for (NicNetworkMapVO association : associations) {
@@ -1428,10 +1431,15 @@ public class CommandSetupHelper {
             String vlanTag = 
BroadcastDomainType.Vlan.getValueFrom(associatedNetwork.getBroadcastUri());
             mappings.add(new NicVlanMappingEntry(associatedNetwork.getUuid(), 
associatedNetwork.getName(), vlanTag));
         }
-        // empty-string data is vmdata.py's signal to delete a 
previously-written file: once a nic has been
-        // trunked, its last association being removed must actively clear any 
stale file left from before,
-        // not just skip writing - the guest must never see associations that 
no longer exist
-        cmd.addVmData(NetworkModel.METATDATA_DIR, 
NetworkModel.NIC_VLAN_MAPPING_FILE, mappings.isEmpty() ? "" : new 
Gson().toJson(mappings));
+        return mappings.isEmpty() ? "" : new Gson().toJson(mappings);
+    }
+
+    /**
+     * Sends the current value when {@code shouldExist}, otherwise sends "" - 
vmdata.py's signal to delete a
+     * previously-written file - so a guest never keeps seeing stale metadata 
once the condition no longer holds.
+     */
+    private void setOrClearVmData(VmDataCommand cmd, String folder, String 
file, boolean shouldExist, Supplier<String> valueSupplier) {
+        cmd.addVmData(folder, file, shouldExist ? valueSupplier.get() : "");
     }
 
     private static final class NicVlanMappingEntry {
diff --git 
a/server/src/test/java/com/cloud/network/router/CommandSetupHelperTest.java 
b/server/src/test/java/com/cloud/network/router/CommandSetupHelperTest.java
index 2e7b1e33df8..5163b13995f 100644
--- a/server/src/test/java/com/cloud/network/router/CommandSetupHelperTest.java
+++ b/server/src/test/java/com/cloud/network/router/CommandSetupHelperTest.java
@@ -151,7 +151,7 @@ public class CommandSetupHelperTest {
     }
 
     @Test
-    public void testAddNicVlanMappingToVmDataSkipsWhenNicNotTrunked() {
+    public void testAddNicVlanMappingToVmDataClearsFileWhenNicNotTrunked() {
         VmDataCommand vmDataCommand = new VmDataCommand("testVMname");
         NicVO nic = Mockito.mock(NicVO.class);
         when(nic.getMultiNetwork()).thenReturn(false);
@@ -159,12 +159,15 @@ public class CommandSetupHelperTest {
 
         commandSetupHelper.addNicVlanMappingToVmData(vmDataCommand, vm, nic);
 
-        Assert.assertTrue(vmDataCommand.getVmData().isEmpty());
+        List<String[]> metadata = vmDataCommand.getVmData();
+        Assert.assertEquals(1, metadata.size());
+        Assert.assertEquals(NetworkModel.NIC_VLAN_MAPPING_FILE, 
metadata.get(0)[1]);
+        Assert.assertEquals("", metadata.get(0)[2]);
         Mockito.verifyNoInteractions(nicNetworkMapDao);
     }
 
     @Test
-    public void testAddNicVlanMappingToVmDataSkipsWhenConfigDisabled() {
+    public void testAddNicVlanMappingToVmDataClearsFileWhenConfigDisabled() {
         VmDataCommand vmDataCommand = new VmDataCommand("testVMname");
         NicVO nic = Mockito.mock(NicVO.class);
         when(nic.getMultiNetwork()).thenReturn(true);
@@ -173,7 +176,10 @@ public class CommandSetupHelperTest {
 
         commandSetupHelper.addNicVlanMappingToVmData(vmDataCommand, vm, nic);
 
-        Assert.assertTrue(vmDataCommand.getVmData().isEmpty());
+        List<String[]> metadata = vmDataCommand.getVmData();
+        Assert.assertEquals(1, metadata.size());
+        Assert.assertEquals(NetworkModel.NIC_VLAN_MAPPING_FILE, 
metadata.get(0)[1]);
+        Assert.assertEquals("", metadata.get(0)[2]);
         Mockito.verifyNoInteractions(nicNetworkMapDao);
     }
 

Reply via email to