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