Mike Kolesnik has uploaded a new change for review. Change subject: engine: Remove vNIC from external network when necessary ......................................................................
engine: Remove vNIC from external network when necessary Removing the vNIC from the external network only when the vNIC is removed or the VM gets somehow removed. This will allow the user of the vNIC to manipulate it on the external network and not lose his changes when the VM stops. Change-Id: I027992f52c35add0afd1ffe207b1adbdb2c5c957 Bug-Url: https://bugzilla.redhat.com/1016457 Signed-off-by: Mike Kolesnik <mkole...@redhat.com> --- M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RemoveVmCommand.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmPoolHandler.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/VmInterfaceManager.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/vm/RemoveVmInterfaceCommand.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/vm/UpdateVmInterfaceCommand.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/provider/network/openstack/OpenstackNetworkProviderProxy.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/RemoveStoragePoolCommand.java M backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/network/VmInterfaceManagerTest.java 8 files changed, 99 insertions(+), 52 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/66/19966/1 diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RemoveVmCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RemoveVmCommand.java index 35ae0d2..50f35ba 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RemoveVmCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RemoveVmCommand.java @@ -11,6 +11,7 @@ import org.ovirt.engine.core.bll.job.ExecutionContext; import org.ovirt.engine.core.bll.job.ExecutionHandler; import org.ovirt.engine.core.bll.memory.MemoryImageRemoverOnDataDomain; +import org.ovirt.engine.core.bll.network.ExternalNetworkManager; import org.ovirt.engine.core.bll.quota.QuotaConsumptionParameter; import org.ovirt.engine.core.bll.quota.QuotaStorageConsumptionParameter; import org.ovirt.engine.core.bll.quota.QuotaStorageDependent; @@ -35,8 +36,9 @@ import org.ovirt.engine.core.common.businessentities.LunDisk; import org.ovirt.engine.core.common.businessentities.VM; import org.ovirt.engine.core.common.businessentities.VMStatus; -import org.ovirt.engine.core.common.locks.LockingGroup; +import org.ovirt.engine.core.common.businessentities.network.VmNic; import org.ovirt.engine.core.common.errors.VdcBllMessages; +import org.ovirt.engine.core.common.locks.LockingGroup; import org.ovirt.engine.core.common.utils.Pair; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.compat.NotImplementedException; @@ -88,6 +90,11 @@ true, false); + for (VmNic nic : getInterfaces()) { + ExternalNetworkManager externalNetworkManager = new ExternalNetworkManager(nic); + externalNetworkManager.deallocateIfExternal(); + } + TransactionSupport.executeInNewTransaction(new TransactionMethod<Void>() { @Override public Void runInTransaction() { diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmPoolHandler.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmPoolHandler.java index 559b463..e5d3543 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmPoolHandler.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmPoolHandler.java @@ -1,25 +1,17 @@ package org.ovirt.engine.core.bll; import java.util.List; -import java.util.Map; import org.ovirt.engine.core.bll.context.CommandContext; -import org.ovirt.engine.core.bll.network.cluster.NetworkHelper; -import org.ovirt.engine.core.bll.provider.ProviderProxyFactory; -import org.ovirt.engine.core.bll.provider.network.NetworkProviderProxy; import org.ovirt.engine.core.bll.quota.QuotaManager; import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.action.VmOperationParameterBase; import org.ovirt.engine.core.common.action.VmPoolSimpleUserParameters; import org.ovirt.engine.core.common.businessentities.DbUser; -import org.ovirt.engine.core.common.businessentities.Entities; import org.ovirt.engine.core.common.businessentities.Snapshot.SnapshotType; import org.ovirt.engine.core.common.businessentities.VmPool; import org.ovirt.engine.core.common.businessentities.VmPoolMap; import org.ovirt.engine.core.common.businessentities.VmPoolType; -import org.ovirt.engine.core.common.businessentities.VmStatic; -import org.ovirt.engine.core.common.businessentities.network.Network; -import org.ovirt.engine.core.common.businessentities.network.VmNic; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.dal.dbbroker.DbFacade; import org.ovirt.engine.core.utils.log.Log; @@ -58,23 +50,6 @@ QuotaManager.getInstance().rollbackQuotaByVmId(vmId); VmHandler.removeStatelessVmUnmanagedDevices(vmId); - handleProviderNetworks(vmId); - } - - private static void handleProviderNetworks(Guid vmId) { - List<VmNic> interfaces = DbFacade.getInstance().getVmNicDao().getAllForVm(vmId); - VmStatic vm = DbFacade.getInstance().getVmStaticDao().get(vmId); - Map<String, Network> clusterNetworks = - Entities.entitiesByName(DbFacade.getInstance().getNetworkDao().getAllForCluster(vm.getVdsGroupId())); - - for (VmNic iface : interfaces) { - Network network = NetworkHelper.getNetworkByVnicProfileId(iface.getVnicProfileId()); - if (network != null && network.isExternal() && clusterNetworks.containsKey(network.getName())) { - NetworkProviderProxy providerProxy = ProviderProxyFactory.getInstance().create( - DbFacade.getInstance().getProviderDao().get(network.getProvidedBy().getProviderId())); - providerProxy.deallocate(iface); - } - } } public static void removeVmStatelessImages(Guid vmId, CommandContext context) { diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/VmInterfaceManager.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/VmInterfaceManager.java index 38783ec..a9acf30 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/VmInterfaceManager.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/VmInterfaceManager.java @@ -3,6 +3,8 @@ import java.util.ArrayList; import java.util.List; +import javax.transaction.Transaction; + import org.ovirt.engine.core.bll.context.CompensationContext; import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.FeatureSupported; @@ -101,6 +103,8 @@ public void removeAll(Guid vmId) { List<VmNic> interfaces = getVmNicDao().getAllForVm(vmId); if (interfaces != null) { + removeFromExternalNetworks(interfaces); + for (VmNic iface : interfaces) { getMacPoolManager().freeMac(iface.getMacAddress()); getVmNicDao().remove(iface.getId()); @@ -109,6 +113,14 @@ } } + protected void removeFromExternalNetworks(List<VmNic> interfaces) { + Transaction transaction = TransactionSupport.suspend(); + for (VmNic iface : interfaces) { + new ExternalNetworkManager(iface).deallocateIfExternal(); + } + TransactionSupport.resume(transaction); + } + /** * Finds active VMs which uses a network from a given networks list * diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/vm/RemoveVmInterfaceCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/vm/RemoveVmInterfaceCommand.java index a4ad472..16c0b77 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/vm/RemoveVmInterfaceCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/vm/RemoveVmInterfaceCommand.java @@ -1,6 +1,8 @@ package org.ovirt.engine.core.bll.network.vm; +import org.ovirt.engine.core.bll.NonTransactiveCommandAttribute; import org.ovirt.engine.core.bll.VmCommand; +import org.ovirt.engine.core.bll.network.ExternalNetworkManager; import org.ovirt.engine.core.bll.network.MacPoolManager; import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.action.RemoveVmInterfaceParameters; @@ -10,7 +12,10 @@ import org.ovirt.engine.core.common.businessentities.network.VmInterfaceType; import org.ovirt.engine.core.common.businessentities.network.VmNic; import org.ovirt.engine.core.common.errors.VdcBllMessages; +import org.ovirt.engine.core.utils.transaction.TransactionMethod; +import org.ovirt.engine.core.utils.transaction.TransactionSupport; +@NonTransactiveCommandAttribute public class RemoveVmInterfaceCommand<T extends RemoveVmInterfaceParameters> extends VmCommand<T> { private String interfaceName = ""; @@ -26,11 +31,13 @@ @Override protected void executeVmCommand() { this.setVmName(getVmStaticDAO().get(getParameters().getVmId()).getName()); - - // return mac to pool VmNic iface = getVmNicDao().get(getParameters().getInterfaceId()); if (iface != null) { + ExternalNetworkManager externalNetworkManager = new ExternalNetworkManager(iface); + externalNetworkManager.deallocateIfExternal(); + + // return mac to pool MacPoolManager.getInstance().freeMac(iface.getMacAddress()); interfaceName = iface.getName(); @@ -42,11 +49,17 @@ } // remove from db - getVmNicDao().remove(getParameters().getInterfaceId()); - getDbFacade().getVmNetworkStatisticsDao().remove(getParameters().getInterfaceId()); - getDbFacade().getVmDeviceDao().remove(new VmDeviceId(getParameters().getInterfaceId(), - getParameters().getVmId())); - setSucceeded(true); + TransactionSupport.executeInNewTransaction(new TransactionMethod<Void>() { + @Override + public Void runInTransaction() { + getVmNicDao().remove(getParameters().getInterfaceId()); + getDbFacade().getVmNetworkStatisticsDao().remove(getParameters().getInterfaceId()); + getDbFacade().getVmDeviceDao().remove(new VmDeviceId(getParameters().getInterfaceId(), + getParameters().getVmId())); + setSucceeded(true); + return null; + } + }); } @Override diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/vm/UpdateVmInterfaceCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/vm/UpdateVmInterfaceCommand.java index b8a54ab..d8a5105 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/vm/UpdateVmInterfaceCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/vm/UpdateVmInterfaceCommand.java @@ -7,6 +7,7 @@ import org.apache.commons.lang.StringUtils; import org.ovirt.engine.core.bll.NonTransactiveCommandAttribute; import org.ovirt.engine.core.bll.ValidationResult; +import org.ovirt.engine.core.bll.network.ExternalNetworkManager; import org.ovirt.engine.core.bll.network.MacPoolManager; import org.ovirt.engine.core.bll.network.cluster.NetworkHelper; import org.ovirt.engine.core.bll.utils.PermissionSubject; @@ -75,6 +76,15 @@ boolean succeeded = false; boolean macAddedToPool = false; try { + if (isVnicProfileChanged(oldIface, getInterface())) { + Network newNetwork = NetworkHelper.getNetworkByVnicProfileId(getInterface().getVnicProfileId()); + Network oldNetwork = NetworkHelper.getNetworkByVnicProfileId(oldIface.getVnicProfileId()); + if (ObjectUtils.notEqual(oldNetwork, newNetwork)) { + ExternalNetworkManager externalNetworkManager = new ExternalNetworkManager(oldIface); + externalNetworkManager.deallocateIfExternal(); + } + } + if (macShouldBeChanged) { macAddedToPool = addMacToPool(getMacAddress()); } diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/provider/network/openstack/OpenstackNetworkProviderProxy.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/provider/network/openstack/OpenstackNetworkProviderProxy.java index 0a5feab..8926363 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/provider/network/openstack/OpenstackNetworkProviderProxy.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/provider/network/openstack/OpenstackNetworkProviderProxy.java @@ -150,23 +150,26 @@ @Override public Map<String, String> allocate(Network network, VmNic nic) { - deallocate(nic); try { - com.woorea.openstack.quantum.model.Network externalNetwork = - getClient().networks().show(network.getProvidedBy().getExternalId()).execute(); - PortForCreate port = new PortForCreate(); - port.setAdminStateUp(true); - port.setName(nic.getName()); - port.setTenantId(externalNetwork.getTenantId()); - port.setMacAddress(nic.getMacAddress()); - port.setNetworkId(externalNetwork.getId()); - port.setDeviceOwner(DEVICE_OWNER); - port.setDeviceId(nic.getId().toString()); + Port port = locatePort(nic); - Port createdPort = getClient().ports().create(port).execute(); + if (port == null) { + com.woorea.openstack.quantum.model.Network externalNetwork = + getClient().networks().show(network.getProvidedBy().getExternalId()).execute(); + PortForCreate portForCreate = new PortForCreate(); + portForCreate.setAdminStateUp(true); + portForCreate.setName(nic.getName()); + portForCreate.setTenantId(externalNetwork.getTenantId()); + portForCreate.setMacAddress(nic.getMacAddress()); + portForCreate.setNetworkId(externalNetwork.getId()); + portForCreate.setDeviceOwner(DEVICE_OWNER); + portForCreate.setDeviceId(nic.getId().toString()); + port = getClient().ports().create(portForCreate).execute(); + } + Map<String, String> runtimeProperties = new HashMap<>(); - runtimeProperties.put("vnic_id", createdPort.getId()); + runtimeProperties.put("vnic_id", port.getId()); runtimeProperties.put("provider_type", provider.getType().name()); runtimeProperties.put("plugin_type", provider.getAdditionalProperties().getPluginType()); @@ -179,17 +182,26 @@ @Override public void deallocate(VmNic nic) { try { - List<Port> ports = getClient().ports().list().execute().getList(); - for (Port port : ports) { - if (DEVICE_OWNER.equals(port.getDeviceOwner()) && nic.getId().toString().equals(port.getDeviceId())) { - getClient().ports().delete(port.getId()).execute(); - } + Port port = locatePort(nic); + + if (port != null) { + getClient().ports().delete(port.getId()).execute(); } } catch (RuntimeException e) { throw new VdcBLLException(VdcBllErrors.PROVIDER_FAILURE, e); } } + private Port locatePort(VmNic nic) { + List<Port> ports = getClient().ports().list().execute().getList(); + for (Port port : ports) { + if (DEVICE_OWNER.equals(port.getDeviceOwner()) && nic.getId().toString().equals(port.getDeviceId())) { + return port; + } + } + return null; + } + @JsonIgnoreProperties(ignoreUnknown = true) private static class ApiRootResponse { // No implementation since we don't care what's inside the response, just that it succeeded. diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/RemoveStoragePoolCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/RemoveStoragePoolCommand.java index 1eea76c..7651667 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/RemoveStoragePoolCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/RemoveStoragePoolCommand.java @@ -11,6 +11,7 @@ import org.ovirt.engine.core.bll.LockMessagesMatchUtil; import org.ovirt.engine.core.bll.NonTransactiveCommandAttribute; import org.ovirt.engine.core.bll.context.CommandContext; +import org.ovirt.engine.core.bll.network.ExternalNetworkManager; import org.ovirt.engine.core.bll.network.MacPoolManager; import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.action.DetachStorageDomainFromPoolParameters; @@ -27,6 +28,7 @@ import org.ovirt.engine.core.common.businessentities.VDSStatus; import org.ovirt.engine.core.common.businessentities.VmStatic; import org.ovirt.engine.core.common.businessentities.network.Network; +import org.ovirt.engine.core.common.businessentities.network.VmNic; import org.ovirt.engine.core.common.businessentities.network.VnicProfile; import org.ovirt.engine.core.common.errors.VdcBLLException; import org.ovirt.engine.core.common.errors.VdcBllMessages; @@ -90,11 +92,21 @@ } private void removeNetworks() { + final List<Network> networks = getNetworkDAO().getAllForDataCenter(getStoragePoolId()); + for (Network network : networks) { + if (network.isExternal()) { + ExternalNetworkManager externalNetworkManager = new ExternalNetworkManager(network); + for (VmNic nic : getVmNicDao().getAllForNetwork(network.getId())) { + externalNetworkManager.setNic(nic); + externalNetworkManager.deallocateIfExternal(); + } + } + } + TransactionSupport.executeInNewTransaction(new TransactionMethod<Void>() { @Override public Void runInTransaction() { - final List<Network> networks = getNetworkDAO().getAllForDataCenter(getStoragePoolId()); for (final Network net : networks) { List<VnicProfile> profiles = getDbFacade().getVnicProfileDao().getAllForNetwork(net.getId()); for (VnicProfile vnicProfile : profiles) { diff --git a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/network/VmInterfaceManagerTest.java b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/network/VmInterfaceManagerTest.java index 3c56024..8e6ba30 100644 --- a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/network/VmInterfaceManagerTest.java +++ b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/network/VmInterfaceManagerTest.java @@ -3,6 +3,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyList; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.times; @@ -63,6 +64,9 @@ @Mock private VmDAO vmDAO; + @Mock + private ExternalNetworkManager externalNetworkManager; + @Spy private VmInterfaceManager vmInterfaceManager = new VmInterfaceManager(); @@ -70,6 +74,7 @@ private Version version; @Before + @SuppressWarnings("unchecked") public void setupMocks() { MockitoAnnotations.initMocks(this); @@ -79,6 +84,7 @@ doReturn(vmNicDao).when(vmInterfaceManager).getVmNicDao(); doReturn(vmDAO).when(vmInterfaceManager).getVmDAO(); doNothing().when(vmInterfaceManager).auditLogMacInUseUnplug(any(VmNic.class)); + doNothing().when(vmInterfaceManager).removeFromExternalNetworks(anyList()); doNothing().when(vmInterfaceManager).log(any(AuditLogableBase.class), any(AuditLogType.class)); } -- To view, visit http://gerrit.ovirt.org/19966 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I027992f52c35add0afd1ffe207b1adbdb2c5c957 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Mike Kolesnik <mkole...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches