Moti Asayag has uploaded a new change for review.

Change subject: engine: Support attaching two labeled networks to a cluster
......................................................................

engine: Support attaching two labeled networks to a cluster

Instead of sending a sequential setup networks command when
multiple networks are being attached to a cluster to the same
host, a single setup networks request should be sent from the
engine to the host to avoid the failure of the latter.

Change-Id: I87194f5c6a382ec49c86cbd26a24ce2aaccb08c9
Bug-Url: https://bugzilla.redhat.com/1054195
Signed-off-by: Moti Asayag <masa...@redhat.com>
---
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MultipleActionsRunner.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MultipleActionsRunnersFactory.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/NetworkClusterAttachmentActionRunner.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/AddNetworksByLabelParametersBuilder.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/cluster/AttachNetworkToVdsGroupCommand.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/cluster/AttachNetworksToClusterCommand.java
A 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/ClusterNetworksParameters.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java
M 
backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/NetworkUtils.java
9 files changed, 263 insertions(+), 33 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/99/23499/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MultipleActionsRunner.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MultipleActionsRunner.java
index 8ef942a..730839f 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MultipleActionsRunner.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MultipleActionsRunner.java
@@ -186,5 +186,4 @@
     public void setIsRunOnlyIfAllCanDoPass(boolean isRunOnlyIfAllCanDoPass) {
         this.isRunOnlyIfAllCanDoPass = isRunOnlyIfAllCanDoPass;
     }
-
 }
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MultipleActionsRunnersFactory.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MultipleActionsRunnersFactory.java
index c73e46e..8ff70c8 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MultipleActionsRunnersFactory.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MultipleActionsRunnersFactory.java
@@ -70,6 +70,11 @@
             break;
         }
 
+        case AttachNetworkToVdsGroup: {
+            runner = new NetworkClusterAttachmentActionRunner(actionType, 
parameters, isInternal);
+            break;
+        }
+
         default: {
             runner = new MultipleActionsRunner(actionType, parameters, 
isInternal);
             break;
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/NetworkClusterAttachmentActionRunner.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/NetworkClusterAttachmentActionRunner.java
new file mode 100644
index 0000000..9585a52
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/NetworkClusterAttachmentActionRunner.java
@@ -0,0 +1,56 @@
+package org.ovirt.engine.core.bll;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.ovirt.engine.core.common.action.AttachNetworkToVdsGroupParameter;
+import org.ovirt.engine.core.common.action.ClusterNetworksParameters;
+import org.ovirt.engine.core.common.action.VdcActionParametersBase;
+import org.ovirt.engine.core.common.action.VdcActionType;
+import org.ovirt.engine.core.common.businessentities.network.Network;
+import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.dal.dbbroker.DbFacade;
+import org.ovirt.engine.core.utils.NetworkUtils;
+
+/**
+ * A multiple action runner designed to attach/detach networks to/from cluster
+ */
+public class NetworkClusterAttachmentActionRunner extends 
MultipleActionsRunner {
+
+    public NetworkClusterAttachmentActionRunner(VdcActionType actionType,
+            List<VdcActionParametersBase> parameters,
+            boolean isInternal) {
+        super(actionType, parameters, isInternal);
+    }
+
+    protected void runCommands() {
+        List<AttachNetworkToVdsGroupParameter> params = new ArrayList<>();
+        Set<Guid> networkIds = new HashSet<>();
+        for (CommandBase<?> command : getCommands()) {
+            if (command.getReturnValue().getCanDoAction()) {
+                AttachNetworkToVdsGroupParameter parameters =
+                        (AttachNetworkToVdsGroupParameter) 
command.getParameters();
+                params.add(parameters);
+                Network network =
+                        
DbFacade.getInstance().getNetworkDao().get(parameters.getNetworkCluster().getNetworkId());
+                if (NetworkUtils.isConfiguredByLabel(network)) {
+                    networkIds.add(network.getId());
+                }
+            }
+        }
+
+        // managing a single network on multiple clusters can be executed 
using the regular runner
+        if (networkIds.size() <= 1) {
+            super.runCommands();
+            return;
+        }
+
+        // multiple networks can be either attached or detached from a single 
cluster
+        if (!params.isEmpty()) {
+            
Backend.getInstance().runInternalAction(VdcActionType.AttachNetworksToCluster,
+                    new 
ClusterNetworksParameters(params.get(0).getVdsGroupId(), params));
+        }
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/AddNetworksByLabelParametersBuilder.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/AddNetworksByLabelParametersBuilder.java
index e672c5b..a939e2c 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/AddNetworksByLabelParametersBuilder.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/AddNetworksByLabelParametersBuilder.java
@@ -1,6 +1,7 @@
 package org.ovirt.engine.core.bll.network;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -12,6 +13,7 @@
 import 
org.ovirt.engine.core.common.businessentities.network.VdsNetworkInterface;
 import org.ovirt.engine.core.common.errors.VdcBLLException;
 import org.ovirt.engine.core.common.errors.VdcBllErrors;
+import org.ovirt.engine.core.compat.Guid;
 
 public class AddNetworksByLabelParametersBuilder extends 
NetworkParametersBuilder {
 
@@ -36,6 +38,29 @@
         return parameters;
     }
 
+    /**
+     * Adds a list of labeled networks to a host
+     */
+    public SetupNetworksParameters buildParameters(Guid vdsId,
+            List<Network> labeledNetworks,
+            Map<String, VdsNetworkInterface> nicsByLabel) {
+        SetupNetworksParameters parameters = 
createSetupNetworksParameters(vdsId);
+        Set<Network> networkToAdd = 
getNetworksToConfigure(parameters.getInterfaces(), labeledNetworks);
+
+        for (Network network : networkToAdd) {
+            VdsNetworkInterface labeledNic = 
nicsByLabel.get(network.getLabel());
+            VdsNetworkInterface nicToConfigure = 
getNicToConfigure(parameters.getInterfaces(), labeledNic.getId());
+            if (nicToConfigure == null) {
+                throw new 
VdcBLLException(VdcBllErrors.LABELED_NETWORK_INTERFACE_NOT_FOUND);
+            }
+
+            // configure the network on the nic
+            
parameters.getInterfaces().addAll(configureNetworks(nicToConfigure, 
Collections.singleton(network)));
+        }
+
+        return parameters;
+    }
+
     public void labelConfiguredNic(String label, VdsNetworkInterface 
nicToConfigure) {
         if (nicToConfigure.getLabels() == null) {
             nicToConfigure.setLabels(new HashSet<String>());
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/cluster/AttachNetworkToVdsGroupCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/cluster/AttachNetworkToVdsGroupCommand.java
index eaee236..3ed1a4e 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/cluster/AttachNetworkToVdsGroupCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/cluster/AttachNetworkToVdsGroupCommand.java
@@ -20,6 +20,8 @@
 import 
org.ovirt.engine.core.common.businessentities.network.VdsNetworkInterface;
 import org.ovirt.engine.core.common.errors.VdcBllMessages;
 import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.dal.dbbroker.DbFacade;
+import org.ovirt.engine.core.dao.network.NetworkClusterDao;
 import org.ovirt.engine.core.utils.NetworkUtils;
 import org.ovirt.engine.core.utils.transaction.TransactionMethod;
 import org.ovirt.engine.core.utils.transaction.TransactionSupport;
@@ -62,25 +64,7 @@
 
             @Override
             public Void runInTransaction() {
-                if (networkExists()) {
-                    getNetworkClusterDAO().update(getNetworkCluster());
-                } else {
-                    getNetworkClusterDAO().save(new 
NetworkCluster(getVdsGroupId(), getNetwork().getId(),
-                            NetworkStatus.OPERATIONAL,
-                            false,
-                            getNetworkCluster().isRequired(),
-                            getNetworkCluster().isMigration()));
-                }
-
-                if (getNetwork().getCluster().isDisplay()) {
-                    
getNetworkClusterDAO().setNetworkExclusivelyAsDisplay(getVdsGroupId(), 
getNetwork().getId());
-                }
-
-                if (getNetwork().getCluster().isMigration()) {
-                    
getNetworkClusterDAO().setNetworkExclusivelyAsMigration(getVdsGroupId(), 
getNetwork().getId());
-                }
-
-                NetworkClusterHelper.setStatus(getVdsGroupId(), getNetwork());
+                updateNetworkAttachment(getVdsGroupId(), getNetworkCluster(), 
getNetwork());
                 return null;
             }
         });
@@ -156,18 +140,6 @@
         return true;
     }
 
-    private boolean networkExists() {
-        List<NetworkCluster> networks = 
getNetworkClusterDAO().getAllForCluster(getVdsGroupId());
-        for (NetworkCluster networkCluster : networks) {
-            if (networkCluster.getNetworkId().equals(
-                    getNetworkCluster().getNetworkId())) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
     private boolean vdsGroupExists() {
         if (!vdsGroupInDb()) {
             addCanDoActionMessage(VdcBllMessages.VDS_CLUSTER_IS_NOT_VALID);
@@ -201,7 +173,7 @@
                 getActionType().getActionGroup()));
 
         // require permissions on cluster the network is attached to
-        if (networkExists()) {
+        if (networkExists(getVdsGroupId(), getNetworkCluster())) {
             permissions.add(new 
PermissionSubject(getParameters().getVdsGroupId(),
                     VdcObjectType.VdsGroups,
                     ActionGroup.CONFIGURE_CLUSTER_NETWORK));
@@ -226,4 +198,41 @@
         getReturnValue().getCanDoActionMessages().addAll(messages);
         return false;
     }
+
+    public static void updateNetworkAttachment(Guid clusterId, NetworkCluster 
networkCluster, Network network) {
+        if (networkExists(clusterId, networkCluster)) {
+            getNetworkClusterDao().update(networkCluster);
+        } else {
+            getNetworkClusterDao().save(new NetworkCluster(clusterId, 
network.getId(),
+                    NetworkStatus.OPERATIONAL,
+                    false,
+                    networkCluster.isRequired(),
+                    networkCluster.isMigration()));
+        }
+
+        if (network.getCluster().isDisplay()) {
+            getNetworkClusterDao().setNetworkExclusivelyAsDisplay(clusterId, 
network.getId());
+        }
+
+        if (network.getCluster().isMigration()) {
+            getNetworkClusterDao().setNetworkExclusivelyAsMigration(clusterId, 
network.getId());
+        }
+
+        NetworkClusterHelper.setStatus(clusterId, network);
+    }
+
+    private static boolean networkExists(Guid clusterId, NetworkCluster 
networkCluster) {
+        List<NetworkCluster> networks = 
getNetworkClusterDao().getAllForCluster(clusterId);
+        for (NetworkCluster nc : networks) {
+            if (nc.getNetworkId().equals(networkCluster.getNetworkId())) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    private static NetworkClusterDao getNetworkClusterDao() {
+        return DbFacade.getInstance().getNetworkClusterDao();
+    }
 }
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/cluster/AttachNetworksToClusterCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/cluster/AttachNetworksToClusterCommand.java
new file mode 100644
index 0000000..0e91ef9
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/cluster/AttachNetworksToClusterCommand.java
@@ -0,0 +1,101 @@
+package org.ovirt.engine.core.bll.network.cluster;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.ovirt.engine.core.bll.InternalCommandAttribute;
+import org.ovirt.engine.core.bll.NonTransactiveCommandAttribute;
+import org.ovirt.engine.core.bll.VdsGroupCommandBase;
+import org.ovirt.engine.core.bll.network.AddNetworksByLabelParametersBuilder;
+import org.ovirt.engine.core.bll.utils.PermissionSubject;
+import org.ovirt.engine.core.common.action.AttachNetworkToVdsGroupParameter;
+import org.ovirt.engine.core.common.action.ClusterNetworksParameters;
+import org.ovirt.engine.core.common.action.VdcActionParametersBase;
+import org.ovirt.engine.core.common.action.VdcActionType;
+import org.ovirt.engine.core.common.businessentities.network.Network;
+import 
org.ovirt.engine.core.common.businessentities.network.VdsNetworkInterface;
+import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.utils.transaction.TransactionMethod;
+import org.ovirt.engine.core.utils.transaction.TransactionSupport;
+
+@InternalCommandAttribute
+@NonTransactiveCommandAttribute
+public class AttachNetworksToClusterCommand<T extends 
ClusterNetworksParameters> extends VdsGroupCommandBase<T> {
+
+    public AttachNetworksToClusterCommand(T parameters) {
+        super(parameters);
+    }
+
+    @Override
+    protected void executeCommand() {
+        TransactionSupport.executeInNewTransaction(new 
TransactionMethod<Void>() {
+
+            @Override
+            public Void runInTransaction() {
+                for (AttachNetworkToVdsGroupParameter param : 
getParameters().getClusterNetworksParameters()) {
+                    
AttachNetworkToVdsGroupCommand.updateNetworkAttachment(param.getVdsGroupId(),
+                            param.getNetworkCluster(),
+                            param.getNetwork());
+                }
+
+                return null;
+            }
+        });
+
+        if 
(NetworkHelper.setupNetworkSupported(getVdsGroup().getcompatibility_version())) 
{
+            Set<Network> networks = new HashSet<>();
+            Map<Guid, List<Network>> networksByHost = new HashMap<>();
+            Map<Guid, Map<String, VdsNetworkInterface>> labelsToNicsByHost = 
new HashMap<>();
+
+            for (AttachNetworkToVdsGroupParameter param : 
getParameters().getClusterNetworksParameters()) {
+                
networks.add(getNetworkDAO().get(param.getNetworkCluster().getNetworkId()));
+            }
+
+            for (Network network : networks) {
+                List<VdsNetworkInterface> nics =
+                        
getDbFacade().getInterfaceDao().getAllInterfacesByLabelForCluster(getVdsGroupId(),
+                                network.getLabel());
+
+                for (VdsNetworkInterface nic : nics) {
+                    if (!networksByHost.containsKey(nic.getVdsId())) {
+                        networksByHost.put(nic.getVdsId(), new 
ArrayList<Network>());
+                        labelsToNicsByHost.put(nic.getVdsId(), new 
HashMap<String, VdsNetworkInterface>());
+                    }
+
+                    
labelsToNicsByHost.get(nic.getVdsId()).put(network.getLabel(), nic);
+                    networksByHost.get(nic.getVdsId()).add(network);
+                }
+            }
+
+            if (!networksByHost.isEmpty()) {
+                configureNetworksOnHosts(networksByHost, labelsToNicsByHost);
+            }
+        }
+
+        setSucceeded(true);
+    }
+
+    private void configureNetworksOnHosts(Map<Guid, List<Network>> 
networksByHost,
+            Map<Guid, Map<String, VdsNetworkInterface>> labelsToNicsByHost) {
+        ArrayList<VdcActionParametersBase> parameters = new ArrayList<>();
+        for (Entry<Guid, List<Network>> entry : networksByHost.entrySet()) {
+            AddNetworksByLabelParametersBuilder builder = new 
AddNetworksByLabelParametersBuilder();
+            parameters.add(builder.buildParameters(entry.getKey(),
+                    entry.getValue(),
+                    labelsToNicsByHost.get(entry.getKey())));
+        }
+
+        
getBackend().runInternalMultipleActions(VdcActionType.PersistentSetupNetworks, 
parameters);
+    }
+
+    @Override
+    public List<PermissionSubject> getPermissionCheckSubjects() {
+        return Collections.emptyList();
+    }
+}
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/ClusterNetworksParameters.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/ClusterNetworksParameters.java
new file mode 100644
index 0000000..7bc8e45
--- /dev/null
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/ClusterNetworksParameters.java
@@ -0,0 +1,23 @@
+package org.ovirt.engine.core.common.action;
+
+import java.util.List;
+
+import org.ovirt.engine.core.compat.Guid;
+
+public class ClusterNetworksParameters extends VdsGroupParametersBase {
+
+    private static final long serialVersionUID = -7719778463146040093L;
+    private List<AttachNetworkToVdsGroupParameter> parameters;
+
+    public ClusterNetworksParameters() {
+    }
+
+    public ClusterNetworksParameters(Guid clusterId, 
List<AttachNetworkToVdsGroupParameter> parameters) {
+        super(clusterId);
+        this.parameters = parameters;
+    }
+
+    public List<AttachNetworkToVdsGroupParameter> 
getClusterNetworksParameters() {
+        return parameters;
+    }
+}
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java
index 22b2421..6d3dff6 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java
@@ -188,6 +188,7 @@
     // AttachNetworkToVdsGroup is taking over this functionality
     UpdateDisplayToVdsGroup(710, ActionGroup.EDIT_CLUSTER_CONFIGURATION, 
false, QuotaDependency.NONE),
     UpdateNetworkOnCluster(711, ActionGroup.CONFIGURE_CLUSTER_NETWORK, false, 
QuotaDependency.NONE),
+    AttachNetworksToCluster(712, false, QuotaDependency.NONE),
 
     /**
      * MultiLevelAdministration
diff --git 
a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/NetworkUtils.java
 
b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/NetworkUtils.java
index f15a6ca..3c44ff2 100644
--- 
a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/NetworkUtils.java
+++ 
b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/NetworkUtils.java
@@ -263,6 +263,17 @@
     }
 
     /**
+     * Determine if a given network interface should be configured on hosts
+     *
+     * @param network
+     *            the network to check.
+     * @return <code>true</code> iff the network is labeled and not an 
external network.
+     */
+    public static boolean isConfiguredByLabel(Network network) {
+        return isLabeled(network) && !network.isExternal();
+    }
+
+    /**
      * Constructs the vlan device name in the format of "{nic name}.{vlan-id}"
      *
      * @param underlyingNic


-- 
To view, visit http://gerrit.ovirt.org/23499
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I87194f5c6a382ec49c86cbd26a24ce2aaccb08c9
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: ovirt-engine-3.4
Gerrit-Owner: Moti Asayag <masa...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to