mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-03 04:12:31 +01:00
Fixing remaining issues with per-VIF flow script and removing version-specific scripts.
Now generating XSnetwork names using gre keys Plus other minor corrections
This commit is contained in:
parent
241ba26a03
commit
e2cc2c1f6e
@ -21,16 +21,22 @@ import com.cloud.agent.api.Command;
|
||||
|
||||
public class OvsDestroyBridgeCommand extends Command {
|
||||
|
||||
long networkId;
|
||||
Long networkId;
|
||||
Integer key;
|
||||
|
||||
public OvsDestroyBridgeCommand(long networkId) {
|
||||
public OvsDestroyBridgeCommand(Long networkId, Integer key) {
|
||||
this.networkId = networkId;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public long getNetworkId() {
|
||||
public Long getNetworkId() {
|
||||
return networkId;
|
||||
}
|
||||
|
||||
public Integer getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return true;
|
||||
|
||||
@ -15,15 +15,18 @@ package com.cloud.network.ovs;
|
||||
import com.cloud.agent.api.Command;
|
||||
|
||||
public class OvsDestroyTunnelCommand extends Command {
|
||||
long networkId;
|
||||
|
||||
Long networkId;
|
||||
Integer key;
|
||||
String inPortName;
|
||||
|
||||
public OvsDestroyTunnelCommand(long networkId, String inPortName) {
|
||||
public OvsDestroyTunnelCommand(Long networkId, Integer key, String inPortName) {
|
||||
this.networkId = networkId;
|
||||
this.inPortName = inPortName;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public long getNetworkId() {
|
||||
public Long getNetworkId() {
|
||||
return networkId;
|
||||
}
|
||||
|
||||
@ -31,6 +34,10 @@ public class OvsDestroyTunnelCommand extends Command {
|
||||
return inPortName;
|
||||
}
|
||||
|
||||
public Integer getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return true;
|
||||
|
||||
@ -620,23 +620,21 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
/**
|
||||
* This method just creates a XenServer network following the tunnel network naming convention
|
||||
*/
|
||||
private synchronized Network findOrCreateTunnelNetwork(Connection conn, long networkId) {
|
||||
private synchronized Network findOrCreateTunnelNetwork(Connection conn, long vnetId) {
|
||||
try {
|
||||
String nwName = "OVSTunnel" + networkId;
|
||||
String nwName = "OVSTunnel" + vnetId;
|
||||
Network nw = null;
|
||||
Network.Record rec = new Network.Record();
|
||||
Set<Network> networks = Network.getByNameLabel(conn, nwName);
|
||||
|
||||
if (networks.size() == 0) {
|
||||
rec.nameDescription = "tunnel network id# " + networkId;
|
||||
rec.nameDescription = "tunnel network id# " + vnetId;
|
||||
rec.nameLabel = nwName;
|
||||
//Initialize the ovs-host-setup to avoid error when doing get-param in plugin
|
||||
Map<String,String> otherConfig = new HashMap<String,String>();
|
||||
otherConfig.put("ovs-host-setup", "");
|
||||
rec.otherConfig = otherConfig;
|
||||
nw = Network.create(conn, rec);
|
||||
// Plug dom0 vif only when creating network
|
||||
enableXenServerNetwork(conn, nw, nwName, "tunnel network for account " + networkId);
|
||||
s_logger.debug("### Xen Server network for tunnels created:" + nwName);
|
||||
} else {
|
||||
nw = networks.iterator().next();
|
||||
@ -654,7 +652,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
*/
|
||||
private synchronized Network configureTunnelNetwork(Connection conn, long networkId, long hostId, int key) {
|
||||
try {
|
||||
Network nw = findOrCreateTunnelNetwork(conn, networkId);
|
||||
// Note: the vnet (or gre key) is used to identify the XS network
|
||||
Network nw = findOrCreateTunnelNetwork(conn, key);
|
||||
String nwName = "OVSTunnel" + key;
|
||||
//Invoke plugin to setup the bridge which will be used by this network
|
||||
String bridge = nw.getBridge(conn);
|
||||
Map<String,String> nwOtherConfig = nw.getOtherConfig(conn);
|
||||
@ -670,6 +670,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
}
|
||||
}
|
||||
if (!configured) {
|
||||
// Plug dom0 vif only if not done before for network and host
|
||||
enableXenServerNetwork(conn, nw, nwName, "tunnel network for account " + key);
|
||||
String result = callHostPlugin(conn, "ovstunnel", "setup_ovs_bridge", "bridge", bridge,
|
||||
"key", String.valueOf(key),
|
||||
"xs_nw_uuid", nw.getUuid(conn),
|
||||
@ -689,9 +691,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void destroyTunnelNetwork(Connection conn, long networkId) {
|
||||
private synchronized void destroyTunnelNetwork(Connection conn, int key) {
|
||||
try {
|
||||
Network nw = findOrCreateTunnelNetwork(conn, networkId);
|
||||
Network nw = findOrCreateTunnelNetwork(conn, key);
|
||||
String bridge = nw.getBridge(conn);
|
||||
String result = callHostPlugin(conn, "ovstunnel", "destroy_ovs_bridge", "bridge", bridge);
|
||||
String[] res = result.split(":");
|
||||
@ -731,8 +733,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
_isOvs = true;
|
||||
return setupvSwitchNetwork(conn);
|
||||
} else {
|
||||
long networkId = Long.parseLong(nic.getBroadcastUri().getHost());
|
||||
return findOrCreateTunnelNetwork(conn, networkId);
|
||||
long vnetId = Long.parseLong(nic.getBroadcastUri().getHost());
|
||||
return findOrCreateTunnelNetwork(conn, vnetId);
|
||||
}
|
||||
} else if (nic.getBroadcastType() == BroadcastDomainType.Storage) {
|
||||
URI broadcastUri = nic.getBroadcastUri();
|
||||
@ -1196,7 +1198,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
startVM(conn, host, vm, vmName);
|
||||
|
||||
if (_isOvs) {
|
||||
// TODO(Salvatore-orlando): First option is to do per-NIC rules here
|
||||
// TODO(Salvatore-orlando): This code should go
|
||||
for (NicTO nic : vmSpec.getNics()) {
|
||||
if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vswitch) {
|
||||
HashMap<String, String> args = parseDefaultOvsRuleComamnd(nic.getBroadcastUri().toString().substring(Networks.BroadcastDomainType.Vswitch.scheme().length() + "://".length()));
|
||||
@ -4791,7 +4793,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
private Answer execute(OvsSetupBridgeCommand cmd) {
|
||||
Connection conn = getConnection();
|
||||
s_logger.debug("### About to configure OVS bridge");
|
||||
Network nw=findOrCreateTunnelNetwork(conn, cmd.getNetworkId());
|
||||
Network nw=findOrCreateTunnelNetwork(conn, cmd.getKey());
|
||||
this.configureTunnelNetwork(conn, cmd.getNetworkId(), cmd.getHostId(), cmd.getKey());
|
||||
s_logger.debug("### Bridge configured");
|
||||
return new Answer(cmd, true, null);
|
||||
@ -4800,7 +4802,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
private Answer execute(OvsDestroyBridgeCommand cmd) {
|
||||
Connection conn = getConnection();
|
||||
s_logger.debug("### About to destroy OVS bridge");
|
||||
destroyTunnelNetwork(conn, cmd.getNetworkId());
|
||||
destroyTunnelNetwork(conn, cmd.getKey());
|
||||
s_logger.debug("### Bridge destroyed");
|
||||
return new Answer(cmd, true, null);
|
||||
}
|
||||
@ -4809,7 +4811,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
Connection conn = getConnection();
|
||||
s_logger.debug("### About to destroy tunnel network");
|
||||
try {
|
||||
Network nw = findOrCreateTunnelNetwork(conn, cmd.getNetworkId());
|
||||
Network nw = findOrCreateTunnelNetwork(conn, cmd.getKey());
|
||||
if (nw == null) {
|
||||
s_logger.warn("### Unable to find tunnel network");
|
||||
return new Answer(cmd, false, "No network found");
|
||||
@ -4841,7 +4843,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
String bridge = "unknown";
|
||||
try {
|
||||
s_logger.debug("### About to create tunnel network");
|
||||
Network nw = findOrCreateTunnelNetwork(conn, cmd.getNetworkId());
|
||||
Network nw = findOrCreateTunnelNetwork(conn, cmd.getKey());
|
||||
if (nw == null) {
|
||||
s_logger.debug("### SOMETHING WENT WRONG DURING NETWORK SETUP");
|
||||
return new OvsCreateTunnelAnswer(cmd, false, "Cannot create network", bridge);
|
||||
|
||||
@ -65,8 +65,7 @@ def main(command, vif_raw):
|
||||
# We need the REAL bridge name
|
||||
bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH,
|
||||
'br-to-parent', bridge])
|
||||
# For the OVS version shipped with XS56FP1 we need to retrieve
|
||||
# the ofport number for all interfaces
|
||||
|
||||
vsctl_output = pluginlib.do_cmd([pluginlib.VSCTL_PATH,
|
||||
'list-ports', bridge])
|
||||
vifs = vsctl_output.split('\n')
|
||||
@ -75,8 +74,9 @@ def main(command, vif_raw):
|
||||
vif_ofport = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'get',
|
||||
'Interface', vif, 'ofport'])
|
||||
if this_vif == vif:
|
||||
this_vif_ofport = vif_ofport
|
||||
vif_ofports.append(vif_ofport)
|
||||
this_vif_ofport = vif_ofport
|
||||
if vif.startswith('vif'):
|
||||
vif_ofports.append(vif_ofport)
|
||||
|
||||
if command == 'offline':
|
||||
clear_flows(bridge, this_vif_ofport, vif_ofports)
|
||||
@ -144,7 +144,7 @@ def setup_ovs_bridge(session, args):
|
||||
"uuid=%s" % xs_nw_uuid,
|
||||
"param-name=other-config",
|
||||
"param-key=ovs-host-setup", "--minimal"])
|
||||
conf_hosts = conf_hosts + ",%s" %cs_host_id
|
||||
conf_hosts = cs_host_id + (conf_hosts and ',%s' % conf_hosts or '')
|
||||
lib.do_cmd([lib.XE_PATH,"network-param-set", "uuid=%s" % xs_nw_uuid,
|
||||
"other-config:ovs-host-setup=%s" %conf_hosts])
|
||||
|
||||
@ -176,8 +176,8 @@ def destroy_ovs_bridge(session, args):
|
||||
# Note that the bridge has been removed on xapi network object
|
||||
xs_nw_uuid = lib.do_cmd([xePath, "network-list",
|
||||
"bridge=%s" % bridge, "--minimal"])
|
||||
lib.do_cmd([xePath,"network-param-set", "uuid=%s" % xs_nw_uuid,
|
||||
"other-config:ovs-setup=False"])
|
||||
#lib.do_cmd([xePath,"network-param-set", "uuid=%s" % xs_nw_uuid,
|
||||
# "other-config:ovs-setup=False"])
|
||||
result = "SUCCESS:%s" %bridge
|
||||
|
||||
logging.debug("Destroy_ovs_bridge completed with result:%s" %result)
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
NFSSR.py=/opt/xensource/sm
|
||||
vmops=..,0755,/etc/xapi.d/plugins
|
||||
xen-ovs-vif-flows.rules=..,0644,/etc/udev/rules.d
|
||||
ovs-vif-flows.py=.,0755,/etc/xapi.d/plugins
|
||||
ovs-vif-flows.py=..,0755,/etc/xapi.d/plugins
|
||||
cloudstack_plugins.conf=..,0644,/etc/xensource
|
||||
cloudstack_pluginlib.py=..,0755,/etc/xapi.d/plugins
|
||||
ovsgre=..,0755,/etc/xapi.d/plugins
|
||||
|
||||
@ -1,79 +0,0 @@
|
||||
# A simple script for enabling and disabling per-vif rules for explicitly
|
||||
# allowing broadcast/multicast traffic on the port where the VIF is attached
|
||||
#
|
||||
# Copyright (C) 2012 Citrix Systems
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import cloudstack_pluginlib as pluginlib
|
||||
|
||||
|
||||
def clear_flows(bridge, vif_ofport):
|
||||
# Remove flow entries originating from given ofport
|
||||
pluginlib.del_flows(bridge, in_port=vif_ofport)
|
||||
# Leverage out_port option for removing flows based on actions
|
||||
pluginlib.del_flows(bridge, out_port=vif_ofport)
|
||||
|
||||
|
||||
def apply_flows(bridge, vif_ofport):
|
||||
action = "output:%s," % vif_ofport
|
||||
# Ensure {b|m}casts sent from VIF ports are always allowed
|
||||
pluginlib.add_flow(bridge, priority=1200,
|
||||
in_port=vif_ofport,
|
||||
dl_dst='ff:ff:ff:ff:ff:ff',
|
||||
actions='NORMAL')
|
||||
pluginlib.add_flow(bridge, priority=1200,
|
||||
in_port=vif_ofport,
|
||||
nw_dst='224.0.0.0/24',
|
||||
actions='NORMAL')
|
||||
# Ensure {b|m}casts are always propagated to VIF ports
|
||||
pluginlib.add_flow(bridge, priority=1100,
|
||||
dl_dst='ff:ff:ff:ff:ff:ff', actions=action)
|
||||
pluginlib.add_flow(bridge, priority=1100,
|
||||
nw_dst='224.0.0.0/24', actions=action)
|
||||
|
||||
|
||||
def main(command, vif_raw):
|
||||
if command not in ('online', 'offline'):
|
||||
return
|
||||
# TODO (very important)
|
||||
# Quit immediately if networking is NOT being managed by the OVS tunnel manager
|
||||
vif_name, dom_id, vif_index = vif_raw.split('-')
|
||||
# validate vif and dom-id
|
||||
vif = "%s%s.%s" % (vif_name, dom_id, vif_index)
|
||||
|
||||
bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'iface-to-br', vif])
|
||||
# find xs network for this bridge, verify is used for ovs tunnel network
|
||||
xs_nw_uuid = pluginlib.do_cmd([pluginlib.XE_PATH, "network-list",
|
||||
"bridge=%s" % bridge, "--minimal"])
|
||||
result = pluginlib.do_cmd([pluginlib.XE_PATH,"network-param-get",
|
||||
"uuid=%s" % xs_nw_uuid,
|
||||
"param-name=other-config",
|
||||
"param-key=is-ovs-tun-network", "--minimal"])
|
||||
|
||||
if result != 'True':
|
||||
return
|
||||
|
||||
vlan = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-vlan', bridge])
|
||||
if vlan != '0':
|
||||
# We need the REAL bridge name
|
||||
bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-parent', bridge])
|
||||
vif_ofport = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'get', 'Interface',
|
||||
vif, 'ofport'])
|
||||
|
||||
if command == 'offline':
|
||||
clear_flows(bridge, vif_ofport)
|
||||
|
||||
if command == 'online':
|
||||
apply_flows(bridge, vif_ofport)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) != 3:
|
||||
print "usage: %s [online|offline] vif-domid-idx" % \
|
||||
os.path.basename(sys.argv[0])
|
||||
sys.exit(1)
|
||||
else:
|
||||
command, vif_raw = sys.argv[1:3]
|
||||
main(command, vif_raw)
|
||||
@ -12,7 +12,7 @@
|
||||
NFSSR.py=/opt/xensource/sm
|
||||
vmops=..,0755,/etc/xapi.d/plugins
|
||||
xen-ovs-vif-flows.rules=..,0644,/etc/udev/rules.d
|
||||
ovs-vif-flows.py=.,0755,/etc/xapi.d/plugins
|
||||
ovs-vif-flows.py=..,0755,/etc/xapi.d/plugins
|
||||
cloudstack_plugins.conf=..,0644,/etc/xensource
|
||||
cloudstack_pluginlib.py=..,0755,/etc/xapi.d/plugins
|
||||
ovsgre=..,0755,/etc/xapi.d/plugins
|
||||
|
||||
@ -129,6 +129,24 @@ public class OvsTunnelManagerImpl implements OvsTunnelManager {
|
||||
_tunnelNetworkDao.update(tunnel.getId(), tunnel);
|
||||
}
|
||||
|
||||
private int getGreKey(Network network) {
|
||||
int key = 0;
|
||||
try {
|
||||
//The GRE key is actually in the host part of the URI
|
||||
String keyStr = network.getBroadcastUri().getHost();
|
||||
// The key is most certainly and int.
|
||||
// So we feel quite safe in converting it into a string
|
||||
key = Integer.valueOf(keyStr);
|
||||
return key;
|
||||
} catch (NumberFormatException e) {
|
||||
s_logger.debug("Well well, how did '" + key +
|
||||
"' end up in the broadcast URI for the network?");
|
||||
throw new CloudRuntimeException(
|
||||
String.format("Invalid GRE key parsed from network broadcast URI (%s)",
|
||||
network.getBroadcastUri().toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@DB
|
||||
protected void CheckAndCreateTunnel(VirtualMachine instance, Network nw, DeployDestination dest) {
|
||||
if (!_isEnabled) {
|
||||
@ -143,18 +161,7 @@ public class OvsTunnelManagerImpl implements OvsTunnelManager {
|
||||
}
|
||||
|
||||
long hostId = dest.getHost().getId();
|
||||
int key = 0;
|
||||
try {
|
||||
//The GRE key is actually in the host part of the URI
|
||||
String keyStr = nw.getBroadcastUri().getHost();
|
||||
// The key is most certainly and int.
|
||||
// So we feel quite safe in converting it into a string
|
||||
key = Integer.valueOf(keyStr);
|
||||
} catch (NumberFormatException e) {
|
||||
s_logger.debug("Well well, how did '" + key +
|
||||
"' end up in the broadcast URI for the network?");
|
||||
s_logger.warn("Unable to create GRE tunnels on host:" + hostId);
|
||||
}
|
||||
int key = getGreKey(nw);
|
||||
// Find active (i.e.: not shut off) VMs with a NIC on the target network
|
||||
List<UserVmVO> vms = _userVmDao.listByNetworkIdAndStates(nw.getId(), State.Running, State.Starting,
|
||||
State.Stopping, State.Unknown, State.Migrating);
|
||||
@ -198,7 +205,7 @@ public class OvsTunnelManagerImpl implements OvsTunnelManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//FIXME: Why are we cancelling the exception here?
|
||||
try {
|
||||
String myIp = dest.getHost().getPrivateIpAddress();
|
||||
boolean noHost = true;
|
||||
@ -337,7 +344,8 @@ public class OvsTunnelManagerImpl implements OvsTunnelManager {
|
||||
try {
|
||||
/* Now we are last one on host, destroy the bridge with all
|
||||
* the tunnels for this network */
|
||||
Command cmd = new OvsDestroyBridgeCommand(nw.getId());
|
||||
int key = getGreKey(nw);
|
||||
Command cmd = new OvsDestroyBridgeCommand(nw.getId(), key);
|
||||
s_logger.debug("### Destroying bridge for network " + nw.getId() + " on host:" + vm.getHostId());
|
||||
Answer ans = _agentMgr.send(vm.getHostId(), cmd);
|
||||
handleDestroyBridgeAnswer(ans, vm.getHostId(), nw.getId());
|
||||
@ -345,11 +353,14 @@ public class OvsTunnelManagerImpl implements OvsTunnelManager {
|
||||
/* Then ask hosts have peer tunnel with me to destroy them */
|
||||
List<OvsTunnelNetworkVO> peers = _tunnelNetworkDao.listByToNetwork(vm.getHostId(), nw.getId());
|
||||
for (OvsTunnelNetworkVO p : peers) {
|
||||
cmd = new OvsDestroyTunnelCommand(p.getNetworkId(), p.getPortName());
|
||||
s_logger.debug("### Destroying tunnel to " + vm.getHostId() +
|
||||
" from " + p.getFrom());
|
||||
ans = _agentMgr.send(p.getFrom(), cmd);
|
||||
handleDestroyTunnelAnswer(ans, p.getFrom(), p.getTo(), p.getNetworkId());
|
||||
// If the tunnel was not successfully created don't bother to remove it
|
||||
if (p.getState().equals("SUCCESS")) {
|
||||
cmd = new OvsDestroyTunnelCommand(p.getNetworkId(), key, p.getPortName());
|
||||
s_logger.debug("### Destroying tunnel to " + vm.getHostId() +
|
||||
" from " + p.getFrom());
|
||||
ans = _agentMgr.send(p.getFrom(), cmd);
|
||||
handleDestroyTunnelAnswer(ans, p.getFrom(), p.getTo(), p.getNetworkId());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
s_logger.warn(String.format("Destroy tunnel(account:%1$s, hostId:%2$s) failed", vm.getAccountId(), vm.getHostId()), e);
|
||||
|
||||
@ -573,6 +573,10 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
|
||||
if (pod == null) {
|
||||
throw new InvalidParameterValueException("Can't find pod by id " + podId);
|
||||
}
|
||||
HostPodVO pod = _podDao.findById(podId);
|
||||
if (pod == null) {
|
||||
throw new InvalidParameterValueException("Can't find pod with specified podId " + podId);
|
||||
}
|
||||
// check if pod belongs to the zone
|
||||
if (!Long.valueOf(pod.getDataCenterId()).equals(dcId)) {
|
||||
InvalidParameterValueException ex = new InvalidParameterValueException("Pod with specified podId" + podId + " doesn't belong to the zone with specified zoneId" + dcId);
|
||||
@ -625,7 +629,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
|
||||
if (pod == null) {
|
||||
throw new InvalidParameterValueException("Can't find pod by id " + podId);
|
||||
}
|
||||
ClusterVO cluster = new ClusterVO(dcId, podId, clusterName);
|
||||
ClusterVO cluster = new ClusterVO(dcId, podId, clusterName);
|
||||
cluster.setHypervisorType(hypervisorType);
|
||||
try {
|
||||
cluster = _clusterDao.persist(cluster);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user